Changeset 2954


Ignore:
Timestamp:
Feb 7, 2007, 5:42:32 AM (19 years ago)
Author:
bird
Message:

implemented kldrModMachOPreParseLoadCommands

Location:
trunk/kLdr
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/Makefile.kmk

    r2952 r2954  
    3535#
    3636TEMPLATE_TST = Testcase template
    37 ifneq ($(filter win nt win32 win64,$(BUILD_TARGET)),)
     37ifneq ($(filter win,$(BUILD_TARGET)),)
    3838 TEMPLATE_TST_TOOL = VCC70
    3939 TEMPLATE_TST_CFLAGS = -W3 -Zi -Zl -MD
     
    4141 TEMPLATE_TST_ASFLAGS = -f win
    4242 TEMPLATE_TST_DEFS = __WIN__
    43  TEMPLATE_SDKS.x86 = WIN32SDK W2K3DDKX86
    44  TEMPLATE_SDKS.amd64 = WIN64SDK W2K3DDKAMD64
     43 TEMPLATE_TST_SDKS = WINPSDK W2K3DDK
    4544
    4645## @todo this is a kBuild bug? $$(PATH_TOOL_VCC70_LIB)
     
    112111        kLdrMod.c \
    113112        kLdrModLX.c \
    114         kLdrModPE.c \
    115113        kLdrModMachO.c \
    116         kLdrModNative.c
     114        kLdrModNative.c \
     115        kLdrModPE.c
    117116kLdr_SOURCES.os2 = \
    118117        kLdr-os2.def \
  • trunk/kLdr/kLdr.h

    r2952 r2954  
    11171117/** The mach-o image format isn't supported by this kLdr build. */
    11181118#define KLDR_ERR_MACHO_NOT_SUPPORTED    (KLDR_ERR_BASE + 7)
    1119 /** The mach-o image format isn't supported by this kLdr build. */
    1120 #define KLDR_ERR_AOUT_NOT_SUPPORTED     (KLDR_ERR_BASE + 8)
     1119/** The FAT image format isn't supported by this kLdr build or
     1120 * a direct open was attempt without going thru the FAT file provider.
     1121 * FAT images are also known as Universal Binaries. */
     1122#define KLDR_ERR_FAT_NOT_SUPPORTED      (KLDR_ERR_BASE + 8)
     1123/** The a.out image format isn't supported by this kLdr build. */
     1124#define KLDR_ERR_AOUT_NOT_SUPPORTED     (KLDR_ERR_BASE + 9)
    11211125
    11221126/** Invalid parameter to a kLdr API. */
     
    12371241 * @{ */
    12381242#define KLDR_ERR_MACHO_BASE                                 (KLDR_ERR_LX_BASE + 12)
    1239 /** Only native endian MACH-O files are supported. */
     1243/** Only native endian Mach-O files are supported. */
    12401244#define KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED           (KLDR_ERR_MACHO_BASE + 0)
    1241 /** 64-bit MACH-O files aren't supported yet. */
     1245/** 64-bit Mach-O files aren't supported yet. */
    12421246#define KLDR_ERR_MACHO_64BIT_NOT_SUPPORTED                  (KLDR_ERR_MACHO_BASE + 1)
    1243 /** The MACH-O header is bad or contains new and unsupported features. */
     1247/** The Mach-O header is bad or contains new and unsupported features. */
    12441248#define KLDR_ERR_MACHO_BAD_HEADER                           (KLDR_ERR_MACHO_BASE + 2)
    12451249/** The file type isn't supported. */
     
    12471251/** The machine (cputype / cpusubtype combination) isn't supported. */
    12481252#define KLDR_ERR_MACHO_UNSUPPORTED_MACHINE                  (KLDR_ERR_MACHO_BASE + 4)
     1253/** Bad load command(s). */
     1254#define KLDR_ERR_MACHO_BAD_LOAD_COMMAND                     (KLDR_ERR_MACHO_BASE + 5)
     1255/** Encountered an unknown load command.*/
     1256#define KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND                 (KLDR_ERR_MACHO_BASE + 6)
     1257/** Encountered a load command that's not implemented.*/
     1258#define KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND             (KLDR_ERR_MACHO_BASE + 7)
     1259/** Bad section. */
     1260#define KLDR_ERR_MACHO_BAD_SECTION                          (KLDR_ERR_MACHO_BASE + 8)
     1261/** Encountered a section type that's not implemented.*/
     1262#define KLDR_ERR_MACHO_UNSUPPORTED_SECTION                  (KLDR_ERR_MACHO_BASE + 9)
     1263/** Encountered a section type that's not known to the loader. (probably invalid) */
     1264#define KLDR_ERR_MACHO_UNKNOWN_SECTION                      (KLDR_ERR_MACHO_BASE + 10)
     1265/** The sections aren't ordered by segment as expected by the loader. */
     1266#define KLDR_ERR_MACHO_BAD_SECTION_ORDER                    (KLDR_ERR_MACHO_BASE + 11)
    12491267/** @} */
    12501268
    12511269/** End of the valid kLdr status codes. */
    1252 #define KLDR_ERR_END                                        (KLDR_ERR_LX_BASE + 12)
     1270#define KLDR_ERR_END                                        (KLDR_ERR_MACHO_BASE + 12)
    12531271
    12541272/** @} */
  • trunk/kLdr/kLdrHlp.h

    r2944 r2954  
    4646#define KLDR_ELEMENTS(a)            ( sizeof(a) / sizeof((a)[0]) )
    4747
    48 /** @def KLDRHLP_LE2H_U16
    49  * Unsigned 16-bit little-endian to host translation. */
    50 /** @def KLDRHLP_LE2H_U32
    51  * Unsigned 32-bit little-endian to host translation. */
    52 #if 1
    53 # define KLDRHLP_LE2H_U16(u16)  ((uint16_t)(u16))
    54 # define KLDRHLP_LE2H_U32(u32)  ((uint32_t)(u32))
    55 #else
    56 # define KLDRHLP_LE2H_U16(u16)  ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
    57 # define KLDRHLP_LE2H_U32(u32)  (   ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
     48
     49/** @name Endian Conversion
     50 * @{ */
     51
     52/** @def KLDRHLP_E2E_U16
     53 * Convert the endian of an unsigned 16-bit value. */
     54# define KLDRHLP_E2E_U16(u16)   ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
     55/** @def KLDRHLP_E2E_U32
     56 * Convert the endian of an unsigned 32-bit value. */
     57# define KLDRHLP_E2E_U32(u32)   (   ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
    5858                                  | ( ((u32) & UINT32_C(0x00ff0000)) >>  8 ) \
    5959                                  | ( ((u32) & UINT32_C(0x0000ff00)) <<  8 ) \
    6060                                  | ( ((u32) & UINT32_C(0x000000ff)) << 24 ) \
    6161                                )
    62 #endif
     62/** @def KLDRHLP_E2E_U64
     63 * Convert the endian of an unsigned 64-bit value. */
     64# define KLDRHLP_E2E_U64(u64)   (   ( ((u64) & UINT64_C(0xff00000000000000)) >> 56 ) \
     65                                  | ( ((u64) & UINT64_C(0x00ff000000000000)) >> 40 ) \
     66                                  | ( ((u64) & UINT64_C(0x0000ff0000000000)) >> 24 ) \
     67                                  | ( ((u64) & UINT64_C(0x000000ff00000000)) >>  8 ) \
     68                                  | ( ((u64) & UINT64_C(0x00000000ff000000)) <<  8 ) \
     69                                  | ( ((u64) & UINT64_C(0x0000000000ff0000)) << 24 ) \
     70                                  | ( ((u64) & UINT64_C(0x000000000000ff00)) << 40 ) \
     71                                  | ( ((u64) & UINT64_C(0x00000000000000ff)) << 56 ) \
     72                                )
     73
     74/** @def KLDRHLP_LE2H_U16
     75 * Unsigned 16-bit little-endian to host endian. */
     76/** @def KLDRHLP_LE2H_U32
     77 * Unsigned 32-bit little-endian to host endian. */
     78/** @def KLDRHLP_LE2H_U64
     79 * Unsigned 64-bit little-endian to host endian. */
     80/** @def KLDRHLP_BE2H_U16
     81 * Unsigned 16-bit big-endian to host endian. */
     82/** @def KLDRHLP_BE2H_U32
     83 * Unsigned 32-bit big-endian to host endian. */
     84/** @def KLDRHLP_BE2H_U64
     85 * Unsigned 64-bit big-endian to host endian. */
     86#if 1
     87# define KLDRHLP_LE2H_U16(u16)  ((uint16_t)(u16))
     88# define KLDRHLP_LE2H_U32(u32)  ((uint32_t)(u32))
     89# define KLDRHLP_LE2H_U64(u64)  ((uint32_t)(u32))
     90# define KLDRHLP_BE2H_U16(u16)  KLDRHLP_E2E_U16(u16)
     91# define KLDRHLP_BE2H_U32(u32)  KLDRHLP_E2E_U32(u32)
     92# define KLDRHLP_BE2H_U64(u64)  KLDRHLP_E2E_U64(u64)
     93#else
     94# define KLDRHLP_LE2H_U16(u16)  KLDRHLP_E2E_U16(u16)
     95# define KLDRHLP_LE2H_U32(u32)  KLDRHLP_E2E_U32(u32)
     96# define KLDRHLP_LE2H_U32(u64)  KLDRHLP_E2E_U64(u64)
     97# define KLDRHLP_BE2H_U16(u16)  ((uint16_t)(u16))
     98# define KLDRHLP_BE2H_U32(u32)  ((uint32_t)(u32))
     99# define KLDRHLP_BE2H_U64(u64)  ((uint32_t)(u32))
     100#endif
     101
     102/** @} */
     103
    63104
    64105/*
     
    174215#  ifdef __GNUC__
    175216#   define kldrHlpBreakpoint() do { __asm__ __volatile__ ("int3\n\tnop"); } while (0)
    176 #  endif 
     217#  endif
    177218#  ifdef _MSC_VER
    178219#   define kldrHlpBreakpoint() __debugbreak()
    179 #  endif 
    180 
    181 #endif 
     220#  endif
     221
     222#endif
    182223
    183224#if (!defined(kLdrHlpMemChr) && !defined(kLdrHlpStrChr_needed))\
     
    196237#ifdef __cplusplus
    197238extern "C" {
    198 #endif 
     239#endif
    199240
    200241int     kLdrHlpMemIComp(const void *pv1, const void *pv2, size_t cb);
     
    230271#ifdef __cplusplus
    231272}
    232 #endif 
     273#endif
    233274
    234275
  • trunk/kLdr/kLdrInternal.h

    r2944 r2954  
    5050 * @{ */
    5151/** ELF signature ("\x7fELF"). */
    52 #define IMAGE_ELF_SIGNATURE KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24))
     52#define IMAGE_ELF_SIGNATURE         KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24))
    5353/** PE signature ("PE\0\0"). */
    54 #define IMAGE_NT_SIGNATURE  KLDRHLP_LE2H_U32('P' | ('E' << 8))
     54#define IMAGE_NT_SIGNATURE          KLDRHLP_LE2H_U32('P' | ('E' << 8))
    5555/** LX signature ("LX") */
    56 #define IMAGE_LX_SIGNATURE  KLDRHLP_LE2H_U16('L' | ('X' << 8))
     56#define IMAGE_LX_SIGNATURE          KLDRHLP_LE2H_U16('L' | ('X' << 8))
    5757/** LE signature ("LE") */
    58 #define IMAGE_LE_SIGNATURE  KLDRHLP_LE2H_U16('L' | ('E' << 8))
     58#define IMAGE_LE_SIGNATURE          KLDRHLP_LE2H_U16('L' | ('E' << 8))
    5959/** NE signature ("NE") */
    60 #define IMAGE_NE_SIGNATURE  KLDRHLP_LE2H_U16('N' | ('E' << 8))
     60#define IMAGE_NE_SIGNATURE          KLDRHLP_LE2H_U16('N' | ('E' << 8))
    6161/** MZ signature ("MZ"). */
    62 #define IMAGE_DOS_SIGNATURE KLDRHLP_LE2H_U16('M' | ('Z' << 8))
     62#define IMAGE_DOS_SIGNATURE         KLDRHLP_LE2H_U16('M' | ('Z' << 8))
     63/** The FAT signature (universal binaries). */
     64#define IMAGE_FAT_SIGNATURE         UINT32_C(0xcafebabe)
     65/** The FAT signature (universal binaries), other endian. */
     66#define IMAGE_FAT_SIGNATURE_OE      UINT32_C(0xbebafeca)
     67/** The 32-bit Mach-O signature. */
     68#define IMAGE_MACHO32_SIGNATURE     UINT32_C(0xfeedface)
     69/** The 32-bit Mach-O signature, other endian. */
     70#define IMAGE_MACHO32_SIGNATURE_OE  UINT32_C(0xcefaedfe)
     71/** The 64-bit Mach-O signature. */
     72#define IMAGE_MACHO64_SIGNATURE     UINT32_C(0xfeedfacf)
     73/** The 64-bit Mach-O signature, other endian. */
     74#define IMAGE_MACHO64_SIGNATURE_OE  UINT32_C(0xfefaedfe)
    6375/** @} */
    6476
     
    424436/** @name Module interpreter method tables
    425437 * @{ */
     438extern KLDRMODOPS       g_kLdrModLXOps;
     439extern KLDRMODOPS       g_kLdrModMachOOps;
     440extern KLDRMODOPS       g_kLdrModNativeOps;
    426441extern KLDRMODOPS       g_kLdrModPEOps;
    427 extern KLDRMODOPS       g_kLdrModLXOps;
    428 extern KLDRMODOPS       g_kLdrModNativeOps;
    429442/** @} */
    430443
  • trunk/kLdr/kLdrMod.c

    r2946 r2954  
    3838# include "kLdrModELF32.h"
    3939# include "kLdrModELF64.h"
     40# include "kLdrModMachO.h"
    4041#endif
    4142
     
    184185    else if (u.u32 == IMAGE_NT_SIGNATURE)
    185186        rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
     187    else if (   u.u32 == IMAGE_MACHO32_SIGNATURE
     188             || u.u32 == IMAGE_MACHO32_SIGNATURE_OE
     189             || u.u32 == IMAGE_MACHO64_SIGNATURE
     190             || u.u32 == IMAGE_MACHO64_SIGNATURE_OE)
     191        rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, offHdr, ppMod);
    186192    else if (u.u32 == IMAGE_ELF_SIGNATURE)
    187193        rc = KLDR_ERR_ELF_NOT_SUPPORTED;
     194    else if (   u.u32 == IMAGE_FAT_SIGNATURE
     195             || u.u32 == IMAGE_FAT_SIGNATURE_OE)
     196        rc = KLDR_ERR_FAT_NOT_SUPPORTED;
    188197    else
    189198        rc = KLDR_ERR_UNKNOWN_FORMAT;
  • trunk/kLdr/kLdrModMachO.c

    r2952 r2954  
    3333#include "kLdrInternal.h"
    3434#include "kLdrModMachO.h"
     35
     36/* quick hack for now. */
     37typedef struct nlist
     38{
     39    uint32_t    n_strx;
     40    uint8_t     n_type;
     41    int8_t      n_other;
     42    int16_t     n_desc;
     43    uint32_t    n_value;
     44} nlist_t;
    3545
    3646
     
    7585*******************************************************************************/
    7686/**
    77  * Instance data for the MACH-O MH_OBJECT module interpreter.
     87 * Instance data for the Mach-O MH_OBJECT module interpreter.
    7888 * @todo interpret the other MH_* formats.
    7989 */
     
    121131
    122132static int  kldrModMachODoCreate(PKLDRRDR pRdr, PKLDRMODMACHO *ppMod);
    123 static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr,
     133static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr,
    124134                                             uint32_t *pcSegments, uint32_t *pcbStringPool);
    125135static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool);
     
    243253                     ? sizeof(mach_header_32_t) : sizeof(mach_header_64_t));
    244254    if (!rc)
    245         rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, &cSegments, &cbStringPool);
     255        rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, &cSegments, &cbStringPool);
    246256    if (rc)
    247257    {
     
    375385 * @param   pbLoadCommands  The load commands to parse.
    376386 * @param   pHdr            The header.
     387 * @param   pRdr            The file reader.
    377388 * @param   pcSegments      Where to store the segment count.
    378389 * @param   pcbStringPool   Where to store the string pool size.
    379390 */
    380 static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr,
     391static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr,
    381392                                             uint32_t *pcSegments, uint32_t *pcbStringPool)
    382393{
     394    union
     395    {
     396        uint8_t              *pb;
     397        load_command_t       *pLoadCmd;
     398        segment_command_32_t *pSeg32;
     399        segment_command_64_t *pSeg64;
     400        thread_command_t     *pThread;
     401        symtab_command_t     *pSymTab;
     402        uuid_command_t       *pUuid;
     403    } u;
     404    const uint64_t cbFile = kLdrRdrSize(pRdr);
     405    uint32_t cSegments = 0;
     406    uint32_t cbStringPool = 0;
     407    uint32_t cLeft = pHdr->ncmds;
     408    uint32_t cbLeft = pHdr->sizeofcmds;
     409    uint8_t *pb = pbLoadCommands;
     410    int      fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE
     411                           || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE;
     412
    383413    *pcSegments = 0;
    384414    *pcbStringPool = 0;
     415
     416    while (cLeft-- > 0)
     417    {
     418        u.pb = pb;
     419
     420        /*
     421         * Convert and validate command header.
     422         */
     423        if (cbLeft < sizeof(load_command_t))
     424            return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     425        if (fConvertEndian)
     426        {
     427            u.pLoadCmd->cmd = KLDRHLP_E2E_U32(u.pLoadCmd->cmd);
     428            u.pLoadCmd->cmdsize = KLDRHLP_E2E_U32(u.pLoadCmd->cmdsize);
     429        }
     430        if (u.pLoadCmd->cmdsize > cbLeft)
     431            return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     432        cbLeft -= u.pLoadCmd->cmdsize;
     433        pb += u.pLoadCmd->cmdsize;
     434
     435        /*
     436         * Convert endian if needed, parse and validate the command.
     437         */
     438        switch (u.pLoadCmd->cmd)
     439        {
     440            case LC_SEGMENT_32:
     441            {
     442                section_32_t *pSect;
     443                section_32_t *pFirstSect;
     444                uint32_t cSectionsLeft;
     445
     446                /* convert and verify*/
     447                if (u.pLoadCmd->cmdsize < sizeof(segment_command_32_t))
     448                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     449                if (fConvertEndian)
     450                {
     451                    u.pSeg32->vmaddr   = KLDRHLP_E2E_U32(u.pSeg32->vmaddr);
     452                    u.pSeg32->vmsize   = KLDRHLP_E2E_U32(u.pSeg32->vmsize);
     453                    u.pSeg32->fileoff  = KLDRHLP_E2E_U32(u.pSeg32->fileoff);
     454                    u.pSeg32->filesize = KLDRHLP_E2E_U32(u.pSeg32->filesize);
     455                    u.pSeg32->maxprot  = KLDRHLP_E2E_U32(u.pSeg32->maxprot);
     456                    u.pSeg32->initprot = KLDRHLP_E2E_U32(u.pSeg32->initprot);
     457                    u.pSeg32->nsects   = KLDRHLP_E2E_U32(u.pSeg32->nsects);
     458                    u.pSeg32->flags    = KLDRHLP_E2E_U32(u.pSeg32->flags);
     459                }
     460
     461                if (    u.pSeg32->filesize
     462                    &&  (   u.pSeg32->fileoff > cbFile
     463                         || (uint64_t)u.pSeg32->fileoff + u.pSeg32->filesize > cbFile))
     464                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     465                if (!u.pSeg32->filesize && u.pSeg32->fileoff)
     466                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     467                if (u.pSeg32->vmsize < u.pSeg32->filesize)
     468                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     469                if ((u.pSeg32->maxprot & u.pSeg32->initprot) != u.pSeg32->initprot)
     470                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     471                if (u.pSeg32->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1))
     472                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     473                if (u.pSeg32->nsects * sizeof(section_32_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_32_t))
     474                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     475
     476                /*
     477                 * convert, validate and parse the sections.
     478                 */
     479                cSectionsLeft = u.pSeg32->nsects;
     480                pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1);
     481                while (cSectionsLeft-- > 0)
     482                {
     483                    int fFileBits;
     484
     485                    if (fConvertEndian)
     486                    {
     487                        pSect->addr      = KLDRHLP_E2E_U32(pSect->addr);
     488                        pSect->size      = KLDRHLP_E2E_U32(pSect->size);
     489                        pSect->offset    = KLDRHLP_E2E_U32(pSect->offset);
     490                        pSect->align     = KLDRHLP_E2E_U32(pSect->align);
     491                        pSect->reloff    = KLDRHLP_E2E_U32(pSect->reloff);
     492                        pSect->nreloc    = KLDRHLP_E2E_U32(pSect->nreloc);
     493                        pSect->flags     = KLDRHLP_E2E_U32(pSect->flags);
     494                        pSect->reserved1 = KLDRHLP_E2E_U32(pSect->reserved1);
     495                        pSect->reserved2 = KLDRHLP_E2E_U32(pSect->reserved2);
     496                    }
     497
     498                    /* validate */
     499                    switch (pSect->flags & SECTION_TYPE)
     500                    {
     501                        case S_ZEROFILL:
     502                            if (pSect->reserved1 || pSect->reserved2)
     503                                return KLDR_ERR_MACHO_BAD_SECTION;
     504                            fFileBits = 0;
     505                            break;
     506                        case S_REGULAR:
     507                        case S_CSTRING_LITERALS:
     508                            if (pSect->reserved1 || pSect->reserved2)
     509                                return KLDR_ERR_MACHO_BAD_SECTION;
     510                            fFileBits = 1;
     511                            break;
     512
     513                        case S_LITERAL_POINTERS:
     514                        case S_INTERPOSING:
     515                        case S_GB_ZEROFILL:
     516                        case S_NON_LAZY_SYMBOL_POINTERS:
     517                        case S_LAZY_SYMBOL_POINTERS:
     518                        case S_4BYTE_LITERALS:
     519                        case S_8BYTE_LITERALS:
     520                        case S_16BYTE_LITERALS:
     521                        case S_SYMBOL_STUBS:
     522                        case S_COALESCED:
     523                        case S_MOD_INIT_FUNC_POINTERS:
     524                        case S_MOD_TERM_FUNC_POINTERS:
     525                            return KLDR_ERR_MACHO_UNSUPPORTED_SECTION;
     526
     527                        default:
     528                            return KLDR_ERR_MACHO_UNKNOWN_SECTION;
     529                    }
     530                    if (pSect->flags & ~(  S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS
     531                                         | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE
     532                                         | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC
     533                                         | S_ATTR_LOC_RELOC | SECTION_TYPE))
     534                        return KLDR_ERR_MACHO_BAD_SECTION;
     535                    if (!pSect->size)
     536                        return KLDR_ERR_MACHO_BAD_SECTION;
     537                    if (    pSect->addr - u.pSeg32->vmaddr > u.pSeg32->vmsize
     538                        ||  pSect->addr - u.pSeg32->vmaddr + pSect->size > u.pSeg32->vmsize)
     539                        return KLDR_ERR_MACHO_BAD_SECTION;
     540                    if (    pSect->align >= 31
     541                        ||  (((1 << pSect->align) - 1) & pSect->addr)
     542                        ||  (((1 << pSect->align) - 1) & u.pSeg32->vmaddr))
     543                        return KLDR_ERR_MACHO_BAD_SECTION;
     544                    if (    fFileBits
     545                        &&  (   pSect->offset > cbFile
     546                             || (uint64_t)pSect->offset + pSect->size > cbFile))
     547                        return KLDR_ERR_MACHO_BAD_SECTION;
     548                    if (!fFileBits && pSect->offset)
     549                        return KLDR_ERR_MACHO_BAD_SECTION;
     550                    if (!pSect->nreloc && pSect->reloff)
     551                        return KLDR_ERR_MACHO_BAD_SECTION;
     552                    if (    pSect->nreloc
     553                        &&  (   pSect->reloff > cbFile
     554                             || (uint64_t)pSect->reloff + (off_t)pSect->nreloc * sizeof(nlist_t)) > cbFile)
     555                        return KLDR_ERR_MACHO_BAD_SECTION;
     556
     557
     558                    /* count segments and strings */
     559                    switch (pHdr->filetype)
     560                    {
     561                        case MH_OBJECT:
     562                        {
     563                            /* Don't load debug symbols. (test this) */
     564                            if (pSect->flags & S_ATTR_DEBUG)
     565                                break;
     566
     567                            /* a new segment? */
     568                            if (    pSect == pFirstSect
     569                                ||  kLdrHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname)))
     570                            {
     571                                /* verify that the linker/assembler has ordered sections correctly. */
     572                                section_32_t *pCur = (pSect - 2);
     573                                while ((uintptr_t)pCur >= (uintptr_t)pFirstSect)
     574                                {
     575                                    if (!kLdrHlpStrNComp(pCur->segname, pSect->segname, sizeof(pSect->segname)))
     576                                        return KLDR_ERR_MACHO_BAD_SECTION_ORDER;
     577                                    pCur--;
     578                                }
     579
     580                                /* ok. count it and the string. */
     581                                cSegments++;
     582                                cbStringPool += kLdrHlpStrLen(pSect->segname) + 1;
     583                            }
     584                            break;
     585                        }
     586
     587                        default:
     588                            return KLDR_ERR_INVALID_PARAMETER;
     589                    }
     590
     591                    /* next */
     592                    pSect++;
     593                }
     594                break;
     595            }
     596
     597            case LC_SEGMENT_64:
     598                /* copy 32-bit code */
     599                break;
     600
     601            case LC_SYMTAB:
     602                if (fConvertEndian)
     603                {
     604                    u.pSymTab->symoff  = KLDRHLP_E2E_U32(u.pSymTab->symoff);
     605                    u.pSymTab->nsyms   = KLDRHLP_E2E_U32(u.pSymTab->nsyms);
     606                    u.pSymTab->stroff  = KLDRHLP_E2E_U32(u.pSymTab->stroff);
     607                    u.pSymTab->strsize = KLDRHLP_E2E_U32(u.pSymTab->strsize);
     608                }
     609
     610                /* verify */
     611                if (    u.pSymTab->symoff >= cbFile
     612                    ||  (uint64_t)u.pSymTab->symoff + u.pSymTab->nsyms * sizeof(nlist_t) > kLdrRdrSize(pRdr))
     613                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     614                if (    u.pSymTab->stroff >= cbFile
     615                    ||  (uint64_t)u.pSymTab->stroff + u.pSymTab->strsize > cbFile)
     616                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     617                break;
     618
     619            case LC_THREAD:
     620            case LC_UNIXTHREAD:
     621            {
     622                uint32_t *pu32 = (uint32_t *)(u.pb + sizeof(load_command_t));
     623                uint32_t cItemsLeft = (u.pThread->cmdsize - sizeof(load_command_t)) / sizeof(uint32_t);
     624                while (cItemsLeft)
     625                {
     626                    /* convert & verify header items ([0] == flavor, [1] == uint32_t count). */
     627                    if (cItemsLeft < 2)
     628                        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     629                    if (fConvertEndian)
     630                    {
     631                        pu32[0] = KLDRHLP_E2E_U32(pu32[0]);
     632                        pu32[1] = KLDRHLP_E2E_U32(pu32[1]);
     633                    }
     634                    if (pu32[1] + 2 > cItemsLeft)
     635                        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     636
     637                    /* convert & verify according to flavor. */
     638                    switch (pu32[0])
     639                    {
     640                        /** @todo */
     641                        default:
     642                            break;
     643                    }
     644
     645                    /* next */
     646                    cItemsLeft -= pu32[1] + 2;
     647                    pu32 += pu32[1] + 2;
     648                }
     649                break;
     650            }
     651
     652            case LC_UUID:
     653                if (u.pUuid->cmdsize != sizeof(uuid_command_t))
     654                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     655                /** @todo Check anything here need converting? */
     656                break;
     657
     658            case LC_LOADFVMLIB:
     659            case LC_IDFVMLIB:
     660            case LC_IDENT:
     661            case LC_FVMFILE:
     662            case LC_PREPAGE:
     663            case LC_DYSYMTAB:
     664            case LC_LOAD_DYLIB:
     665            case LC_ID_DYLIB:
     666            case LC_LOAD_DYLINKER:
     667            case LC_ID_DYLINKER:
     668            case LC_PREBOUND_DYLIB:
     669            case LC_ROUTINES:
     670            case LC_ROUTINES_64:
     671            case LC_SUB_FRAMEWORK:
     672            case LC_SUB_UMBRELLA:
     673            case LC_SUB_CLIENT:
     674            case LC_SUB_LIBRARY:
     675            case LC_TWOLEVEL_HINTS:
     676            case LC_PREBIND_CKSUM:
     677            case LC_LOAD_WEAK_DYLIB:
     678            case LC_SYMSEG:
     679                return KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND;
     680
     681            default:
     682                return KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND;
     683        }
     684    }
     685
     686    /* be strict (for now). */
     687    if (cbLeft)
     688        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     689
     690    *pcSegments = cSegments;
     691    *pcbStringPool = cLeft;
     692
    385693    return 0;
    386694}
     
    17232031/** @copydoc kLdrModRelocateBits */
    17242032static int kldrModMachORelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
    1725                                  PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
     2033                                    PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
    17262034{
    17272035    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
     
    17402048
    17412049/**
    1742  * The PE module interpreter method table.
     2050 * The Mach-O module interpreter method table.
    17432051 */
    1744 KLDRMODOPS g_kLdrModPEOps =
    1745 {
    1746     "PE",
     2052KLDRMODOPS g_kLdrModMachOOps =
     2053{
     2054    "Mach-O",
    17472055    NULL,
    17482056    kldrModMachOCreate,
  • trunk/kLdr/kLdrModMachO.h

    r2952 r2954  
    283283{
    284284    uint32_t        cmd;            /**< The load command id. */
    285     uint32_t        cmdsize;        /**< The size of the command (including this header?). */
     285    uint32_t        cmdsize;        /**< The size of the command (including this header). */
    286286} load_command_t;
    287287
     
    308308#define LC_ID_DYLIB         UINT32_C(0x0d)  /**< Dynamically linked share library ident. See dylib_command. */
    309309#define LC_LOAD_DYLINKER    UINT32_C(0x0e)  /**< Load a dynamical link editor. See dylinker_command. */
    310 #define LC_ID_DYLINKER      UINt32_C(0x0f)  /**< Dynamic link editor ident. See dylinker_command. */
     310#define LC_ID_DYLINKER      UINT32_C(0x0f)  /**< Dynamic link editor ident. See dylinker_command. */
    311311#define LC_PREBOUND_DYLIB   UINT32_C(0x10)  /**< Prebound modules for dynamically linking of a shared lib. See prebound_dylib_command. */
    312312#define LC_ROUTINES         UINT32_C(0x11)  /**< Image routines. See routines_command_32. */
Note: See TracChangeset for help on using the changeset viewer.