• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Binding Directory Entries

    June 5, 2023 Bob Cozzi

    I assume you’ve heard about *BNDDIR (Binding Directory) objects introduced circa 1994 with OS/400 V3R2. The infamous QC2LE binding directory is used by a huge number of RPG applications to access C runtime and unblocked MI functions such as system cvthc, cpybytes, and matmatr. You have probably seen RPG IV source code with the BNDDIR(‘QC2LE’) keyword on the header specification.

    I was one of the first developers outside of IBM to use Binding Directories for my own code. When I go back and look at my own RPG IV code created prior to mid-2007, well over 90 percent of it has BNDDIR(‘QC2LE’) in the header specification. Today, a number of RPG IV developers assume BNDDIR(‘QC2LE’) is one of those “just gotta include it” controls like the OPTIONS(*NODEBUGIO) keyword. But that hasn’t been the case since at least V6R1.

    Binding Directories

    Binding Directory objects (*BNDDIR) are a simple list of *MODULE and *SRVPGM object names. Binding Directory Entries are the *MODULE and *SRVPGM object names stored in the Bind Directory object.

    That list is used when you compile your own programs. The compiler (technically the Binder or CRTPGM step) uses binding directories to resolve the procedures you call in your own code. That is, it is a directory of objects that contain each of the procedures you’re calling; that is procedures not defined locally within your RPG IV program itself. For example, if you have the following in your RPG IV program:

       ctl-opt  BNDDIR('QC2LE');
        system('ovrprtf QPRINT OUTQ(COZZI)');
    

    The binder needs to locate the system procedure so it can resolve this reference. It uses the binding directory QC2LE that you provided, to create a list of modules and service programs known as Binding Directory Entries. It then checks the export list of each entry for the procedure named system (case sensitive). If it finds it, everything is wonderful, if not, you get an unresolved external reference error message.

    The QC2LE binding directory contains over two dozen entries that are searched for various C and MI runtime procedures. Each entry can export thousands of procedures or variable names.

    QC2LE Is No Longer Needed

    After a few years of using BNDDIR(‘QC2LE’), I was speaking with IBM Rochester legend Bruce Vining on a different topic and mentioned the pervasive QC2LE use, suggesting it should be integrated into the compiler so it wouldn’t be required in every program. Turns out Bruce was on the same page. He was working on the regular APIs binding directory (QUSAPIBD) at the time and wanted to do just that; consolidate QC2LE with QUSAPIBD. Most operating system APIs were already exported via that QUSAPIDB binding directory. Only C and MI interfaces required QC2LE. The QUSAPIDB binding directory is always associated with the binder (CRTPGM and CRTSRVPGM) so it was never explicitly specified. In fact, no one outside of IBM needed to be aware of QUSAPIBD at all.

    To combine QC2LE with QUSAPIBD, we needed to extract what was in QC2LE and add those entries to QUSAPIBD. The problem was that RTVBNDSRC materialized the exported procedures and variables, but nothing other than WRKBNDDIRE and DSPBNDDIR showed you the contents of a Binding Directory. During the early days of ILE (which was named “NPM” before it was announced) I had written a program to read *BNDDIRE objects and dump out the entries. The *BNDDIR objects are a simple space object with fixed length entries. Therefore, it was relatively easy to do a little reverse engineering/trial and error to get it working.

    Later, Bruce used a similar technique to enhance the QUSAPIBD binding directory. This meant that things like QlgConvertCase, cvthc, and system would no longer require BNDDIR(‘QC2LE’) on the top of your RPG IV source code. So, beginning with IBM i5/OS V6R1, the need to include BNDDIR(‘QC2LE’) vanished. Today, if you see it in your code, you can feel confident to safely remove it.

    As the years went by, IBM enhanced DSPBNDDIR with OUTFILE support. You can now direct the entries of a Binding Directory to a database file with a simple CL command:

    DSPBNDDIR QSYS/QC2LE OUTPUT(*OUTFILE) OUTFILE(QGPL/PICKLES)
    

    After running the command, you have a list of the QC2LE entries in a database file named PICKLES. If you also send the QUSAPIBD entries to an outfile, you’ll notice that all the entries from QC2LE are replicated there. Therefore, you no longer need to reference QC2LE in your code.

    Binding Source

    How do you know what is exported from the various Binding Directory entries? What does a service program such as QC2SYS actually export? To find out, you need to use the WRKSRVPGM command and drill down to the Export list. Or you can use the RTVBNDSRC (Retrieve Binder Source) CL command and generate the Binder Source for the QC2SYS service program. For example:

    RTVBNDSRC SRVPGM(QC2SYS) SRCFILE(QGPL/QSRVSRC)
    

    The generated Binder Source is stored in QGPL/QSRVSRC(QC2SYS) and looks like this:

    STRPGMEXP PGMLVL(*CURRENT) SIGNATURE(X'000000000000000000009485A3A2A8A2')   
    /***********************************************************/      
    /*   *SRVPGM      QC2SYS       QSYS     05/17/23  09:06:15      */      
    /***********************************************************/      
      EXPORT SYMBOL("system")                                                   
      EXPORT SYMBOL("_C_NEU_system")                                            
    ENDPGMEXP
    

    You can see the infamous system C runtime function is exposed in two variations: the original named ‘system,’ and a CCSID neutral version named ‘_C_NEU_system’.

    Binding Directories Versus Binder Source

    A long-standing point of confusion has been the terms “Binder Source” and “Binding Directory.” One is source code, the other is an object type of *BNDDIR.

    • A Binding Directory (*BNDDIR) object contains a list of objects that can be imported or bound to your programs.
    • Binder Source is a source file member that contains EXPORT statements to identify the procedures in a *SRVPGM that may be imported by other programs.

    Binder Source

    When you create a *SRVPGM you specify binder source to control what is exported from that service program. The binder source parameters of CRTSRVPGM are:

    • EXPORT – Controls whether Binder Source controls exports or *ALL items are exported.
    • SRCFILE – The source file that contains the binder source member (when EXPORT(*SRCFILE) is specified.
    • SRCMBR – The binder source file member (when EXPORT(*SRCFILE) is specified.

    Binder Source is not required. Instead, you can specify EXPORT(*ALL) and force the binder to export all external procedures and variables. Exported procedure names can be quite lengthy. For example, our SQL iQuery ships with several *SRVPGM objects. Below is a segment of the binder source for one of the service programs. This excerpt contains C++ class objects that are used to when output to CSV, XLS, FTP, JSON, HTML, etc. is requested. You can see that the long export names are continued onto subsequent lines.

      EXPORT SYMBOL("__ct__6CChartFv")                                                
      EXPORT SYMBOL("__ct__7CcsvObjFv")                                               
      EXPORT SYMBOL("__ct__7CxlsObjFP6CLIobj")                                        
      EXPORT SYMBOL("__ct__7CSysFtpFv")                                               
      EXPORT SYMBOL("__ct__8CcsvPropFv")                                              
      EXPORT SYMBOL("__ct__8CxlsObj")                                      
      EXPORT SYMBOL("__ct__8CHtmlObjFv")                                              
      EXPORT SYMBOL("__ct__8CJSONObjFv")                                              
      EXPORT SYMBOL("__ct__8CSylkObjFv")                                              
      EXPORT SYMBOL("__ct__9CHtmlPropFv")                                             
      EXPORT SYMBOL("__dftct__Q2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2 + _3std9allocatorXTc__Fv")                                                          
      EXPORT SYMBOL("__dftdt__Q2_3std13basic_filebufXTcTQ2_3std11char_traitsXTc__F + v")
    

    Binder Source may also be used to export variables. The only variable that gets used with any kind of regularity is _EXCP_MSGID, which is exported from the QC2UTIL1 service program (also in the QC2LE binding directory).

    EXPORT SYMBOL("_C_proc_list")           
    EXPORT SYMBOL("_C_space_list")          
    EXPORT SYMBOL("_C_streams")             
    EXPORT SYMBOL("_C_stream_exit")         
    EXPORT SYMBOL("errno")                  
    EXPORT SYMBOL("_EXCP_MSGID")            
    EXPORT SYMBOL("_C_UTIL1_dont_use1")     
    EXPORT SYMBOL("_C_ag_type")             
    EXPORT SYMBOL("_C_stdin_buffer")        
    EXPORT SYMBOL("_C_act_mark")            
    EXPORT SYMBOL("_C_removemsg")           
    

    Tip: Compile your *MODULE and/or *SRVPGM and then use RTVBNDSRC to generate the binder language statements source code for the exported items. Then go into that source and remove and reorder the list of exported items as desired. This is typically how most developers handle binder source and exports.

    Binding Directory Entries SQL Function

    While Binder Source is, well, source, Binding Directories are actual IBM i objects. Internally *BNDDIR objects are a user space-like object, as I previously mentioned that hold a list of binding directory entries in fixed-length positions that repeats for each entry.

    At some point, System Value QSECURITY(40) shut down MI and C access to a lot of fun things on the system. One of them was direct access to *BNDDIR objects. With no API to read *BNDDIR entries, we are now limited to the following two CL commands:

    • WRKBNDDIRE – Work with the entries of a Binding Directory
    • DSPBNDDIR – Display the entries of a Binding Directory

    The DSPBNDDIR supports options OUTPUT(* | *PRINT | *OUTFILE). The OUTFILE support can be used directly in RPG, or we can create an SQL Function to handle everything for us.

    Calling an API today is “so 1999.” Using CL OUTFILE support to access system interfaces just feels like using Indicators in RPG IV. You know you can, it has been around forever, but it makes you think you’re not as smart as you think you are.

    Last year I created an SQL User-defined Table Function (UDTF) named BNDDIR_ENTRIES that returns the list of entries for a Binding Directory. Today, if I’m in IBM ACS RUNSQL Scripts or using RUNiQRY on the CL command line, I use this table function to quickly view the entries in any Binding Directory.

    This SQL function accepts the name of the binding directory and generates a list of entry names along with all other available Entry information, including the date it was added to the Binding Directory. Here’s a look at the legacy QC2LE binding directory and returned by my BNDDIR_ENTRIES SQL Function:

    The BNDDIR_ENTRIES SQL Function returns the binding directory entries, along with the object type, activation setting, and date it was added to the binding directory. It uses the DSPBNDDIR OUTPUT(*OUTFILE) support to get the data and return it as an SQL resultSet. Normally I would use an API to get my SQL Function results internally, but with no such API and my access to the *BNDDIR object blocked . . . this is the way.

    The code is available over on my GitHub page: https://github.com/bobcozzi/BNDDIR_ENTRIES

    Just copy/paste the code into IBM ACS Runsql Scripts, or create a source file member named BNDDIRE and “compile” it with the RUNSQLSTM CL command.

    This version of the function works on IBM i V7R2 and later. Recently IBM added an SQL VIEW that contains all the binding directories on the system. I am not a fan of that approach. It tends not to perform well, and hand returns everything in the world and relies on you to filter it out with a WHERE clause. Why not just tell a function what you want, and get back what you want? That’s what I prefer. But if you’re on V7R4 or later, you can also check out the BINDING_DIRECTORY_INFO VIEW in QSYS2. Note that the documentation for this IBM-provided VIEW indicates that the date/timestamp being returned is the “timestamp when the object was created.” This is not correct. The timestamp is the timestamp of when the entry was added to the Binding Directory.

    Bob Cozzi is an IBM i contractor and consultant as well as the author of The Modern RPG Language, developer of SQL iQuery and SQL Tools, and a speaker on SQL and RPG IV topics you can actua

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, Access Client Solutions, API, CSV, FHG, Four Hundred Guru, FTP, HTML, IBM i, JSON, QC2LE, RPG IV, SQL, SQL iQuery, V7R4, XLS

    Sponsored by
    PERFSCAN

    Revolutionary Performance Management Software

    At Greymine, we recognize there is a void in the IT world for a dedicated performance management company and also for a performance management tool that’s modern, easy to use, and doesn’t cost an arm and a leg. That’s why we created PERFSCAN.

    PERFSCAN is designed to make your job easier. With revolutionary technology, an easy-to-read report and graphics engine, and real time monitoring, tasks that used to take days can now take minutes. This means you will know your system better and will be able to provide better service to your customers.

    OUR FEATURES

    PERFSCAN is full of robust features that don’t require you to take a three-day class in order to use the product effectively.

    Customizable Performance Reporting

    Whether you are troubleshooting a major system problem or simply creating a monthly report, PERFSCAN lets you select any combination of desired performance metrics (CPU, Disk, and Memory).

    User Defined Performance Guidelines

    No matter if you are a managed service provider managing complex systems in the cloud or a customer analyzing your on-premises solution, PERFSCAN gives you the flexibility to define all mission critical guidelines how they need to be.

    Understanding The Impact Of Change

    Tired of all the finger pointing when performance is suffering? PERFSCAN’s innovative What’s Changed and Period vs. Period analysis creates a culture of proof by correlating known environmental changes with system performance metrics.

    Comprehensive Executive Summary

    Creating performance graphs is easy. Understanding what they mean is another thing. With one mouse click, PERFSCAN includes an easy-to-understand executive summary for each core metric analyzed.

    Combined Real-Time Monitor And Performance Analysis Tool

    With PERFSCAN’s combined built in enterprise real-time monitor and historical performance analysis capability, you will always know how your mission-critical systems are performing.

    Cloud Performance Reporting Is Easy

    Managing performance for production systems in the cloud can be a black hole to many system administrators. The good news is PERFSCAN analyzes all core metrics regardless of the location. That’s why MSPs and customers love PERFSCAN.

    Detailed Job Analysis

    PERFSCAN shows detailed top job analysis for any desired period. All metrics are displayed in two ways: Traditional Report and Percentage Breakdown Pie Chart. This toggle capability instantly shows the jobs using the most system resources.

    Save Report Capability

    Your boss lost the report you gave to him on Friday. Now what do you do? With PERFSCAN’s save report capability, any report can be retrieved in a matter of seconds.

    Professional PDF Reporting With Branding

    Creating professional looking reports for your customers has never been easier with PERFSCAN. Branding for our partners and service provider customers is easy with PERFSCAN.

    Check it out at perfscan.com

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    How Does Your Infrastructure Spending Stack Up To The World? Fortra Completes Postmortem Of GoAnywhere Vulnerability

    One thought on “Guru: Binding Directory Entries”

    • Glenn Gundermann says:
      June 6, 2023 at 2:26 pm

      This is really cool. You can learn something every day.
      Thank you for this knowledge.

      Reply

    Leave a Reply Cancel reply

TFH Volume: 33 Issue: 33

This Issue Sponsored By

  • Maxava
  • New Generation Software
  • PERFSCAN
  • Computer Keyes
  • Manta Technologies

Table of Contents

  • Power10 Boosts NVM-Express Flash Performance
  • Fortra Completes Postmortem Of GoAnywhere Vulnerability
  • Guru: Binding Directory Entries
  • How Does Your Infrastructure Spending Stack Up To The World?
  • IBM i PTF Guide, Volume 25, Number 22

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • ARCAD’s Deal with IBM for DevOps In Merlin Is Exclusive
  • In The IBM i Trenches With: Maxava
  • Is The Cloud On Your IBM i Horizon?
  • Four Hundred Monitor, September 20
  • IBM i PTF Guide, Volume 25, Number 38
  • The Subscription Pricing For The IBM i Stack So Far
  • Facing The Challenges Of Upgrading Old Systems With The Cloud
  • Guru: Generating XML Using SQL – The Easy Way
  • Rocket Buys Data Integration Provider B.O.S.
  • IBM i PTF Guide, Volume 25, Number 37

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2023 IT Jungle