Changeset 2855


Ignore:
Timestamp:
Nov 4, 2006, 3:30:19 AM (19 years ago)
Author:
bird
Message:

More code.

Location:
trunk/kLdr
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.c

    r2853 r2855  
    136136}
    137137
     138
     139/**
     140 * Compares arch+cpu some code was generated for with a arch+cpu for executing it
     141 * to see if it'll work out fine or not.
     142 *
     143 * @returns 0 if the code is compatible with the cpu.
     144 * @returns KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE if the arch+cpu isn't compatible with the code.
     145 * @param   enmCodeArch The architecture the code was generated for.
     146 * @param   enmCodeCpu  The cpu the code was generated for.
     147 * @param   enmArch     The architecture to run it on.
     148 * @param   enmCpu      The cpu to run it on.
     149 */
     150int kLdrCompareCpus(KLDRARCH enmCodeArch, KLDRCPU enmCodeCpu, KLDRARCH enmArch, KLDRCPU enmCpu)
     151{
     152    /*
     153     * Compare arch and cpu.
     154     */
     155    if (enmCodeArch != enmArch)
     156        return KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     157
     158    /* exact match is nice. */
     159    if (enmCodeCpu == enmCpu)
     160        return 0;
     161    switch (enmArch)
     162    {
     163        case KLDRARCH_X86_16:
     164            if (enmCpu < KLDRCPU_FIRST_X86_16 || enmCpu > KLDRCPU_LAST_X86_16)
     165                return KLDR_ERR_INVALID_PARAMETER;
     166
     167            /* intel? */
     168            if (enmCodeCpu <= KLDRCPU_CORE2_16)
     169            {
     170                /* also intel? */
     171                if (enmCpu <= KLDRCPU_CORE2_16)
     172                    return enmCodeCpu <= enmCpu ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     173                switch (enmCpu)
     174                {
     175                    case KLDRCPU_K6_16:
     176                        return enmCodeCpu <= KLDRCPU_I586 ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     177                    case KLDRCPU_K7_16:
     178                    case KLDRCPU_K8_16:
     179                    default:
     180                        return enmCodeCpu <= KLDRCPU_I686 ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     181                }
     182            }
     183            /* amd */
     184            return enmCpu >= KLDRCPU_K6_16 && enmCpu <= KLDRCPU_K8_16
     185                    ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     186
     187        case KLDRARCH_X86_32:
     188            if (enmCpu < KLDRCPU_FIRST_X86_32 || enmCpu > KLDRCPU_LAST_X86_32)
     189                return KLDR_ERR_INVALID_PARAMETER;
     190
     191            /* blend? */
     192            if (enmCodeCpu == KLDRCPU_X86_32_BLEND)
     193                return 0;
     194
     195            /* intel? */
     196            if (enmCodeCpu <= KLDRCPU_CORE2_32)
     197            {
     198                /* also intel? */
     199                if (enmCpu <= KLDRCPU_CORE2_32)
     200                    return enmCodeCpu <= enmCpu ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     201                switch (enmCpu)
     202                {
     203                    case KLDRCPU_K6:
     204                        return enmCodeCpu <= KLDRCPU_I586 ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     205                    case KLDRCPU_K7:
     206                    case KLDRCPU_K8_32:
     207                    default:
     208                        return enmCodeCpu <= KLDRCPU_I686 ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     209                }
     210            }
     211            /* amd */
     212            return enmCpu >= KLDRCPU_K6 && enmCpu <= KLDRCPU_K8_32
     213                    ? 0 : KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     214
     215        case KLDRARCH_AMD64:
     216            if (enmCpu < KLDRCPU_FIRST_AMD64 || enmCpu > KLDRCPU_LAST_AMD64)
     217                return KLDR_ERR_INVALID_PARAMETER;
     218
     219            /* blend? */
     220            if (enmCodeCpu == KLDRCPU_AMD64_BLEND)
     221                return 0;
     222            /* this is simple for now. */
     223            return KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     224
     225        default:
     226            break;
     227    }
     228    return KLDR_ERR_ARCH_CPU_NOT_COMPATIBLE;
     229}
     230
     231
     232/**
     233 * Gets the arch+cpu of the calling cpu.
     234 *
     235 * @param   penmArch    Where to store the cpu architecture.
     236 * @param   penmCpu     Where to store the cpu brand/model.
     237 */
     238void kLdrGetArchCpu(PKLDRARCH penmArch, PKLDRCPU penmCpu)
     239{
     240#if defined(__x86_64__) || defined(_M_X64) || defined(__AMD64__) || defined(_M_AMD64)
     241    *penmArch = KLDRARCH_AMD64;
     242    *penmCpu = KLDRCPU_AMD64_BLEND; ///@todo check it using cpu.
     243
     244#elif defined(__i386__) || defined(_M_IX86)
     245    *penmArch = KLDRARCH_X86_32;
     246    *penmCpu = KLDRCPU_X86_32_BLEND; ///@todo check it using cpu.
     247
     248#else
     249# error "Port me"
     250#endif
     251}
  • trunk/kLdr/kLdr.h

    r2854 r2855  
    281281/** @defgroup grp_kLdrMod   kLdrMod - The executable image intepreter
    282282 * @{ */
    283 
    284 
    285 /**
    286  * Debug info type (from the loader point of view).
    287  */
    288 typedef enum KLDRDBGINFOTYPE
    289 {
    290     /** The usual invalid enum value. */
    291     KLDRDBGINFOTYPE_INVALID = 0,
    292     /** Stabs. */
    293     KLDRDBGINFOTYPE_STABS,
    294     /** Debug With Arbitrary Record Format (DWARF). */
    295     KLDRDBGINFOTYPE_DWARF,
    296     /** Microsoft Codeview debug info. */
    297     KLDRDBGINFOTYPE_CODEVIEW,
    298     /** Watcom debug info. */
    299     KLDRDBGINFOTYPE_WATCOM,
    300     /** IBM High Level Language debug info.. */
    301     KLDRDBGINFOTYPE_HLL,
    302     /** The end of the valid debug info values (exclusive). */
    303     KLDRDBGINFOTYPE_END,
    304     /** Blow the type up to 32-bit. */
    305     KLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff
    306 } KLDRDBGINFOTYPE;
    307 /** Pointer to a kLdr debug info type. */
    308 typedef KLDRDBGINFOTYPE *PKLDRDBGINFOTYPE;
    309 
    310 
    311 /**
    312  * Stack information.
    313  */
    314 typedef struct KLDRSTACKINFO
    315 {
    316     /** The base address of the stack (sub) segment.
    317      * Set this to NIL_KLDRADDR if the module doesn't include any stack segment. */
    318     KLDRADDR        Address;
    319     /** The base address of the stack (sub) segment, link address.
    320      * Set this to NIL_KLDRADDR if the module doesn't include any stack (sub)segment. */
    321     KLDRADDR        LinkAddress;
    322     /** The stack size of the main thread.
    323      * If no stack (sub)segment in the module, this is the stack size of the main thread.
    324      * If the module doesn't contain this kind of information this field will be set to 0. */
    325     KLDRSIZE        cbStack;
    326     /** The stack size of non-main threads.
    327      * If the module doesn't contain this kind of information this field will be set to 0. */
    328     KLDRSIZE        cbStackThread;
    329 } KLDRSTACKINFO;
    330 /** Pointer to stack information. */
    331 typedef KLDRSTACKINFO *PKLDRSTACKINFO;
    332 /** Pointer to const stack information. */
    333 typedef const KLDRSTACKINFO *PCKLDRSTACKINFO;
    334 
    335 
    336 /**
    337  * Loader segment.
    338  */
    339 typedef struct KLDRSEG
    340 {
    341     /** Variable free to use for the kLdr user. */
    342     void           *pvUser;
    343     /** The segment name. (Might not be zero terminated!) */
    344     const char     *pchName;
    345     /** The length of the segment name. */
    346     uint32_t        cchName;
    347     /** The size of the segment. */
    348     KLDRSIZE        cb;
    349     /** The required segment alignment. */
    350     KLDRADDR        Alignment;
    351     /** The link address.
    352      * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */
    353     KLDRADDR        LinkAddress;
    354     /** The address the segment was mapped at by kLdrModMap().
    355      * Set to NIL_KLDRADDR if not mapped. */
    356     KLDRADDR        MapAddress;
    357     /** The segment protection. */
    358     KLDRPROT        enmProt;
    359 } KLDRSEG;
    360 /** Pointer to a loader segment. */
    361 typedef KLDRSEG *PKLDRSEG;
    362 /** Pointer to a loader segment. */
    363 typedef const KLDRSEG *PCKLDRSEG;
    364 
    365 
    366 /**
    367  * Loader module format.
    368  */
    369 typedef enum KLDRFMT
    370 {
    371     /** The usual invalid 0 format. */
    372     KLDRFMT_INVALID = 0,
    373     /** The native OS loader. */
    374     KLDRFMT_NATIVE,
    375     /** The AOUT loader. */
    376     KLDRFMT_AOUT,
    377     /** The ELF loader. */
    378     KLDRFMT_ELF,
    379     /** The LX loader. */
    380     KLDRFMT_LX,
    381     /** The mach-o loader. */
    382     KLDRFMT_MACHO,
    383     /** The LX loader. */
    384     KLDRFMT_PE,
    385     /** The end of the valid format values (exclusive). */
    386     KLDRFMT_END,
    387     /** Hack to blow the type up to 32-bit. */
    388     KLDRFMT_32BIT_HACK = 0x7fffffff
    389 } KLDRFMT;
    390 
    391 
    392 /**
    393  * Loader module type.
    394  */
    395 typedef enum KLDRTYPE
    396 {
    397     /** The usual invalid 0 type. */
    398     KLDRTYPE_INVALID = 0,
    399     /** Object file. */
    400     KLDRTYPE_OBJECT,
    401     /** Executable module, fixed load address. */
    402     KLDRTYPE_EXECUTABLE_FIXED,
    403     /** Executable module, relocatable, non-fixed load address. */
    404     KLDRTYPE_EXECUTABLE_RELOCATABLE,
    405     /** Executable module, position independent code, non-fixed load address. */
    406     KLDRTYPE_EXECUTABLE_PIC,
    407     /** Shared library, fixed load address.
    408      * Typically a system library. */
    409     KLDRTYPE_SHARED_LIBRARY_FIXED,
    410     /** Shared library, relocatable, non-fixed load address. */
    411     KLDRTYPE_SHARED_LIBRARY_RELOCATABLE,
    412     /** Shared library, position independent code, non-fixed load address. */
    413     KLDRTYPE_SHARED_LIBRARY_PIC,
    414     /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */
    415     KLDRTYPE_FORWARDER_DLL,
    416     /** Core or dump. */
    417     KLDRTYPE_CORE,
    418     /** The end of the valid types values (exclusive). */
    419     KLDRTYPE_END,
    420     /** Hack to blow the type up to 32-bit. */
    421     KLDRTYPE_32BIT_HACK = 0x7fffffff
    422 } KLDRTYPE;
    423 
    424283
    425284/**
     
    464323    KLDRARCH_32BIT_HACK = 0x7fffffff
    465324} KLDRARCH;
    466 
     325/** Pointer to a CPU architecture type. */
     326typedef KLDRARCH *PKLDRARCH;
    467327
    468328/**
     
    484344    KLDRCPU_I586_16,
    485345    KLDRCPU_I686_16,
     346    KLDRCPU_P4_16,
     347    KLDRCPU_CORE2_16,
    486348    KLDRCPU_K6_16,
    487349    KLDRCPU_K7_16,
    488350    KLDRCPU_K8_16,
     351    KLDRCPU_FIRST_X86_16 = KLDRCPU_I8086,
     352    KLDRCPU_LAST_X86_16 = KLDRCPU_K8_16,
    489353    /** @} */
    490354
    491355    /** @name KLDRARCH_X86_32
    492356     * @{ */
     357    KLDRCPU_X86_32_BLEND,
    493358    KLDRCPU_I386,
    494359    KLDRCPU_I486,
     
    501366    KLDRCPU_K7,
    502367    KLDRCPU_K8_32,
     368    KLDRCPU_FIRST_X86_32 = KLDRCPU_I386,
     369    KLDRCPU_LAST_X86_32 = KLDRCPU_K8_32,
    503370    /** @} */
    504371
    505372    /** @name KLDRARCH_AMD64
    506373     * @{ */
     374    KLDRCPU_AMD64_BLEND,
    507375    KLDRCPU_K8,
    508376    KLDRCPU_P4_64,
    509377    KLDRCPU_CORE2,
     378    KLDRCPU_FIRST_AMD64 = KLDRCPU_K8,
     379    KLDRCPU_LAST_AMD64 = KLDRCPU_CORE2,
    510380    /** @} */
    511381
     
    515385    KLDRCPU_32BIT_HACK = 0x7fffffff
    516386} KLDRCPU;
     387/** Pointer to a CPU type. */
     388typedef KLDRCPU *PKLDRCPU;
     389
     390void kLdrGetArchCpu(PKLDRARCH penmArch, PKLDRCPU penmCpu);
     391int kLdrCompareCpus(KLDRARCH enmCodeArch, KLDRCPU enmCodeCpu, KLDRARCH enmArch, KLDRCPU enmCpu);
     392
     393
     394/**
     395 * Debug info type (from the loader point of view).
     396 */
     397typedef enum KLDRDBGINFOTYPE
     398{
     399    /** The usual invalid enum value. */
     400    KLDRDBGINFOTYPE_INVALID = 0,
     401    /** Stabs. */
     402    KLDRDBGINFOTYPE_STABS,
     403    /** Debug With Arbitrary Record Format (DWARF). */
     404    KLDRDBGINFOTYPE_DWARF,
     405    /** Microsoft Codeview debug info. */
     406    KLDRDBGINFOTYPE_CODEVIEW,
     407    /** Watcom debug info. */
     408    KLDRDBGINFOTYPE_WATCOM,
     409    /** IBM High Level Language debug info.. */
     410    KLDRDBGINFOTYPE_HLL,
     411    /** The end of the valid debug info values (exclusive). */
     412    KLDRDBGINFOTYPE_END,
     413    /** Blow the type up to 32-bit. */
     414    KLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff
     415} KLDRDBGINFOTYPE;
     416/** Pointer to a kLdr debug info type. */
     417typedef KLDRDBGINFOTYPE *PKLDRDBGINFOTYPE;
     418
     419
     420/**
     421 * Stack information.
     422 */
     423typedef struct KLDRSTACKINFO
     424{
     425    /** The base address of the stack (sub) segment.
     426     * Set this to NIL_KLDRADDR if the module doesn't include any stack segment. */
     427    KLDRADDR        Address;
     428    /** The base address of the stack (sub) segment, link address.
     429     * Set this to NIL_KLDRADDR if the module doesn't include any stack (sub)segment. */
     430    KLDRADDR        LinkAddress;
     431    /** The stack size of the main thread.
     432     * If no stack (sub)segment in the module, this is the stack size of the main thread.
     433     * If the module doesn't contain this kind of information this field will be set to 0. */
     434    KLDRSIZE        cbStack;
     435    /** The stack size of non-main threads.
     436     * If the module doesn't contain this kind of information this field will be set to 0. */
     437    KLDRSIZE        cbStackThread;
     438} KLDRSTACKINFO;
     439/** Pointer to stack information. */
     440typedef KLDRSTACKINFO *PKLDRSTACKINFO;
     441/** Pointer to const stack information. */
     442typedef const KLDRSTACKINFO *PCKLDRSTACKINFO;
     443
     444
     445/**
     446 * Loader segment.
     447 */
     448typedef struct KLDRSEG
     449{
     450    /** Variable free to use for the kLdr user. */
     451    void           *pvUser;
     452    /** The segment name. (Might not be zero terminated!) */
     453    const char     *pchName;
     454    /** The length of the segment name. */
     455    uint32_t        cchName;
     456    /** The size of the segment. */
     457    KLDRSIZE        cb;
     458    /** The required segment alignment. */
     459    KLDRADDR        Alignment;
     460    /** The link address.
     461     * Set to NIL_KLDRADDR if the segment isn't supposed to be mapped. */
     462    KLDRADDR        LinkAddress;
     463    /** The address the segment was mapped at by kLdrModMap().
     464     * Set to NIL_KLDRADDR if not mapped. */
     465    KLDRADDR        MapAddress;
     466    /** The segment protection. */
     467    KLDRPROT        enmProt;
     468} KLDRSEG;
     469/** Pointer to a loader segment. */
     470typedef KLDRSEG *PKLDRSEG;
     471/** Pointer to a loader segment. */
     472typedef const KLDRSEG *PCKLDRSEG;
     473
     474
     475/**
     476 * Loader module format.
     477 */
     478typedef enum KLDRFMT
     479{
     480    /** The usual invalid 0 format. */
     481    KLDRFMT_INVALID = 0,
     482    /** The native OS loader. */
     483    KLDRFMT_NATIVE,
     484    /** The AOUT loader. */
     485    KLDRFMT_AOUT,
     486    /** The ELF loader. */
     487    KLDRFMT_ELF,
     488    /** The LX loader. */
     489    KLDRFMT_LX,
     490    /** The mach-o loader. */
     491    KLDRFMT_MACHO,
     492    /** The LX loader. */
     493    KLDRFMT_PE,
     494    /** The end of the valid format values (exclusive). */
     495    KLDRFMT_END,
     496    /** Hack to blow the type up to 32-bit. */
     497    KLDRFMT_32BIT_HACK = 0x7fffffff
     498} KLDRFMT;
     499
     500
     501/**
     502 * Loader module type.
     503 */
     504typedef enum KLDRTYPE
     505{
     506    /** The usual invalid 0 type. */
     507    KLDRTYPE_INVALID = 0,
     508    /** Object file. */
     509    KLDRTYPE_OBJECT,
     510    /** Executable module, fixed load address. */
     511    KLDRTYPE_EXECUTABLE_FIXED,
     512    /** Executable module, relocatable, non-fixed load address. */
     513    KLDRTYPE_EXECUTABLE_RELOCATABLE,
     514    /** Executable module, position independent code, non-fixed load address. */
     515    KLDRTYPE_EXECUTABLE_PIC,
     516    /** Shared library, fixed load address.
     517     * Typically a system library. */
     518    KLDRTYPE_SHARED_LIBRARY_FIXED,
     519    /** Shared library, relocatable, non-fixed load address. */
     520    KLDRTYPE_SHARED_LIBRARY_RELOCATABLE,
     521    /** Shared library, position independent code, non-fixed load address. */
     522    KLDRTYPE_SHARED_LIBRARY_PIC,
     523    /** DLL that contains no code or data only imports and exports. (Chiefly OS/2.) */
     524    KLDRTYPE_FORWARDER_DLL,
     525    /** Core or dump. */
     526    KLDRTYPE_CORE,
     527    /** The end of the valid types values (exclusive). */
     528    KLDRTYPE_END,
     529    /** Hack to blow the type up to 32-bit. */
     530    KLDRTYPE_32BIT_HACK = 0x7fffffff
     531} KLDRTYPE;
    517532
    518533
     
    704719int     kLdrModEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
    705720                           uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
    706 int     kLdrModGetImport(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName);
    707 int32_t kLdrModNumberOfImports(PKLDRMOD pMod, void *pvBits);
    708 int     kLdrModCanExecuteOn(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
    709 int     kLdrModGetStackInfo(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
    710 int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
     721int     kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName);
     722int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits);
     723int     kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
     724int     kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
     725int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
    711726/** Pointer to a debug info enumberator callback. */
    712727typedef FNKLDRENUMDBG *PFNKLDRENUMDBG;
    713 int     kLdrModEnumDbgInfo(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
    714 int     kLdrModHasDbgInfo(PKLDRMOD pMod, void *pvBits);
     728int     kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     729int     kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits);
    715730
    716731/** @name Operations On The Internally Managed Mapping
     
    777792                           PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
    778793    /** @copydoc kLdrModGetImport */
    779     int (* pfnGetImport)(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName);
     794    int (* pfnGetImport)(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName);
    780795    /** @copydoc kLdrModNumberOfImports */
    781     int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, void *pvBits);
     796    int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, const void *pvBits);
    782797    /** @copydoc kLdrModCanExecuteOn */
    783     int (* pfnCanExecuteOn)(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
     798    int (* pfnCanExecuteOn)(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
    784799    /** @copydoc kLdrModGetStackInfo */
    785     int (* pfnGetStackInfo)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
     800    int (* pfnGetStackInfo)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
    786801    /** @copydoc kLdrModQueryMainEntrypoint */
    787     int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
     802    int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
    788803    /** @copydoc kLdrModEnumDbgInfo */
    789     int (* pfnEnumDbgInfo)(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     804    int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
    790805    /** @copydoc kLdrModHasDbgInfo */
    791     int (* pfnHasDbgInfo)(PKLDRMOD pMod, void *pvBits);
     806    int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits);
    792807    /** @copydoc kLdrModMap */
    793808    int (* pfnMap)(PKLDRMOD pMod);
     
    10331048/** A memory allocation failed. */
    10341049#define KLDR_ERR_NO_MEMORY                                  (KLDR_ERR_BASE + 49)
    1035 
     1050/** The import ordinal was out of bounds. */
     1051#define KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS               (KLDR_ERR_BASE + 50)
     1052/** A forwarder chain was too long. */
     1053#define KLDR_ERR_TOO_LONG_FORWARDER_CHAIN                   (KLDR_ERR_BASE + 51)
    10361054
    10371055/** @name kLdrModPE status codes
  • trunk/kLdr/kLdrDyldMod.c

    r2854 r2855  
    929929            KLDRADDR uValue;
    930930            rc = kLdrModQuerySymbol(pBindMod->pMod, NULL, KLDRMOD_BASEADDRESS_MAP,
    931                                     uSymbol, pszSymbol, kldrDyldModFixupGetImportCallback, pPrereqMod, &uValue, &fKind);
     931                                    uSymbol, pszSymbol, kldrDyldModFixupGetImportCallback, pBindMod, &uValue, &fKind);
    932932            if (    !rc
    933933                &&  (   !fFound
     
    12121212
    12131213    rc = kLdrModQuerySymbol(pMod->pMod, NULL, KLDRMOD_BASEADDRESS_MAP,
    1214                             uSymbolOrdinal, pszSymbolName, kldrDyldModFixupGetImportCallback, pPrereqMod,
     1214                            uSymbolOrdinal, pszSymbolName, kldrDyldModFixupGetImportCallback, pMod,
    12151215                            &uValue, &fKind);
    12161216    if (!rc)
  • trunk/kLdr/kLdrMod.c

    r2854 r2855  
    319319 * @param   cchName         The size of the name buffer.
    320320 */
    321 int     kLdrModGetImport(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName)
     321int     kLdrModGetImport(PKLDRMOD pMod, const void *pvBits, uint32_t iImport, char *pszName, size_t cchName)
    322322{
    323323    KLDRMOD_VALIDATE(pMod);
     
    334334 *                          This can be used by some module interpreters to reduce memory consumption.
    335335 */
    336 int32_t kLdrModNumberOfImports(PKLDRMOD pMod, void *pvBits)
     336int32_t kLdrModNumberOfImports(PKLDRMOD pMod, const void *pvBits)
    337337{
    338338    KLDRMOD_VALIDATE(pMod);
     
    350350 *                          This can be used by some module interpreters to reduce memory consumption.
    351351 */
    352 int     kLdrModCanExecuteOn(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
    353 {
    354     KLDRMOD_VALIDATE(pMod);
    355     return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
     352int     kLdrModCanExecuteOn(PKLDRMOD pMod, const void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu)
     353{
     354    KLDRMOD_VALIDATE(pMod);
     355    if (pMod->pOps->pfnCanExecuteOn)
     356        return pMod->pOps->pfnCanExecuteOn(pMod, pvBits, enmArch, enmCpu);
     357    return kLdrCompareCpus(pMod->enmArch, pMod->enmCpu, enmArch, enmCpu);
    356358}
    357359
     
    369371 * @param   pStackInfo      The stack information.
    370372 */
    371 int     kLdrModGetStackInfo(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
     373int     kLdrModGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
    372374{
    373375    KLDRMOD_VALIDATE(pMod);
     
    391393 * @param   pMainEPAddress  Where to store the entry point address.
    392394 */
    393 int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
     395int     kLdrModQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
    394396{
    395397    KLDRMOD_VALIDATE(pMod);
     
    410412 * @see pg_kDbg for the debug info reader.
    411413 */
    412 int     kLdrModEnumDbgInfo(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
     414int     kLdrModEnumDbgInfo(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser)
    413415{
    414416    KLDRMOD_VALIDATE(pMod);
     
    426428 *                          This can be used by some module interpreters to reduce memory consumption.
    427429 */
    428 int     kLdrModHasDbgInfo(PKLDRMOD pMod, void *pvBits)
     430int     kLdrModHasDbgInfo(PKLDRMOD pMod, const void *pvBits)
    429431{
    430432    KLDRMOD_VALIDATE(pMod);
  • trunk/kLdr/kLdrModPE.c

    r2854 r2855  
    9999static int kldrModPEQueryForwarder(PKLDRMODPE pModPE, const void *pvBits, const char *pszForwarder,
    100100                                   PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind);
     101static int32_t kldrModPENumberOfImports(PKLDRMOD pMod, const void *pvBits);
    101102
    102103
     
    643644{
    644645    const IMAGE_IMPORT_DESCRIPTOR *paImpDir;
    645     uint32_t        cImpModules;
    646646    uint32_t        iImpModule;
    647647    uint32_t        cchImpModule;
     
    718718     * entry for the module... not sure if this is right though.
    719719     */
    720     cImpModules = pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
    721                 / sizeof(IMAGE_IMPORT_DESCRIPTOR);
     720    if (    !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
     721        ||  !pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
     722        return KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND;
    722723    paImpDir = KLDRMODPE_RVA2TYPE(pvBits,
    723724                                  pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
    724725                                  const IMAGE_IMPORT_DESCRIPTOR *);
    725     for (iImpModule = 0; iImpModule < cImpModules; cImpModules++)
    726     {
    727         const char     *pszName = KLDRMODPE_RVA2TYPE(pvBits, paImpDir[iImpModule].Name, const char *);
    728         const size_t    cchName = kLdrHlpStrLen(pszName);
     726
     727    kldrModPENumberOfImports(pModPE->pMod, pvBits);
     728    for (iImpModule = 0; iImpModule < pModPE->cImportModules; iImpModule++)
     729    {
     730        const char *pszName = KLDRMODPE_RVA2TYPE(pvBits, paImpDir[iImpModule].Name, const char *);
     731        size_t      cchName = kLdrHlpStrLen(pszName);
    729732        if (    (   cchName == cchImpModule
    730733                 || (   cchName > cchImpModule
     
    736739            &&  kLdrHlpMemIComp(pszName, pszForwarder, cchImpModule)
    737740           )
    738             break;
    739     }
    740     if (iImpModule >= cImpModules)
    741         return KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND;
    742 
    743     /*
    744      * Now the rest is up to the callback (almost).
    745      */
    746     rc = pfnGetForwarder(pModPE->pMod, iImpModule, uSymbol, pszSymbol, puValue, pfKind, pvUser);
    747     if (!rc && pfKind)
    748         *pfKind |= KLDRSYMKIND_FORWARDER;
    749     return rc;
     741        {
     742            /*
     743             * Now the rest is up to the callback (almost).
     744             */
     745            rc = pfnGetForwarder(pModPE->pMod, iImpModule, uSymbol, pszSymbol, puValue, pfKind, pvUser);
     746            if (!rc && pfKind)
     747                *pfKind |= KLDRSYMKIND_FORWARDER;
     748            return rc;
     749        }
     750    }
     751    return KLDR_ERR_PE_FORWARDER_IMPORT_NOT_FOUND;
    750752}
    751753
     
    831833
    832834/** @copydoc kLdrModGetImport */
    833 int (* pfnGetImport)(PKLDRMOD pMod, void *pvBits, uint32_t iImport, const char *pszName, size_t cchName);
     835static int kldrModPEGetImport(PKLDRMOD pMod, void *pvBits, uint32_t iImport, char *pszName, size_t cchName)
     836{
     837    PKLDRMODPE                      pModPE = (PKLDRMODPE)pMod->pvData;
     838    const IMAGE_IMPORT_DESCRIPTOR  *pImpDesc;
     839    const char                     *pszImportName;
     840    size_t                          cchImportName;
     841    int                             rc;
     842
     843    /*
     844     * Make sure we've got mapped bits and resolve any base address aliases.
     845     */
     846    rc = kldrModPEBitsAndBaseAddress(pModPE, &pvBits, NULL);
     847    if (rc)
     848        return rc;
     849
     850    /*
     851     * Simple bounds check.
     852     */
     853    if (iImport >= (uint32_t)kldrModPENumberOfImports(pMod, pvBits))
     854        return KLDR_ERR_IMPORT_ORDINAL_OUT_OF_BOUNDS;
     855
     856    /*
     857     * Get the name.
     858     */
     859    pImpDesc = KLDRMODPE_RVA2TYPE(pvBits,
     860                                  pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress
     861                                  + sizeof(IMAGE_IMPORT_DESCRIPTOR) * iImport,
     862                                  const IMAGE_IMPORT_DESCRIPTOR *);
     863    pszImportName = KLDRMODPE_RVA2TYPE(pvBits, pImpDesc->Name, const char *);
     864    cchImportName = strlen(pszImportName);
     865    if (cchImportName < cchName)
     866    {
     867        kLdrHlpMemCopy(pszName, pszImportName, cchImportName + 1);
     868        rc = 0;
     869    }
     870    else
     871    {
     872        kLdrHlpMemCopy(pszName, pszImportName, cchName);
     873        if (cchName)
     874            pszName[cchName - 1] = '\0';
     875        rc = KLDR_ERR_BUFFER_OVERFLOW;
     876    }
     877
     878    return rc;
     879}
     880
     881
    834882/** @copydoc kLdrModNumberOfImports */
    835 int32_t (* pfnNumberOfImports)(PKLDRMOD pMod, void *pvBits);
    836 /** @copydoc kLdrModCanExecuteOn */
    837 int (* pfnCanExecuteOn)(PKLDRMOD pMod, void *pvBits, KLDRARCH enmArch, KLDRCPU enmCpu);
     883static int32_t kldrModPENumberOfImports(PKLDRMOD pMod, const void *pvBits)
     884{
     885    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     886    if (pModPE->cImportModules == ~(uint32_t)0)
     887    {
     888        /*
     889         * We'll have to walk the import descriptors to figure out their number.
     890         * First, make sure we've got mapped bits and resolve any base address aliases.
     891         */
     892        if (kldrModPEBitsAndBaseAddress(pModPE, &pvBits, NULL))
     893            return -1;
     894        pModPE->cImportModules = 0;
     895        if (    pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size
     896            &&  pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
     897        {
     898            const IMAGE_IMPORT_DESCRIPTOR  *pImpDesc;
     899
     900            pImpDesc = KLDRMODPE_RVA2TYPE(pvBits,
     901                                          pModPE->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
     902                                          const IMAGE_IMPORT_DESCRIPTOR *);
     903            while (pImpDesc->Name && pImpDesc->FirstThunk)
     904            {
     905                pModPE->cImportModules = 0;
     906                pImpDesc++;
     907            }
     908        }
     909    }
     910    return pModPE->cImportModules;
     911}
     912
     913
    838914/** @copydoc kLdrModGetStackInfo */
    839 int (* pfnGetStackInfo)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo);
     915static int kldrModPEGetStackInfo(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRSTACKINFO pStackInfo)
     916{
     917    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     918
     919    pStackInfo->Address = NIL_KLDRADDR;
     920    pStackInfo->LinkAddress = NIL_KLDRADDR;
     921    pStackInfo->cbStack = pStackInfo->cbStackThread = pModPE->Hdrs.OptionalHeader.SizeOfStackReserve;
     922
     923    return 0;
     924}
     925
     926
    840927/** @copydoc kLdrModQueryMainEntrypoint */
    841 int (* pfnQueryMainEntrypoint)(PKLDRMOD pMod, void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress);
     928static int kldrModPEQueryMainEntrypoint(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress, PKLDRADDR pMainEPAddress)
     929{
     930    PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData;
     931    int rc;
     932
     933    rc = kldrModPEBitsAndBaseAddress(pModPE, NULL, &BaseAddress);
     934    if (rc)
     935        return rc;
     936
     937    *pMainEPAddress = pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint
     938        ? BaseAddress + pModPE->Hdrs.OptionalHeader.AddressOfEntryPoint
     939        : NIL_KLDRADDR;
     940    return 0;
     941}
     942
     943
    842944/** @copydoc kLdrModEnumDbgInfo */
    843 int (* pfnEnumDbgInfo)(PKLDRMOD pMod, void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     945int (* pfnEnumDbgInfo)(PKLDRMOD pMod, const void *pvBits, PFNKLDRENUMDBG pfnCallback, void *pvUser);
     946
    844947/** @copydoc kLdrModHasDbgInfo */
    845 int (* pfnHasDbgInfo)(PKLDRMOD pMod, void *pvBits);
     948int (* pfnHasDbgInfo)(PKLDRMOD pMod, const void *pvBits);
    846949/** @copydoc kLdrModMap */
    847950int (* pfnMap)(PKLDRMOD pMod);
Note: See TracChangeset for help on using the changeset viewer.