RPX/RPL Export

Export Tables

Code decoration generates data that preprpl[32|64] looks for, which describes each export. A definitions file can also be used to enumerate the desired exports.

Both methods can be used simultaneously. preprpl[32|64] takes the collected list of all exported symbols, and then finds all of them in the object files and libraries that are listed as input.

Export Table Format

The export table is formatted to have its own copy of the exported symbol names. This allows the main symbol table to stripped or obfuscated. The export table is also sorted by export name so that searches into it are fast (Log2n).

The export table is the basis for the import object that is generated by makerpl[32|64] later on.

Finding Exports

Exports from a RPL are found manually using the function:

int OSDynLoad_FindExport(
        OSDynLoad_ModuleHandle aModuleHandle, 
        int                    aTypeIsData, 
        char const *           apExportName, 
        void * *               appRetAddr
);

The time taken to find an export this way is Log2 n, where n is the number of exported symbols from a module (binary search). Potentially, this is different from time taken at module load, which can be on the order of constant time in most cases. Finding an export does not alter the reference count.

There is no runtime overhead cost for creating the search table for module exports.

Usage

A module is loaded using:

int OSDynLoad_Acquire(
        char const *             apFileName, 
        OSDynLoad_ModuleHandle * apRetHandle
);

This returns an error code. If there is no error, a handle to the loaded module is placed in the return pointer argument. Attempts to acquire the same module repeatedly do not cause another load, they just increment a reference count.

If you know that a module is loaded, you can use:

int OSDynLoad_IsModuleLoaded(
        char const *             apFileName, 
        OSDynLoad_ModuleHandle * apRetHandle
);

This returns an error code. If there is no error, and if a handle to the loaded module is placed in the return pointer argument, then you can use this handle with OSDynLoad_FindExport. OSDynLoad_IsModuleLoaded does not increment a reference count. See OSDynLoad_IsModuleLoaded regarding its use with OSDynLoad_Release.

Releasing a module is as follows.

int OSDynLoad_Release(
        OSDynLoad_ModuleHandle aModuleHandle
);

A module is unloaded only after all references to it are released.

Usage

After a module is successfully loaded, its entry point is called to perform initialization. Module entry points have the following name and prototype:

#define OSDYNLOAD_ENTRY_REASON_LOAD     1
#define OSDYNLOAD_ENTRY_REASON_UNLOAD   2
typedef int (*pf_rpl_entry)(OSDynLoad_ModuleHandle aHandle, int aReason);

The entry point receives its own handle value, and a reason for the invocation. If the reason is …REASON_LOAD, and a nonzero error value is returned, the entire load process for all modules being loaded is aborted. In this case, any modules that received a load notification also receive an unload notification.

After a module is successfully loaded, a callback to registered viewers (like the debugger) occurs to inform them of the act. After a module is loaded, exports within it can be found.

Exporting

There are several options for you to choose from when exporting. Regardless of the option that you choose, data exports are similar, and the header file for functions remains the same (undecorated).

Revision History

2014/03/10 Added OSDynLoad_IsModuleLoaded.
2013/11/01 Added OSDynLoad_IsModuleLoaded.
2013/05/08 Automated cleanup pass.
2013/03/15 Initial version.


CONFIDENTIAL