OpenWiki

Yahm Lib

Edit this page (last edited November 20, 2005)
Palm Notes | Recent Changes | Title Index | User Preferences | Random Page | Help
  • Library purpose
  • Library review
  • The benefits of YAHMLib
  • Library integration
  • Error codes
  • High level API
  • Middle level API
  • .got section
  • Low level API
  • User-defined functions
  • The meaning of thunk types
  • Thunks for GCC
  • Thunks for CodeWarrior
  • Library purpose

    YAHM library was designed for simple migration from ARM-based hack to standalone application. With help of YAHMlib you can easily implement syscall patching inside your application.

    Library review

    YAHMLib has 3 layers of API. All API's are implemented as m68k functions.

    The benefits of YAHMLib

    Current documentation assumes that reader already knows how to create hack. Only YAHMLib API is duscussed below.

    Library integration

    YAHM library can be used with both CW and GCC compilers. Just include lowlevel.c and trapcontrol5.c sources to your project. yahm_lib.h header contains all YAHM API functions. Include 5 arm resources into target executable.

    Also you can include YahmLibrary.rcp into your project:
    #include "yahm_int.h"
    
    
    DATA "armc" ID YAHM_INIT_RES_ID "armc270E.bin"
    DATA "armc" ID YAHM_SET_TRAP_RES_ID "armc270F.bin"
    
    DATA "armc" ID YAHM_FAT_THUNK_RES_ID "fatthunk.bin"
    DATA "armc" ID YAHM_SHORT_RES_ID "SHORT.BIN"
    DATA "armc" ID  YAHM_SHORT_OLD_RES_ID "shorttoold.bin"
    DATA "armc" ID  YAHM_CW_THUNK_RES_ID "cwthunk.bin"
    
    

    Error codes

    YAHM library return some custom errors:

    High level API

    High level API is the simplest one. Just move all resources from hack to standalone application. API contains of two functions: one for hack activation and one for hack deactivation.
    Err YAHM_InstallHack(void);
    
    Err YAHM_UninstallHack(void);
    

    YAHM_InstallHack install all 'armc' resources from current application. Alse initialization 'armc' 999 resource is called before if exists.

    YAHM_UninstallHack uninstall patches that were installed with YAHM_InstallHack.

    Known issues for hack to application migration: Check type of application in hack code. Now it's 'appl', not the 'code'. Implement configuration screen manually. It's much simple than writing a hack configuration panel.

    Middle level API

    Use middle level instead of high level if you want flexible trap patching. High level call middle level functions for each 'armc' resource.

    Err YAHM_ExecuteInitialization(void *initCodeResource, Boolean init);
    // initCodeResource - pointer to initialization arm code
    // init - true for initialization, false for deinitialization
    
    Err YAHM_InstallTrap(MemHandle hTrapCode, MemHandle hGot, MemHandle hTrapInfo, UInt32 creator, UInt16 resId);
    // hTrap code - handle for trap arm code chunk (or resource)
    // hGot - handle for gcc GOT section, pass NULL for CodeWarrior 
    // hTrapInfo - handle for TRA5 resource with YAHM_SyscallInfo5 structure
    // creator, resId - those parameters are used for FtrSet(creator, resId, oldTrapAddress) 
    
    void YAHM_UninstallTrap(MemHandle hTrap, UInt32 creator, UInt16 resID);
    // hTrap code - handle for trap arm code chunk (or resource)
    // creator, resId - those parameters are used for restoring old address from FtrGet(creator, resId, &oldTrapAddress) 
    
    
    void *YAHM_FixupGccCode(MemHandle hGot, void *pCodeResource, void* *ppGotPtr);
    void *YAHM_FixupGccCodeEx(MemHandle hGot, MemHandle  hCodeResource, void* *ppGotPtr);
    // pCodeResource - pointer to arm code chunk
    // hCodeResource - pointer to arm code chunk
    // hGotResource - handle for gcc GOT section, pass NULL for CodeWarrior 
    // ppGotPtr - pointer to GOT into relocated chunk
    // return value - pointer to relocated chunk or codeResource if GOT section is absent
    
    void YAHM_FreeRelocatedChunk(void *pRelocatedCode);
    
    
    

    YAHM_ExecuteInitialization used for calling initialization/deinitialization resouce manually.

    Call YAHM_InstallTrap to install trap. Pass handles for code, .got, trap info for proper installation. Function save old syscall pointer to feature with creator and resId parameters.

    Call YAHM_UninstallTrap to uninstall trap.

    .got section

    Compilation with arm-gcc creates ELF executable file and extracts code section from it. Creating position-independent code (PIC) in ELF executable creates additional .got section. Code uses .got section to evaluate function addresses and literal strings offsets. build-prc from YAHM SDK includes .got section into target .prc file with the same ResID as appropriate armc resource has. YAHM loads both armc and .got and merge it into single resource in dynamic heap. High and Middle levels load .got section too. YAHM_FixupGccCode and YAHM_FixupGccCodeEx function can be used to load resource with .got section manually. Those functions merge code resource (passed in hCodeResorce or pCodeResource parameters) and .got resource (passed in hGotResource parameter). Function returns an address of relocated chunk in dynamic memory or NULL if there are no enough memory. ppGotPtr parameter points to .got section on exit. This parameter value can be used to set R10 register for PIC arm code.

    YAHM_FreeRelocatedChunk can be used for freeing relocated code chunk.

    hGotResource parameter can be set to NULL. In this case functions don't make relocation and return pCodeResource as relocated address value. If relocated address is found in storage memory, then YAHM_FreeRelocatedChunk doesn't free chunk. This feature can be used to load and relocate both GCC and CW resources similary.

    YAHMLib v1.07+ checks for NVFS manager existence and copies all code resources into dynamic heap to avoid problems with NVFS DBCache.

    Low level API

    Low level API mimics pre-OS5 API. Only two functions for setting and retrieving trap handler address. Those functions require deep knowledge of ARM programming.

    void *YAHM_GetTrapAddress(UInt32 base, UInt32 offset);
    
    void *YAHM_SetTrapAddress(UInt32 base, UInt32 offset, void *trapHandler);
    

    User-defined functions

    YAHMLib requires few user-defined functions to work. Developer should implement those simple functions manually. The simplest version are showed below.

    Persistent settings
    typedef struct{ // Global YAHM settings. Should be saved in preferences.
            UInt32 protectYAHM; // if true, then YAHM protect application database
            UInt32 thunkCount;        // number of trap slots. allocate at least 40-50 slots.
    }YAHM_persistSettings;
    
    // copy persist settings to structure, allocated by YAHM
    extern void YAHM_GetPersistSettings(YAHM_persistSettings *pSettings);
    
    // implementation sample
    void YAHM_GetPersistSettings(YAHM_persistSettings *pSettings){
            pSettings->protectYAHM = true;
            pSettings->thunkCount = 40;
    }
    

    YAHMLibrary require persistent setting to work. Developer should implement YAHM_GetPersistSettings function for changing library behaviour. Those settings can be either set in code or can be changed by user.

    Runtime settings
    typedef struct{ // Runtime YAHM settings. They are valid on single YAHM execution. Should be saved in feature pointer
            UInt32 activeHacksCount;
            void *pPool;
    }YAHM_runtimeSettings;
    
    extern void YAHM_SetRuntimeSettings(YAHM_runtimeSettings *pSettings);
    // return ptr to runtime settings structure.
    extern YAHM_runtimeSettings *YAHM_GetRuntimeSettingsPtr(void);
    
    // callback function. 
    extern void YAHM_warnAboutIncompatibleUpdate(void);
    
    
    // sample implementation
    void YAHM_SetRuntimeSettings(YAHM_runtimeSettings *pSettings)
    {
             FtrSet(MY_CRID, YAHM_FTR_ID, (UInt32)pSettings);
    }
    
    YAHM_runtimeSettings *YAHM_GetRuntimeSettingsPtr(void)
    {
            YAHM_runtimeSettings *pSet = NULL;
            FtrGet(CRID, YAHM_FTR_ID, (UInt32 *)&pSet);
            if (pSet == NULL){
                    pSet = MemPtrNew(sizeof(YAHM_runtimeSettings));
                    YAHM_SetRuntimeSettings(pSet);
                    MemPtrSetOwner(pSet, 0);
                    MemSet(pSet, sizeof(YAHM_runtimeSettings), 0);
            }
            return pSet;
    }
    

    Developer is responsible for allocating and saving YAHM library runtime settings. YAHM_GetRuntimeSettingsPtr function should return pointer to persistent structure. For the first time this function should allocate memory chunk for settings. The best way is saving pointer to structure in feature memory. Runtime settings should be valid from the first hack activation up to device reset. You can share one runtime settings between different programs.

    Function YAHM_warnAboutIncompatibleUpdate is called when several programs (or two different program versions) are used different versions of YAHM Library. This function usually should call SysFatalAlert.

    The meaning of thunk types

    Thunk is a piece of code and data that sits between syscall table and your patch code. Thunk was introduced to solve two problems: to prevent patch chain breaks and to execute runtime startup.

    Different thunk types require different code configurations. Currently YAHMLib supports three type of thunks.

    Thunks for GCC

    Thunks for CodeWarrior


    Palm Notes | Recent Changes | Title Index | User Preferences | Random Page | Help
    Edit this page | View other revisions
    Print this page | View XML
    Find page by browsing, searching or an index
    Edited November 20, 2005 (diff)
    Valid XHTML 1.0!Valid CSS!