VirtualBox

Changeset 58 in kStuff


Ignore:
Timestamp:
Oct 12, 2013 8:18:21 PM (11 years ago)
Author:
bird
Message:

Mach-O: Carve segments from the mach-o segments instead of the sections inside them. This works better for non-object files.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/k/kErrors.h

    r54 r58  
    208208/** The image has no UUID. */
    209209#define KLDR_ERR_NO_IMAGE_UUID                          (KLDR_ERR_BASE + 38)
     210/** Duplicate segment name. */
     211#define KLDR_ERR_DUPLICATE_SEGMENT_NAME                 (KLDR_ERR_BASE + 39)
    210212/** @} */
    211213
     
    214216 */
    215217/** The base of the kLdrModPE specific status codes. */
    216 #define KLDR_ERR_PE_BASE                                (KLDR_ERR_BASE + 39)
     218#define KLDR_ERR_PE_BASE                                (KLDR_ERR_BASE + 40)
    217219/** The machine isn't supported by the interpreter. */
    218220#define KLDR_ERR_PE_UNSUPPORTED_MACHINE                 (KLDR_ERR_PE_BASE + 0)
     
    303305/** Unsupported fixup type. */
    304306#define KLDR_ERR_MACHO_UNSUPPORTED_FIXUP_TYPE           (KLDR_ERR_MACHO_BASE + 16)
     307/** Both debug and non-debug sections in segment. */
     308#define KLDR_ERR_MACHO_MIXED_DEBUG_SECTION_FLAGS        (KLDR_ERR_MACHO_BASE + 17)
     309/** The segment bits are non-contiguous in the file. */
     310#define KLDR_ERR_MACHO_NON_CONT_SEG_BITS                (KLDR_ERR_MACHO_BASE + 18)
    305311/** @} */
    306312
     
    309315 */
    310316/** The base of the kCpu specific status codes. */
    311 #define KCPU_ERR_BASE                                   (KLDR_ERR_MACHO_BASE + 18)
     317#define KCPU_ERR_BASE                                   (KLDR_ERR_MACHO_BASE + 19)
    312318/** The specified ARCH+CPU pairs aren't compatible. */
    313319#define KCPU_ERR_ARCH_CPU_NOT_COMPATIBLE                (KCPU_ERR_BASE + 0)
  • trunk/include/k/kLdr.h

    r54 r58  
    366366
    367367
     368/** @name KLDRMOD::fFlags
     369 * @{ */
     370/** The link address doesn't form a contiguous image, from the first to the
     371 * last segment.   */
     372#define KLDRMOD_FLAGS_NON_CONTIGUOUS_LINK_ADDRS         K_BIT32(0)
     373/** @} */
     374
    368375/** Pointer to a module interpreter method table. */
    369376typedef struct KLDRMODOPS *PKLDRMODOPS;
     
    390397    /** The endian used by the module. */
    391398    KLDRENDIAN          enmEndian;
     399    /** Module falgs. */
     400    KU32                fFlags;
    392401    /** The filename length (bytes). */
    393402    KU32                cchFilename;
  • trunk/kLdr/kLdrModLX.c

    r54 r58  
    302302    pMod->pszName = NULL; /* finalized further down */
    303303    pMod->cchName = 0;
     304    pMod->fFlags = 0;
    304305    switch (Hdr.e32_cpu)
    305306    {
  • trunk/kLdr/kLdrModMachO.c

    r57 r58  
    6363#endif
    6464
     65/** @def KLDRMODMACHO_CHECK_RETURN
     66 * Checks that an expression is true and return if it isn't.
     67 * This is a debug aid.
     68 */
     69#ifdef KLDRMODMACHO_STRICT2
     70# define KLDRMODMACHO_FAILED_RETURN(rc)  kHlpAssertFailedReturn(rc)
     71#else
     72# define KLDRMODMACHO_FAILED_RETURN(rc)  return (rc)
     73#endif
     74
    6575
    6676/*******************************************************************************
     
    399409    pMod->pszName = kHlpGetFilename(pMod->pszFilename);
    400410    pMod->cchName = cchFilename - (pMod->pszName - pMod->pszFilename);
     411    pMod->fFlags = 0;
    401412    switch (s.Hdr32.cputype)
    402413    {
     
    535546    } u;
    536547    const KU64 cbFile = kRdrSize(pRdr) - offImage;
    537     const char *pchCurSegName = NULL;
    538548    KU32 cSegments = 0;
    539549    KU32 cSections = 0;
     
    560570         * Convert and validate command header.
    561571         */
    562         if (cbLeft < sizeof(load_command_t))
    563             return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     572        KLDRMODMACHO_CHECK_RETURN(cbLeft >= sizeof(load_command_t), KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    564573        if (fConvertEndian)
    565574        {
     
    567576            u.pLoadCmd->cmdsize = K_E2E_U32(u.pLoadCmd->cmdsize);
    568577        }
    569         if (u.pLoadCmd->cmdsize > cbLeft)
    570             return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     578        KLDRMODMACHO_CHECK_RETURN(u.pLoadCmd->cmdsize <= cbLeft, KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    571579        cbLeft -= u.pLoadCmd->cmdsize;
    572580        pb += u.pLoadCmd->cmdsize;
     
    579587            case LC_SEGMENT_32:
    580588            {
    581                 section_32_t *pSect;
    582                 section_32_t *pFirstSect;
    583                 KU32 cSectionsLeft;
    584 
    585                 /* convert and verify*/
    586                 if (u.pLoadCmd->cmdsize < sizeof(segment_command_32_t))
    587                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    588                 if (    pHdr->magic != IMAGE_MACHO32_SIGNATURE_OE
    589                     &&  pHdr->magic != IMAGE_MACHO32_SIGNATURE)
    590                     return KLDR_ERR_MACHO_BIT_MIX;
     589                segment_command_32_t *pSrcSeg = (segment_command_32_t *)u.pLoadCmd;
     590                section_32_t   *pFirstSect    = (section_32_t *)(pSrcSeg + 1);
     591                section_32_t   *pSect         = pFirstSect;
     592                KU32            cSectionsLeft = pSrcSeg->nsects;
     593                KU64            offSect       = 0;
     594                KBOOL           fSkipSeg      = !kHlpStrComp(pSrcSeg->segname, "__DWARF")
     595                                             || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG));
     596
     597                /* Convert and verify the segment. */
     598                KLDRMODMACHO_CHECK_RETURN(u.pLoadCmd->cmdsize >= sizeof(segment_command_32_t), KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
     599                KLDRMODMACHO_CHECK_RETURN(   pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE
     600                                          || pHdr->magic == IMAGE_MACHO32_SIGNATURE, KLDR_ERR_MACHO_BIT_MIX);
    591601                if (fConvertEndian)
    592602                {
    593                     u.pSeg32->vmaddr   = K_E2E_U32(u.pSeg32->vmaddr);
    594                     u.pSeg32->vmsize   = K_E2E_U32(u.pSeg32->vmsize);
    595                     u.pSeg32->fileoff  = K_E2E_U32(u.pSeg32->fileoff);
    596                     u.pSeg32->filesize = K_E2E_U32(u.pSeg32->filesize);
    597                     u.pSeg32->maxprot  = K_E2E_U32(u.pSeg32->maxprot);
    598                     u.pSeg32->initprot = K_E2E_U32(u.pSeg32->initprot);
    599                     u.pSeg32->nsects   = K_E2E_U32(u.pSeg32->nsects);
    600                     u.pSeg32->flags    = K_E2E_U32(u.pSeg32->flags);
     603                    pSrcSeg->vmaddr   = K_E2E_U32(pSrcSeg->vmaddr);
     604                    pSrcSeg->vmsize   = K_E2E_U32(pSrcSeg->vmsize);
     605                    pSrcSeg->fileoff  = K_E2E_U32(pSrcSeg->fileoff);
     606                    pSrcSeg->filesize = K_E2E_U32(pSrcSeg->filesize);
     607                    pSrcSeg->maxprot  = K_E2E_U32(pSrcSeg->maxprot);
     608                    pSrcSeg->initprot = K_E2E_U32(pSrcSeg->initprot);
     609                    pSrcSeg->nsects   = K_E2E_U32(pSrcSeg->nsects);
     610                    pSrcSeg->flags    = K_E2E_U32(pSrcSeg->flags);
    601611                }
    602612
    603                 if (    u.pSeg32->filesize
    604                     &&  (   u.pSeg32->fileoff > cbFile
    605                          || (KU64)u.pSeg32->fileoff + u.pSeg32->filesize > cbFile))
    606                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    607                 if (u.pSeg32->vmsize < u.pSeg32->filesize)
    608                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    609                 if ((u.pSeg32->maxprot & u.pSeg32->initprot) != u.pSeg32->initprot)
    610                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    611                 if (u.pSeg32->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1))
    612                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    613                 if (u.pSeg32->nsects * sizeof(section_32_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_32_t))
    614                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    615                 if (    pHdr->filetype == MH_OBJECT
    616                     &&  cSegmentCommands > 0)
    617                     return KLDR_ERR_MACHO_BAD_OBJECT_FILE;
    618                 cSegmentCommands++;
     613                /* Validation code shared with the 64-bit variant. */
     614                #define VALIDATE_AND_ADD_SEGMENT(a_cBits) \
     615                do { \
     616                    KLDRMODMACHO_CHECK_RETURN(   pSrcSeg->filesize == 0 \
     617                                              || (   pSrcSeg->fileoff <= cbFile \
     618                                                  && (KU64)pSrcSeg->fileoff + pSrcSeg->filesize <= cbFile), \
     619                                              KLDR_ERR_MACHO_BAD_LOAD_COMMAND); \
     620                    KLDRMODMACHO_CHECK_RETURN(pSrcSeg->filesize <= pSrcSeg->vmsize, \
     621                                              KLDR_ERR_MACHO_BAD_LOAD_COMMAND); \
     622                    KLDRMODMACHO_CHECK_RETURN((pSrcSeg->maxprot & pSrcSeg->initprot) == pSrcSeg->initprot, \
     623                                              KLDR_ERR_MACHO_BAD_LOAD_COMMAND); \
     624                    KLDRMODMACHO_CHECK_RETURN(!(pSrcSeg->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1)), \
     625                                              KLDR_ERR_MACHO_BAD_LOAD_COMMAND); \
     626                    KLDRMODMACHO_CHECK_RETURN(   pSrcSeg->nsects * sizeof(section_##a_cBits##_t) \
     627                                              <= u.pLoadCmd->cmdsize - sizeof(segment_command_##a_cBits##_t), \
     628                                              KLDR_ERR_MACHO_BAD_LOAD_COMMAND); \
     629                    KLDRMODMACHO_CHECK_RETURN(    pHdr->filetype != MH_OBJECT \
     630                                              ||  cSegmentCommands == 0,\
     631                                              KLDR_ERR_MACHO_BAD_OBJECT_FILE); \
     632                    cSegmentCommands++; \
     633                    \
     634                    /* add the segment. */ \
     635                    if (!fSkipSeg) \
     636                    { \
     637                        cbStringPool += kHlpStrNLen(&pSrcSeg->segname[0], sizeof(pSrcSeg->segname)) + 1; \
     638                        cSegments++; \
     639                        \
     640                        /* Link address lower? */ \
     641                        if (*pLinkAddress > pSrcSeg->vmaddr) \
     642                            *pLinkAddress = pSrcSeg->vmaddr; \
     643                    } \
     644                } while (0)
     645
     646                VALIDATE_AND_ADD_SEGMENT(32);
    619647
    620648                /*
    621                  * convert, validate and parse the sections.
     649                 * Convert, validate and parse the sections.
    622650                 */
    623                 cSectionsLeft = u.pSeg32->nsects;
    624                 pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1);
     651                cSectionsLeft = pSrcSeg->nsects;
     652                pFirstSect = pSect = (section_32_t *)(pSrcSeg + 1);
    625653                while (cSectionsLeft-- > 0)
    626654                {
    627                     int fFileBits;
    628 
    629655                    if (fConvertEndian)
    630656                    {
     
    640666                    }
    641667
    642                     /* validate */
    643                     switch (pSect->flags & SECTION_TYPE)
    644                     {
    645                         case S_ZEROFILL:
    646                             if (pSect->reserved1 || pSect->reserved2)
    647                                 return KLDR_ERR_MACHO_BAD_SECTION;
    648                             fFileBits = 0;
    649                             break;
    650                         case S_REGULAR:
    651                         case S_CSTRING_LITERALS:
    652                         case S_COALESCED:
    653                         case S_4BYTE_LITERALS:
    654                         case S_8BYTE_LITERALS:
    655                         case S_16BYTE_LITERALS:
    656                             if (pSect->reserved1 || pSect->reserved2)
    657                                 return KLDR_ERR_MACHO_BAD_SECTION;
    658                             fFileBits = 1;
    659                             break;
    660 
    661                         case S_SYMBOL_STUBS:
    662                             if (   pSect->reserved1
    663                                 || pSect->reserved2 > 64 /* stub size */ )
    664                                 return KLDR_ERR_MACHO_BAD_SECTION;
    665                             fFileBits = 1;
    666                             break;
    667 
    668                         case S_NON_LAZY_SYMBOL_POINTERS:
    669                         case S_LAZY_SYMBOL_POINTERS:
    670                             if (pSect->reserved2) /* (reserved 1 is indirect symbol table index)*/
    671                                 return KLDR_ERR_MACHO_BAD_SECTION;
    672                             *pfCanLoad = K_FALSE;
    673                             fFileBits = -1; /* __DATA.__got in the 64-bit mach_kernel has bits, any things without bits? */
    674                             break;
    675 
    676                         case S_MOD_INIT_FUNC_POINTERS: /** @todo this requires a query API or flag... (e.g. C++ constructors)  */
    677                             if (!(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO))
    678                                 return KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION;
    679                         case S_MOD_TERM_FUNC_POINTERS: /** @todo this requires a query API or flag... (e.g. C++ destructors) */
    680                             if (!(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO))
    681                                 return KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION;
    682                             if (pSect->reserved1 || pSect->reserved2)
    683                                 return KLDR_ERR_MACHO_BAD_SECTION;
    684                             fFileBits = 1;
    685                             break; /* ignored */
    686 
    687                         case S_LITERAL_POINTERS:
    688                         case S_INTERPOSING:
    689                         case S_GB_ZEROFILL:
    690                             return KLDR_ERR_MACHO_UNSUPPORTED_SECTION;
    691 
    692                         default:
    693                             return KLDR_ERR_MACHO_UNKNOWN_SECTION;
    694                     }
    695                     if (pSect->flags & ~(  S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS
    696                                          | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE
    697                                          | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC
    698                                          | S_ATTR_LOC_RELOC | SECTION_TYPE))
    699                         return KLDR_ERR_MACHO_BAD_SECTION;
    700                     if (    pSect->addr - u.pSeg32->vmaddr > u.pSeg32->vmsize
    701                         ||  pSect->addr - u.pSeg32->vmaddr + pSect->size > u.pSeg32->vmsize)
    702                         return KLDR_ERR_MACHO_BAD_SECTION;
    703                     if (    pSect->align >= 31
    704                         ||  (((1 << pSect->align) - 1) & pSect->addr)
    705                         ||  (((1 << pSect->align) - 1) & u.pSeg32->vmaddr))
    706                         return KLDR_ERR_MACHO_BAD_SECTION;
    707                     if (    fFileBits
    708                         &&  (   pSect->offset > cbFile
    709                              || (KU64)pSect->offset + pSect->size > cbFile))
    710                         return KLDR_ERR_MACHO_BAD_SECTION;
    711                     if (!fFileBits && pSect->offset)
    712                         return KLDR_ERR_MACHO_BAD_SECTION;
    713                     if (!pSect->nreloc && pSect->reloff)
    714                         return KLDR_ERR_MACHO_BAD_SECTION;
    715                     if (    pSect->nreloc
    716                         &&  (   pSect->reloff > cbFile
    717                              || (KU64)pSect->reloff + (KLDRFOFF)pSect->nreloc * sizeof(macho_relocation_info_t)) > cbFile)
    718                         return KLDR_ERR_MACHO_BAD_SECTION;
    719 
    720 
    721                     /* count segments and strings, calculate image link address. */
    722                     switch (pHdr->filetype)
    723                     {
    724                         case MH_OBJECT:
    725                         case MH_EXECUTE:
    726                         case MH_DYLIB:
    727                         case MH_DSYM:
    728                         case MH_KEXT_BUNDLE:
    729                         {
    730                             cSections++;
    731 
    732                             /* Don't load debug symbols. */
    733                             if (   (pSect->flags & S_ATTR_DEBUG)
    734                                 || !kHlpStrComp(pSect->segname, "__DWARF"))
    735                                 break;
    736 
    737                             /* a new segment? */
    738                             if (    !pchCurSegName
    739                                 ||  kHlpStrNComp(pSect->segname, pchCurSegName, sizeof(pSect->segname)))
    740                             {
    741 #if 0 /** @todo This doesn't work because of BSS. */
    742                                 /* verify that the linker/assembler has ordered sections correctly. */
    743                                 section_32_t *pCur = (pSect - 2);
    744                                 while ((KUPTR)pCur >= (KUPTR)pFirstSect)
    745                                 {
    746                                     if (!kHlpStrNComp(pCur->segname, pSect->segname, sizeof(pSect->segname)))
    747                                         return KLDR_ERR_MACHO_BAD_SECTION_ORDER;
    748                                     pCur--;
    749                                 }
    750 #endif
    751 
    752                                 /* ok. count it and the string. */
    753                                 pchCurSegName = &pSect->segname[0];
    754                                 cbStringPool += kHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1;
    755                                 cSegments++;
    756 
    757                                 /* Link address lower? */
    758                                 if (*pLinkAddress > u.pSeg32->vmaddr)
    759                                     *pLinkAddress = u.pSeg32->vmaddr;
    760                             }
    761                             break;
    762                         }
    763 
    764                         default:
    765                             return KERR_INVALID_PARAMETER;
    766                     }
     668                    /* Validation code shared with the 64-bit variant. */
     669                    #define VALIDATE_AND_ADD_SECTION(a_cBits) \
     670                    do { \
     671                        int fFileBits; \
     672                        \
     673                        /* validate */ \
     674                        KLDRMODMACHO_CHECK_RETURN(!kHlpStrComp(pSect->segname, pSrcSeg->segname),\
     675                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     676                        \
     677                        switch (pSect->flags & SECTION_TYPE) \
     678                        { \
     679                            case S_ZEROFILL: \
     680                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \
     681                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved2, KLDR_ERR_MACHO_BAD_SECTION); \
     682                                fFileBits = 0; \
     683                                break; \
     684                            case S_REGULAR: \
     685                            case S_CSTRING_LITERALS: \
     686                            case S_COALESCED: \
     687                            case S_4BYTE_LITERALS: \
     688                            case S_8BYTE_LITERALS: \
     689                            case S_16BYTE_LITERALS: \
     690                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \
     691                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved2, KLDR_ERR_MACHO_BAD_SECTION); \
     692                                fFileBits = 1; \
     693                                break; \
     694                            \
     695                            case S_SYMBOL_STUBS: \
     696                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \
     697                                /* reserved2 == stub size. 0 has been seen (corecrypto.kext) */ \
     698                                KLDRMODMACHO_CHECK_RETURN(pSect->reserved2 > 64, KLDR_ERR_MACHO_BAD_SECTION); \
     699                                fFileBits = 1; \
     700                                break; \
     701                            \
     702                            case S_NON_LAZY_SYMBOL_POINTERS: \
     703                            case S_LAZY_SYMBOL_POINTERS: \
     704                                /* (reserved 1 = is indirect symbol table index) */ \
     705                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved2, KLDR_ERR_MACHO_BAD_SECTION); \
     706                                *pfCanLoad = K_FALSE; \
     707                                fFileBits = -1; /* __DATA.__got in the 64-bit mach_kernel has bits, any things without bits? */ \
     708                                break; \
     709                            \
     710                            case S_MOD_INIT_FUNC_POINTERS: \
     711                                /** @todo this requires a query API or flag... (e.g. C++ constructors) */ \
     712                                KLDRMODMACHO_CHECK_RETURN(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO, \
     713                                                          KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION); \
     714                            case S_MOD_TERM_FUNC_POINTERS: \
     715                                /** @todo this requires a query API or flag... (e.g. C++ destructors) */ \
     716                                KLDRMODMACHO_CHECK_RETURN(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO, \
     717                                                          KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION); \
     718                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \
     719                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved2, KLDR_ERR_MACHO_BAD_SECTION); \
     720                                fFileBits = 1; \
     721                                break; /* ignored */ \
     722                            \
     723                            case S_LITERAL_POINTERS: \
     724                            case S_INTERPOSING: \
     725                            case S_GB_ZEROFILL: \
     726                                KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_UNSUPPORTED_SECTION); \
     727                            \
     728                            default: \
     729                                KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_UNKNOWN_SECTION); \
     730                        } \
     731                        KLDRMODMACHO_CHECK_RETURN(!(pSect->flags & ~(  S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS \
     732                                                                     | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE \
     733                                                                     | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC \
     734                                                                     | S_ATTR_LOC_RELOC | SECTION_TYPE)), \
     735                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     736                        KLDRMODMACHO_CHECK_RETURN((pSect->flags & S_ATTR_DEBUG) == (pSect->flags & S_ATTR_DEBUG), \
     737                                                  KLDR_ERR_MACHO_MIXED_DEBUG_SECTION_FLAGS); \
     738                        \
     739                        KLDRMODMACHO_CHECK_RETURN(pSect->addr - pSrcSeg->vmaddr <= pSrcSeg->vmsize, \
     740                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     741                        KLDRMODMACHO_CHECK_RETURN(pSect->addr - pSrcSeg->vmaddr + pSect->size <= pSrcSeg->vmsize, \
     742                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     743                        KLDRMODMACHO_CHECK_RETURN(pSect->align < 31, \
     744                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     745                        KLDRMODMACHO_CHECK_RETURN(!((K_BIT32(pSect->align) - KU32_C(1)) & pSect->addr), \
     746                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     747                        KLDRMODMACHO_CHECK_RETURN(!((K_BIT32(pSect->align) - KU32_C(1)) & pSrcSeg->vmaddr), \
     748                                                  KLDR_ERR_MACHO_BAD_SECTION); \
     749                        \
     750                        /* Adjust the section offset before we check file offset. */ \
     751                        offSect = (offSect + K_BIT64(pSect->align) - KU64_C(1)) & ~(K_BIT64(pSect->align) - KU64_C(1)); \
     752                        if (pSect->addr) \
     753                        { \
     754                            KLDRMODMACHO_CHECK_RETURN(offSect <= pSect->addr - pSrcSeg->vmaddr, KLDR_ERR_MACHO_BAD_SECTION); \
     755                            if (offSect < pSect->addr - pSrcSeg->vmaddr) \
     756                                offSect = pSect->addr - pSrcSeg->vmaddr; \
     757                        } \
     758                        \
     759                        if (fFileBits && pSect->offset == 0 && pSrcSeg->fileoff == 0 && pHdr->filetype == MH_DSYM) \
     760                            fFileBits = 0; \
     761                        if (fFileBits) \
     762                        { \
     763                            KLDRMODMACHO_CHECK_RETURN(pSect->offset == pSrcSeg->fileoff + offSect, \
     764                                                      KLDR_ERR_MACHO_NON_CONT_SEG_BITS); \
     765                            KLDRMODMACHO_CHECK_RETURN(pSect->offset - pSrcSeg->fileoff <= pSrcSeg->filesize, \
     766                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     767                            KLDRMODMACHO_CHECK_RETURN(pSect->offset <= cbFile, \
     768                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     769                            KLDRMODMACHO_CHECK_RETURN((KU64)pSect->offset + pSect->size <= cbFile, \
     770                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     771                        } \
     772                        else \
     773                            KLDRMODMACHO_CHECK_RETURN(pSect->offset == 0, KLDR_ERR_MACHO_BAD_SECTION); \
     774                        \
     775                        if (!pSect->nreloc) \
     776                            KLDRMODMACHO_CHECK_RETURN(!pSect->reloff, \
     777                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     778                        else \
     779                        { \
     780                            KLDRMODMACHO_CHECK_RETURN(pSect->reloff <= cbFile, \
     781                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     782                            KLDRMODMACHO_CHECK_RETURN(     (KU64)pSect->reloff \
     783                                                         + (KLDRFOFF)pSect->nreloc * sizeof(macho_relocation_info_t) \
     784                                                      <= cbFile, \
     785                                                      KLDR_ERR_MACHO_BAD_SECTION); \
     786                        } \
     787                        \
     788                        /* validate against file type (pointless?) and count the section. */ \
     789                        switch (pHdr->filetype) \
     790                        { \
     791                            case MH_OBJECT: \
     792                            case MH_EXECUTE: \
     793                            case MH_DYLIB: \
     794                            case MH_DSYM: \
     795                            case MH_KEXT_BUNDLE: \
     796                                cSections++; \
     797                                break; \
     798                            default: \
     799                                KLDRMODMACHO_FAILED_RETURN(KERR_INVALID_PARAMETER); \
     800                        } \
     801                        \
     802                        /* Advance the section offset, since we're also aligning it. */ \
     803                        offSect += pSect->size; \
     804                    } while (0) /* VALIDATE_AND_ADD_SECTION */
     805
     806                    VALIDATE_AND_ADD_SECTION(32);
    767807
    768808                    /* next */
     
    774814            case LC_SEGMENT_64:
    775815            {
    776                 section_64_t *pSect;
    777                 section_64_t *pFirstSect;
    778                 KU32 cSectionsLeft;
    779 
    780                 /* convert and verify*/
    781                 if (u.pLoadCmd->cmdsize < sizeof(segment_command_64_t))
    782                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    783                 if (    pHdr->magic != IMAGE_MACHO64_SIGNATURE_OE
    784                     &&  pHdr->magic != IMAGE_MACHO64_SIGNATURE)
    785                     return KLDR_ERR_MACHO_BIT_MIX;
     816                segment_command_64_t *pSrcSeg = (segment_command_64_t *)u.pLoadCmd;
     817                section_64_t   *pFirstSect    = (section_64_t *)(pSrcSeg + 1);
     818                section_64_t   *pSect         = pFirstSect;
     819                KU32            cSectionsLeft = pSrcSeg->nsects;
     820                KU64            offSect       = 0;
     821                KBOOL           fSkipSeg      = !kHlpStrComp(pSrcSeg->segname, "__DWARF")
     822                                             || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG));
     823
     824                /* Convert and verify the segment. */
     825                KLDRMODMACHO_CHECK_RETURN(u.pLoadCmd->cmdsize >= sizeof(segment_command_64_t), KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
     826                KLDRMODMACHO_CHECK_RETURN(   pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE
     827                                          || pHdr->magic == IMAGE_MACHO64_SIGNATURE, KLDR_ERR_MACHO_BIT_MIX);
    786828                if (fConvertEndian)
    787829                {
    788                     u.pSeg64->vmaddr   = K_E2E_U64(u.pSeg64->vmaddr);
    789                     u.pSeg64->vmsize   = K_E2E_U64(u.pSeg64->vmsize);
    790                     u.pSeg64->fileoff  = K_E2E_U64(u.pSeg64->fileoff);
    791                     u.pSeg64->filesize = K_E2E_U64(u.pSeg64->filesize);
    792                     u.pSeg64->maxprot  = K_E2E_U32(u.pSeg64->maxprot);
    793                     u.pSeg64->initprot = K_E2E_U32(u.pSeg64->initprot);
    794                     u.pSeg64->nsects   = K_E2E_U32(u.pSeg64->nsects);
    795                     u.pSeg64->flags    = K_E2E_U32(u.pSeg64->flags);
     830                    pSrcSeg->vmaddr   = K_E2E_U64(pSrcSeg->vmaddr);
     831                    pSrcSeg->vmsize   = K_E2E_U64(pSrcSeg->vmsize);
     832                    pSrcSeg->fileoff  = K_E2E_U64(pSrcSeg->fileoff);
     833                    pSrcSeg->filesize = K_E2E_U64(pSrcSeg->filesize);
     834                    pSrcSeg->maxprot  = K_E2E_U32(pSrcSeg->maxprot);
     835                    pSrcSeg->initprot = K_E2E_U32(pSrcSeg->initprot);
     836                    pSrcSeg->nsects   = K_E2E_U32(pSrcSeg->nsects);
     837                    pSrcSeg->flags    = K_E2E_U32(pSrcSeg->flags);
    796838                }
    797839
    798                 if (    u.pSeg64->filesize
    799                     &&  (   u.pSeg64->fileoff > cbFile
    800                          || u.pSeg64->fileoff + u.pSeg64->filesize > cbFile))
    801                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    802                 if (u.pSeg64->vmsize < u.pSeg64->filesize)
    803                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    804                 if ((u.pSeg64->maxprot & u.pSeg64->initprot) != u.pSeg64->initprot)
    805                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    806                 if (u.pSeg64->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1))
    807                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    808                 if (u.pSeg64->nsects * sizeof(section_64_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_64_t))
    809                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
    810                 if (    pHdr->filetype == MH_OBJECT
    811                     &&  cSegmentCommands > 0)
    812                     return KLDR_ERR_MACHO_BAD_OBJECT_FILE;
    813                 cSegmentCommands++;
     840                VALIDATE_AND_ADD_SEGMENT(64);
    814841
    815842                /*
    816                  * convert, validate and parse the sections.
     843                 * Convert, validate and parse the sections.
    817844                 */
    818                 cSectionsLeft = u.pSeg64->nsects;
    819                 pFirstSect = pSect = (section_64_t *)(u.pSeg64 + 1);
    820845                while (cSectionsLeft-- > 0)
    821846                {
    822                     int fFileBits;
    823 
    824847                    if (fConvertEndian)
    825848                    {
     
    835858                    }
    836859
    837                     /* validate */
    838                     switch (pSect->flags & SECTION_TYPE)
    839                     {
    840                         case S_ZEROFILL:
    841                             if (pSect->reserved1 || pSect->reserved2)
    842                                 return KLDR_ERR_MACHO_BAD_SECTION;
    843                             fFileBits = 0;
    844                             break;
    845                         case S_REGULAR:
    846                         case S_CSTRING_LITERALS:
    847                         case S_COALESCED:
    848                         case S_4BYTE_LITERALS:
    849                         case S_8BYTE_LITERALS:
    850                         case S_16BYTE_LITERALS:
    851                             if (pSect->reserved1 || pSect->reserved2)
    852                                 return KLDR_ERR_MACHO_BAD_SECTION;
    853                             fFileBits = 1;
    854                             break;
    855 
    856                         case S_SYMBOL_STUBS:
    857                             if (   pSect->reserved1
    858                                 || pSect->reserved2 > 64 /* stub size. 0 has been seen (corecrypto.kext) */ )
    859                                 return KLDR_ERR_MACHO_BAD_SECTION;
    860                             fFileBits = 1;
    861                             break;
    862 
    863                         case S_NON_LAZY_SYMBOL_POINTERS:
    864                         case S_LAZY_SYMBOL_POINTERS:
    865                             if (pSect->reserved2) /* (reserved 1 is indirect symbol table index)*/
    866                                 return KLDR_ERR_MACHO_BAD_SECTION;
    867                             *pfCanLoad = K_FALSE;
    868                             fFileBits = -1; /* __DATA.__got in the 64-bit mach_kernel has bits, any things without bits? */
    869                             break;
    870 
    871                         case S_MOD_INIT_FUNC_POINTERS: /** @todo this requires a query API or flag... (e.g. C++ constructors)  */
    872                             if (!(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO))
    873                                 return KLDR_ERR_MACHO_UNSUPPORTED_INIT_SECTION;
    874                         case S_MOD_TERM_FUNC_POINTERS: /** @todo this requires a query API or flag... (e.g. C++ destructors) */
    875                             if (!(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO))
    876                                 return KLDR_ERR_MACHO_UNSUPPORTED_TERM_SECTION;
    877                             if (pSect->reserved1 || pSect->reserved2)
    878                                 return KLDR_ERR_MACHO_BAD_SECTION;
    879                             fFileBits = 1;
    880                             break; /* ignored */
    881 
    882                         case S_LITERAL_POINTERS:
    883                         case S_INTERPOSING:
    884                         case S_GB_ZEROFILL:
    885                             return KLDR_ERR_MACHO_UNSUPPORTED_SECTION;
    886 
    887                         default:
    888                             return KLDR_ERR_MACHO_UNKNOWN_SECTION;
    889                     }
    890                     if (pSect->flags & ~(  S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS
    891                                          | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE
    892                                          | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC
    893                                          | S_ATTR_LOC_RELOC | SECTION_TYPE))
    894                         return KLDR_ERR_MACHO_BAD_SECTION;
    895                     if (    pSect->addr - u.pSeg64->vmaddr > u.pSeg64->vmsize
    896                         ||  pSect->addr - u.pSeg64->vmaddr + pSect->size > u.pSeg64->vmsize)
    897                         return KLDR_ERR_MACHO_BAD_SECTION;
    898                     if (    pSect->align >= 31
    899                         ||  (((1 << pSect->align) - 1) & pSect->addr)
    900                         ||  (((1 << pSect->align) - 1) & u.pSeg64->vmaddr))
    901                         return KLDR_ERR_MACHO_BAD_SECTION;
    902                     if (    fFileBits
    903                         &&  (   pSect->offset > cbFile
    904                              || (KU64)pSect->offset + pSect->size > cbFile))
    905                         return KLDR_ERR_MACHO_BAD_SECTION;
    906                     if (!fFileBits && pSect->offset)
    907                         return KLDR_ERR_MACHO_BAD_SECTION;
    908                     if (!pSect->nreloc && pSect->reloff)
    909                         return KLDR_ERR_MACHO_BAD_SECTION;
    910                     if (    pSect->nreloc
    911                         &&  (   pSect->reloff > cbFile
    912                              || (KU64)pSect->reloff + (KLDRFOFF)pSect->nreloc * sizeof(macho_relocation_info_t)) > cbFile)
    913                         return KLDR_ERR_MACHO_BAD_SECTION;
    914 
    915 
    916                     /* count segments and strings, calculate image link address. */
    917                     switch (pHdr->filetype)
    918                     {
    919                         case MH_OBJECT:
    920                         case MH_EXECUTE:
    921                         case MH_DYLIB:
    922                         case MH_DSYM:
    923                         case MH_KEXT_BUNDLE:
    924                         {
    925                             cSections++;
    926 
    927                             /* Don't load debug symbols. (test this) */
    928                             if (   (pSect->flags & S_ATTR_DEBUG)
    929                                 || !kHlpStrComp(pSect->segname, "__DWARF"))
    930                                 break;
    931 
    932                             /* a new segment? */
    933                             if (    !pchCurSegName
    934                                 ||  kHlpStrNComp(pSect->segname, pchCurSegName, sizeof(pSect->segname)))
    935                             {
    936 #if 0 /** @todo This doesn't work because of BSS. */
    937                                 /* verify that the linker/assembler has ordered sections correctly. */
    938                                 section_64_t *pCur = (pSect - 2);
    939                                 while ((KUPTR)pCur >= (KUPTR)pFirstSect)
    940                                 {
    941                                     if (!kHlpStrNComp(pCur->segname, pSect->segname, sizeof(pSect->segname)))
    942                                         return KLDR_ERR_MACHO_BAD_SECTION_ORDER;
    943                                     pCur--;
    944                                 }
    945 #endif
    946 
    947                                 /* ok. count it and the string. */
    948                                 pchCurSegName = &pSect->segname[0];
    949                                 cbStringPool += kHlpStrNLen(&pSect->segname[0], sizeof(pSect->segname)) + 1;
    950                                 cSegments++;
    951 
    952                                 /* Link address lower? */
    953                                 if (*pLinkAddress > u.pSeg64->vmaddr)
    954                                     *pLinkAddress = u.pSeg64->vmaddr;
    955                             }
    956                             break;
    957                         }
    958 
    959                         default:
    960                             return KERR_INVALID_PARAMETER;
    961                     }
     860                    VALIDATE_AND_ADD_SECTION(64);
    962861
    963862                    /* next */
     
    986885                if (    u.pSymTab->symoff >= cbFile
    987886                    ||  (KU64)u.pSymTab->symoff + u.pSymTab->nsyms * cbSym > cbFile)
    988                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     887                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    989888                if (    u.pSymTab->stroff >= cbFile
    990889                    ||  (KU64)u.pSymTab->stroff + u.pSymTab->strsize > cbFile)
    991                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     890                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    992891
    993892                /* only one string in objects, please. */
     
    995894                if (    pHdr->filetype == MH_OBJECT
    996895                    &&  cSymbolTabs != 1)
    997                     return KLDR_ERR_MACHO_BAD_OBJECT_FILE;
     896                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_OBJECT_FILE);
    998897                break;
    999898            }
     
    1012911                    /* convert & verify header items ([0] == flavor, [1] == KU32 count). */
    1013912                    if (cItemsLeft < 2)
    1014                         return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     913                        KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    1015914                    if (fConvertEndian)
    1016915                    {
     
    1019918                    }
    1020919                    if (pu32[1] + 2 > cItemsLeft)
    1021                         return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     920                        KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    1022921
    1023922                    /* convert & verify according to flavor. */
     
    1038937            case LC_UUID:
    1039938                if (u.pUuid->cmdsize != sizeof(uuid_command_t))
    1040                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     939                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    1041940                /** @todo Check anything here need converting? */
    1042941                break;
     
    1044943            case LC_CODE_SIGNATURE:
    1045944                if (u.pUuid->cmdsize != sizeof(linkedit_data_command_t))
    1046                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     945                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    1047946                break;
    1048947
     
    1050949            case LC_VERSION_MIN_IPHONEOS:
    1051950                if (u.pUuid->cmdsize != sizeof(version_min_command_t))
    1052                     return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     951                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    1053952                break;
    1054953
     
    1076975                /** @todo valid command size. */
    1077976                if (!(fOpenFlags & KLDRMOD_OPEN_FLAGS_FOR_INFO))
    1078                     return KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND;
     977                    KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND);
    1079978                break;
    1080979
     
    1093992            case LC_PREBIND_CKSUM:
    1094993            case LC_SYMSEG:
    1095                 return KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND;
     994                KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND);
    1096995
    1097996            default:
    1098                 return KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND;
     997                KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND);
    1099998        }
    1100999    }
     
    11021001    /* be strict. */
    11031002    if (cbLeft)
    1104         return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
     1003        KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_LOAD_COMMAND);
    11051004
    11061005    switch (pHdr->filetype)
     
    11121011        case MH_KEXT_BUNDLE:
    11131012            if (!cSegments)
    1114                 return KLDR_ERR_MACHO_BAD_OBJECT_FILE;
     1013                KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_MACHO_BAD_OBJECT_FILE);
    11151014            break;
    11161015    }
     
    11461045        const uuid_command_t       *pUuid;
    11471046    } u;
    1148     const char *pchCurSegName = NULL;
    11491047    KU32 cLeft = pModMachO->Hdr.ncmds;
    11501048    KU32 cbLeft = pModMachO->Hdr.sizeofcmds;
    11511049    const KU8 *pb = pModMachO->pbLoadCommands;
    1152     PKLDRSEG pSeg = &pModMachO->pMod->aSegments[0];
     1050    PKLDRSEG pDstSeg = &pModMachO->pMod->aSegments[0];
    11531051    PKLDRMODMACHOSEG pSegExtra = &pModMachO->aSegments[0];
    11541052    PKLDRMODMACHOSECT pSectExtra = pModMachO->paSections;
    11551053    const KU32 cSegments = pModMachO->pMod->cSegments;
    1156     KU32 i, c;
     1054    PKLDRSEG pSegItr;
    11571055
    11581056    while (cLeft-- > 0)
     
    11691067            case LC_SEGMENT_32:
    11701068            {
    1171                 section_32_t *pSect;
    1172                 section_32_t *pFirstSect;
    1173                 KU32 cSectionsLeft;
    1174 
    1175                 kHlpAssert(u.pSeg32->vmaddr >= pModMachO->LinkAddress);
    1176 
    1177                 /*
    1178                  * convert, validate and parse the sections.
    1179                  */
    1180                 cSectionsLeft = u.pSeg32->nsects;
    1181                 pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1);
    1182                 while (cSectionsLeft-- > 0)
    1183                 {
    1184                     switch (pModMachO->Hdr.filetype)
    1185                     {
    1186                         case MH_OBJECT:
    1187                         case MH_EXECUTE:
    1188                         case MH_DYLIB:
    1189                         case MH_DSYM:
    1190                         case MH_KEXT_BUNDLE:
    1191                         {
    1192                             /* Section data extract. */
    1193                             pSectExtra->cb = pSect->size;
    1194                             pSectExtra->RVA = pSect->addr;
    1195                             pSectExtra->LinkAddress = pSect->addr;
    1196                             if (pSect->offset)
    1197                                 pSectExtra->offFile = pSect->offset + pModMachO->offImage;
    1198                             else
    1199                                 pSectExtra->offFile = -1;
    1200                             pSectExtra->cFixups = pSect->nreloc;
    1201                             pSectExtra->paFixups = NULL;
    1202                             if (pSect->nreloc)
    1203                                 pSectExtra->offFixups = pSect->reloff + pModMachO->offImage;
    1204                             else
    1205                                 pSectExtra->offFixups = -1;
    1206                             pSectExtra->fFlags = pSect->flags;
    1207                             pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
    1208                             pSectExtra->pvMachoSection = pSect;
    1209 
    1210                             /* Don't load debug symbols. (test this!) */
    1211                             if (   (pSect->flags & S_ATTR_DEBUG)
    1212                                 || !kHlpStrComp(pSect->segname, "__DWARF"))
    1213                             {
    1214                                 pSectExtra++;
    1215                                 /** @todo */
    1216                                 break;
    1217                             }
    1218 
    1219                             if (    !pchCurSegName
    1220                                 ||  kHlpStrNComp(pSect->segname, pchCurSegName, sizeof(pSect->segname)))
    1221                             {
    1222                                 /* close the previous segment */
    1223                                 if (pSegExtra != &pModMachO->aSegments[0])
    1224                                     pSegExtra[-1].cSections = pSectExtra - pSegExtra[-1].paSections;
    1225 
    1226                                 /* new segment. */
    1227                                 pSeg->pvUser = NULL;
    1228                                 pSeg->pchName = pbStringPool;
    1229                                 pSeg->cchName = (KU32)kHlpStrNLen(&pSect->segname[0], sizeof(pSect->sectname));
    1230                                 kHlpMemCopy(pbStringPool, &pSect->segname[0], pSeg->cchName);
    1231                                 pbStringPool += pSeg->cchName;
    1232                                 *pbStringPool++ = '\0';
    1233                                 pSeg->SelFlat = 0;
    1234                                 pSeg->Sel16bit = 0;
    1235                                 pSeg->fFlags = 0;
    1236                                 pSeg->enmProt = KPROT_EXECUTE_WRITECOPY; /** @todo fixme! */
    1237                                 pSeg->cb = pSect->size;
    1238                                 pSeg->Alignment = (KLDRADDR)1 << pSect->align;
    1239                                 pSeg->LinkAddress = pSect->addr;
    1240                                 if (pSect->offset)
    1241                                 {
    1242                                     pSeg->offFile = pSect->offset + pModMachO->offImage;
    1243                                     pSeg->cbFile  = pSect->size;
    1244                                 }
    1245                                 else
    1246                                 {
    1247                                     pSeg->offFile = -1;
    1248                                     pSeg->cbFile  = -1;
    1249                                 }
    1250                                 pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
    1251                                 pSeg->cbMapped = 0;
    1252                                 pSeg->MapAddress = 0;
    1253 
    1254                                 pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0];
    1255                                 pSegExtra->cSections = 0;
    1256                                 pSegExtra->paSections = pSectExtra;
    1257 
    1258                                 pSeg++;
    1259                                 pSegExtra++;
    1260                                 pchCurSegName = &pSect->segname[0];
    1261                             }
    1262                             else
    1263                             {
    1264                                 /* update exiting segment */
    1265                                 if (pSeg[-1].Alignment < K_BIT64(pSect->align))
    1266                                     pSeg[-1].Alignment = K_BIT64(pSect->align);
    1267                                 if (pSect->addr < pSeg[-1].LinkAddress)
    1268                                     return KLDR_ERR_MACHO_BAD_SECTION; /** @todo move up! */
    1269 
    1270                                 /* If there are file bits, ensure they are in the current flow.
    1271                                    (yes, we are very very careful here, I know.) */
    1272                                 if (    pSect->offset
    1273                                     &&  (KU64)pSeg[-1].cbFile == pSeg[-1].cb)
    1274                                 {
    1275                                     int fOk = (KU64)pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + (KU64)pModMachO->offImage
    1276                                            && pSect[-1].offset
    1277                                            && (KU64)pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + (KU64)pModMachO->offImage + pSect[-1].size;
    1278                                     /* more checks? */
    1279                                     if (fOk)
    1280                                         pSeg[-1].cbFile = (KLDRFOFF)(pSect->addr - pSeg[-1].LinkAddress) + pSect->size;
    1281                                     else
    1282                                     {
    1283 
    1284                                         pSeg[-1].cbFile = pSeg[-1].offFile = -1;
    1285                                         pModMachO->fMapUsingLoadCommandSections = K_TRUE;
    1286                                     }
    1287                                 }
    1288                                 pSeg[-1].cb = pSect->addr - pSeg[-1].LinkAddress + pSect->size;
    1289 
    1290                                 /** @todo update the protection... */
    1291                             }
    1292                             pSectExtra++;
    1293                             break;
    1294                         }
    1295 
    1296                         default:
    1297                             return KERR_INVALID_PARAMETER;
    1298                     }
    1299 
    1300                     /* next */
    1301                     pSect++;
    1302                 }
     1069                const segment_command_32_t *pSrcSeg = (const segment_command_32_t *)u.pLoadCmd;
     1070                section_32_t   *pFirstSect    = (section_32_t *)(pSrcSeg + 1);
     1071                section_32_t   *pSect         = pFirstSect;
     1072                KU32            cSectionsLeft = pSrcSeg->nsects;
     1073
     1074                /* Shared with the 64-bit variant. */
     1075                #define ADD_SEGMENT_AND_ITS_SECTIONS(a_cBits) \
     1076                do { \
     1077                    KBOOL   fSkipSeg = !kHlpStrComp(pSrcSeg->segname, "__DWARF") \
     1078                                    || (cSectionsLeft > 0 && (pFirstSect->flags & S_ATTR_DEBUG)); \
     1079                    \
     1080                    kHlpAssert(pSrcSeg->vmaddr >= pModMachO->LinkAddress); \
     1081                    \
     1082                    /* \
     1083                     * Check that the segment name is unique.  We couldn't do that \
     1084                     * in the preparsing stage. \
     1085                     */ \
     1086                    for (pSegItr = &pModMachO->pMod->aSegments[0]; pSegItr != pDstSeg; pSegItr++) \
     1087                        if (!kHlpStrNComp(pSegItr->pchName, pSrcSeg->segname, sizeof(pSrcSeg->segname))) \
     1088                            KLDRMODMACHO_FAILED_RETURN(KLDR_ERR_DUPLICATE_SEGMENT_NAME); \
     1089                    \
     1090                    /* \
     1091                     * Create a new segment, unless we're supposed to skip this one. \
     1092                     */ \
     1093                    if (!fSkipSeg) \
     1094                    { \
     1095                        pDstSeg->pvUser = NULL; \
     1096                        pDstSeg->pchName = pbStringPool; \
     1097                        pDstSeg->cchName = (KU32)kHlpStrNLen(&pSrcSeg->segname[0], sizeof(pSrcSeg->segname)); \
     1098                        kHlpMemCopy(pbStringPool, &pSrcSeg->segname[0], pDstSeg->cchName); \
     1099                        pbStringPool += pDstSeg->cchName; \
     1100                        *pbStringPool++ = '\0'; \
     1101                        pDstSeg->SelFlat = 0; \
     1102                        pDstSeg->Sel16bit = 0; \
     1103                        pDstSeg->fFlags = 0; \
     1104                        pDstSeg->enmProt = KPROT_EXECUTE_WRITECOPY; /** @todo fixme! */ \
     1105                        pDstSeg->cb = pSrcSeg->vmsize; \
     1106                        pDstSeg->Alignment = 1; /* updated while parsing sections. */ \
     1107                        pDstSeg->LinkAddress = pSrcSeg->vmaddr; \
     1108                        if (pSrcSeg->filesize > 0) \
     1109                        { \
     1110                            pDstSeg->offFile = pSrcSeg->fileoff + pModMachO->offImage; \
     1111                            pDstSeg->cbFile  = pSrcSeg->filesize; \
     1112                        } \
     1113                        else \
     1114                        { \
     1115                            pDstSeg->offFile = -1; \
     1116                            pDstSeg->cbFile  = -1; \
     1117                        } \
     1118                        pDstSeg->RVA = pSrcSeg->vmaddr - pModMachO->LinkAddress; \
     1119                        pDstSeg->cbMapped = 0; \
     1120                        pDstSeg->MapAddress = 0; \
     1121                        \
     1122                        pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0]; \
     1123                        pSegExtra->cSections = 0; \
     1124                        pSegExtra->paSections = pSectExtra; \
     1125                    } \
     1126                    \
     1127                    /* \
     1128                     * Convert and parse the sections. \
     1129                     */ \
     1130                    while (cSectionsLeft-- > 0) \
     1131                    { \
     1132                        /* Section data extract. */ \
     1133                        pSectExtra->cb = pSect->size; \
     1134                        pSectExtra->RVA = pSect->addr; \
     1135                        pSectExtra->LinkAddress = pSect->addr; \
     1136                        if (pSect->offset) \
     1137                            pSectExtra->offFile = pSect->offset + pModMachO->offImage; \
     1138                        else \
     1139                            pSectExtra->offFile = -1; \
     1140                        pSectExtra->cFixups = pSect->nreloc; \
     1141                        pSectExtra->paFixups = NULL; \
     1142                        if (pSect->nreloc) \
     1143                            pSectExtra->offFixups = pSect->reloff + pModMachO->offImage; \
     1144                        else \
     1145                            pSectExtra->offFixups = -1; \
     1146                        pSectExtra->fFlags = pSect->flags; \
     1147                        pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0]; \
     1148                        pSectExtra->pvMachoSection = pSect; \
     1149                        \
     1150                        /* Update the segment alignment, if we're not skipping it. */ \
     1151                        if (!fSkipSeg && pDstSeg->Alignment < ((KLDRADDR)1 << pSect->align)) \
     1152                            pDstSeg->Alignment = (KLDRADDR)1 << pSect->align; \
     1153                        \
     1154                        /* Next section. */ \
     1155                        pSectExtra++; \
     1156                        pSect++; \
     1157                    } \
     1158                    \
     1159                    /* Close the segment and advance. */ \
     1160                    if (!fSkipSeg) \
     1161                    { \
     1162                        pSegExtra->cSections = pSectExtra - pSegExtra->paSections; \
     1163                        pSegExtra++; \
     1164                        pDstSeg++; \
     1165                    } \
     1166                } while (0) /* ADD_SEGMENT_AND_ITS_SECTIONS */
     1167
     1168                ADD_SEGMENT_AND_ITS_SECTIONS(32);
    13031169                break;
    13041170            }
     
    13061172            case LC_SEGMENT_64:
    13071173            {
    1308                 section_64_t *pSect;
    1309                 section_64_t *pFirstSect;
    1310                 KU32 cSectionsLeft;
    1311 
    1312                 kHlpAssert(u.pSeg64->vmaddr >= pModMachO->LinkAddress);
    1313 
    1314                 /*
    1315                  * convert, validate and parse the sections.
    1316                  */
    1317                 cSectionsLeft = u.pSeg64->nsects;
    1318                 pFirstSect = pSect = (section_64_t *)(u.pSeg64 + 1);
    1319                 while (cSectionsLeft-- > 0)
    1320                 {
    1321                     switch (pModMachO->Hdr.filetype)
    1322                     {
    1323                         case MH_OBJECT:
    1324                         case MH_EXECUTE:
    1325                         case MH_DYLIB:
    1326                         case MH_DSYM:
    1327                         case MH_KEXT_BUNDLE:
    1328                         {
    1329                             /* Section data extract. */
    1330                             pSectExtra->cb = pSect->size;
    1331                             pSectExtra->RVA = pSect->addr;
    1332                             pSectExtra->LinkAddress = pSect->addr;
    1333                             if (pSect->offset)
    1334                                 pSectExtra->offFile = pSect->offset + pModMachO->offImage;
    1335                             else
    1336                                 pSectExtra->offFile = -1;
    1337                             pSectExtra->cFixups = pSect->nreloc;
    1338                             pSectExtra->paFixups = NULL;
    1339                             if (pSect->nreloc)
    1340                                 pSectExtra->offFixups = pSect->reloff + pModMachO->offImage;
    1341                             else
    1342                                 pSectExtra->offFixups = -1;
    1343                             pSectExtra->fFlags = pSect->flags;
    1344                             pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
    1345                             pSectExtra->pvMachoSection = pSect;
    1346 
    1347                             /* Don't load debug symbols. (test this!) */
    1348                             if (   (pSect->flags & S_ATTR_DEBUG)
    1349                                 || !kHlpStrComp(pSect->segname, "__DWARF"))
    1350                             {
    1351                                 pSectExtra++;
    1352                                 /** @todo */
    1353                                 break;
    1354                             }
    1355 
    1356                             if (    !pchCurSegName
    1357                                 ||  kHlpStrNComp(pSect->segname, pchCurSegName, sizeof(pSect->segname)))
    1358                             {
    1359                                 /* close the previous segment */
    1360                                 if (pSegExtra != &pModMachO->aSegments[0])
    1361                                     pSegExtra[-1].cSections = pSectExtra - pSegExtra[-1].paSections;
    1362 
    1363                                 /* new segment. */
    1364                                 pSeg->pvUser = NULL;
    1365                                 pSeg->pchName = pbStringPool;
    1366                                 pSeg->cchName = (KU32)kHlpStrNLen(&pSect->segname[0], sizeof(pSect->sectname));
    1367                                 kHlpMemCopy(pbStringPool, &pSect->segname[0], pSeg->cchName);
    1368                                 pbStringPool += pSeg->cchName;
    1369                                 *pbStringPool++ = '\0';
    1370                                 pSeg->SelFlat = 0;
    1371                                 pSeg->Sel16bit = 0;
    1372                                 pSeg->fFlags = 0;
    1373                                 pSeg->enmProt = KPROT_EXECUTE_WRITECOPY; /** @todo fixme! */
    1374                                 pSeg->cb = pSect->size;
    1375                                 pSeg->Alignment = (KLDRADDR)1 << pSect->align;
    1376                                 pSeg->LinkAddress = pSect->addr;
    1377                                 if (pSect->offset)
    1378                                 {
    1379                                     pSeg->offFile = pSect->offset + pModMachO->offImage;
    1380                                     pSeg->cbFile  = pSect->size;
    1381                                 }
    1382                                 else
    1383                                 {
    1384                                     pSeg->offFile = -1;
    1385                                     pSeg->cbFile  = -1;
    1386                                 }
    1387                                 pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
    1388                                 pSeg->cbMapped = 0;
    1389                                 pSeg->MapAddress = 0;
    1390 
    1391                                 pSegExtra->iOrgSegNo = pSegExtra - &pModMachO->aSegments[0];
    1392                                 pSegExtra->cSections = 0;
    1393                                 pSegExtra->paSections = pSectExtra;
    1394 
    1395                                 pSeg++;
    1396                                 pSegExtra++;
    1397                                 pchCurSegName = &pSect->segname[0];
    1398                             }
    1399                             else
    1400                             {
    1401                                 /* update exiting segment */
    1402                                 if (pSeg[-1].Alignment < K_BIT64(pSect->align))
    1403                                     pSeg[-1].Alignment = K_BIT64(pSect->align);
    1404                                 if (pSect->addr < pSeg[-1].LinkAddress)
    1405                                     return KLDR_ERR_MACHO_BAD_SECTION; /** @todo move up! */
    1406 
    1407                                 /* If there are file bits, ensure they are in the current flow.
    1408                                    (yes, we are very very careful here, I know.) */
    1409                                 if (    pSect->offset
    1410                                     &&  (KU64)pSeg[-1].cbFile == pSeg[-1].cb)
    1411                                 {
    1412                                     int fOk = (KU64)pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + (KU64)pModMachO->offImage
    1413                                            && pSect[-1].offset
    1414                                            && (KU64)pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + (KU64)pModMachO->offImage + pSect[-1].size;
    1415                                     /* more checks? */
    1416                                     if (fOk)
    1417                                         pSeg[-1].cbFile = (KLDRFOFF)(pSect->addr - pSeg[-1].LinkAddress) + pSect->size;
    1418                                     else
    1419                                     {
    1420 
    1421                                         pSeg[-1].cbFile = pSeg[-1].offFile = -1;
    1422                                         pModMachO->fMapUsingLoadCommandSections = K_TRUE;
    1423                                     }
    1424                                 }
    1425                                 pSeg[-1].cb = pSect->addr - pSeg[-1].LinkAddress + pSect->size;
    1426 
    1427                                 /** @todo update the protection... */
    1428                             }
    1429                             pSectExtra++;
    1430                             break;
    1431                         }
    1432 
    1433                         default:
    1434                             return KERR_INVALID_PARAMETER;
    1435                     }
    1436 
    1437                     /* next */
    1438                     pSect++;
    1439                 }
     1174                const segment_command_64_t *pSrcSeg = (const segment_command_64_t *)u.pLoadCmd;
     1175                section_64_t   *pFirstSect    = (section_64_t *)(pSrcSeg + 1);
     1176                section_64_t   *pSect         = pFirstSect;
     1177                KU32            cSectionsLeft = pSrcSeg->nsects;
     1178
     1179                ADD_SEGMENT_AND_ITS_SECTIONS(64);
    14401180                break;
    14411181            }
     
    14661206    } /* while more commands */
    14671207
    1468     /*
    1469      * Close the last segment (if any).
    1470      */
    1471     if (pSegExtra != &pModMachO->aSegments[0])
    1472         pSegExtra[-1].cSections = pSectExtra - pSegExtra[-1].paSections;
    1473 
    1474     /*
    1475      * Make sure the segments are sorted, or we'll get screwed further down.
    1476      */
    1477     c = pSeg - &pModMachO->pMod->aSegments[0];
    1478     pSeg = &pModMachO->pMod->aSegments[0];
    1479     for (i = 0; i < c - 1; i++)
    1480     {
    1481         KLDRADDR LinkAddress = pSeg[i + 1].LinkAddress;
    1482         if (LinkAddress < pSeg[i].LinkAddress)
    1483         {
    1484             /* Gotta move the next segment, find the correct location. */
    1485             KLDRMODMACHOSEG TmpSegExtra;
    1486             KLDRSEG TmpSeg;
    1487             KU32 j = i;
    1488             KU32 cShift = 1;
    1489 
    1490             while (j > 0 && LinkAddress < pSeg[j - 1].LinkAddress)
    1491                 j--, cShift++;
    1492 
    1493             TmpSegExtra = pModMachO->aSegments[i + 1];
    1494             kHlpMemMove(&pModMachO->aSegments[j + 1], &pModMachO->aSegments[j],
    1495                         cShift * sizeof(pModMachO->aSegments[0]));
    1496             pModMachO->aSegments[j] = TmpSegExtra;
    1497 
    1498             TmpSeg = pSeg[i + 1];
    1499             kHlpMemMove(&pSeg[j + 1], &pSeg[j], cShift * sizeof(pSeg[0]));
    1500             pSeg[j] = TmpSeg;
    1501         }
    1502     }
    1503     pSeg = &pModMachO->pMod->aSegments[c];
     1208    kHlpAssert(pDstSeg == &pModMachO->pMod->aSegments[cSegments - pModMachO->fMakeGot]);
     1209
     1210#if 0
     1211    {
     1212        /*
     1213         * Make sure the segments are sorted by link address, or we'll get screwed
     1214         * further down.
     1215         */
     1216        KLDRADDR cb1;
     1217        KSIZE cb2;
     1218        KU32 i;
     1219        KU32 c = pDstSeg - &pModMachO->pMod->aSegments[0];
     1220
     1221        pDstSeg = &pModMachO->pMod->aSegments[0];
     1222        for (i = 0; i < c - 1; i++)
     1223        {
     1224            KLDRADDR LinkAddress = pDstSeg[i + 1].LinkAddress;
     1225            if (LinkAddress < pDstSeg[i].LinkAddress)
     1226            {
     1227                /* Gotta move the next segment, find the correct location. */
     1228                KLDRMODMACHOSEG TmpSegExtra;
     1229                KLDRSEG TmpSeg;
     1230                KU32 j = i;
     1231                KU32 cShift = 1;
     1232
     1233                while (j > 0 && LinkAddress < pDstSeg[j - 1].LinkAddress)
     1234                    j--, cShift++;
     1235
     1236                TmpSegExtra = pModMachO->aSegments[i + 1];
     1237                kHlpMemMove(&pModMachO->aSegments[j + 1], &pModMachO->aSegments[j],
     1238                            cShift * sizeof(pModMachO->aSegments[0]));
     1239                pModMachO->aSegments[j] = TmpSegExtra;
     1240
     1241                TmpSeg = pDstSeg[i + 1];
     1242                kHlpMemMove(&pDstSeg[j + 1], &pDstSeg[j], cShift * sizeof(pDstSeg[0]));
     1243                pDstSeg[j] = TmpSeg;
     1244            }
     1245        }
     1246
     1247        /*
     1248         * Adjust mapping addresses calculating the image size.
     1249         */
     1250        pDstSeg = &pModMachO->pMod->aSegments[0];
     1251        for (i = 0; i < cSegments - 1; i++)
     1252        {
     1253            cb1 = pDstSeg[i + 1].LinkAddress - pDstSeg[i].LinkAddress;
     1254            cb2 = (KSIZE)cb1;
     1255            pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
     1256        }
     1257        cb1 = KLDR_ALIGN_ADDR(pDstSeg[i].cb, pDstSeg[i].Alignment);
     1258        cb2 = (KSIZE)cb1;
     1259        pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
     1260
     1261        pModMachO->cbImage = pDstSeg[i].RVA + cb1;
     1262    }
     1263#else
     1264    /*
     1265     * Adjust mapping addresses calculating the image size.
     1266     */
     1267    {
     1268        KLDRADDR uNextRVA = 0;
     1269        KLDRADDR cb;
     1270        KU32     c;
     1271
     1272        /* Adjust RVAs. */
     1273        c = cSegments - pModMachO->fMakeGot;
     1274        for (pDstSeg = &pModMachO->pMod->aSegments[0]; c-- > 0; pDstSeg++)
     1275        {
     1276            cb = pDstSeg->RVA - uNextRVA;
     1277            if (cb >= 0x00100000) /* 1MB */
     1278            {
     1279                pDstSeg->RVA = uNextRVA;
     1280                pModMachO->pMod->fFlags |= KLDRMOD_FLAGS_NON_CONTIGUOUS_LINK_ADDRS;
     1281            }
     1282            uNextRVA = pDstSeg->RVA + KLDR_ALIGN_ADDR(pDstSeg->cb, pDstSeg->Alignment);
     1283        }
     1284
     1285        /* Calculate the cbMapping members. */
     1286        c = cSegments - pModMachO->fMakeGot;
     1287        for (pDstSeg = &pModMachO->pMod->aSegments[0]; c-- > 1; pDstSeg++)
     1288        {
     1289            cb = pDstSeg[1].RVA - pDstSeg->RVA;
     1290            pDstSeg->cbMapped = (KSIZE)cb == cb ? cb : KSIZE_MAX;
     1291        }
     1292
     1293        cb = KLDR_ALIGN_ADDR(pDstSeg->cb, pDstSeg->Alignment);
     1294        pDstSeg->cbMapped = (KSIZE)cb == cb ? (KSIZE)cb : KSIZE_MAX;
     1295
     1296        /* And finally, the image size. */
     1297        pModMachO->cbImage = pDstSeg->RVA + cb;
     1298    }
     1299#endif
     1300
    15041301
    15051302    /*
     
    15151312        KU32 cbJmpStubs;
    15161313
    1517         if (pSeg != &pModMachO->pMod->aSegments[0])
    1518             pModMachO->GotRVA = pSeg[-1].RVA + KLDR_ALIGN_ADDR(pSeg[-1].cb, pSeg[-1].Alignment);
    1519         else
    1520             pModMachO->GotRVA = 0;
     1314        pModMachO->GotRVA = pModMachO->cbImage;
    15211315
    15221316        if (pModMachO->cbJmpStub)
     
    15321326        }
    15331327
    1534         pSeg->pvUser = NULL;
    1535         pSeg->pchName = "GOT";
    1536         pSeg->cchName = 3;
    1537         pSeg->SelFlat = 0;
    1538         pSeg->Sel16bit = 0;
    1539         pSeg->fFlags = 0;
    1540         pSeg->enmProt = KPROT_READONLY;
    1541         pSeg->cb = cbGot + cbJmpStubs;
    1542         pSeg->Alignment = 64;
    1543         pSeg->LinkAddress = pModMachO->LinkAddress + pModMachO->GotRVA;
    1544         pSeg->offFile = -1;
    1545         pSeg->cbFile  = -1;
    1546         pSeg->RVA = pModMachO->GotRVA;
    1547         pSeg->cbMapped = 0;
    1548         pSeg->MapAddress = 0;
     1328        pDstSeg = &pModMachO->pMod->aSegments[cSegments - 1];
     1329        pDstSeg->pvUser = NULL;
     1330        pDstSeg->pchName = "GOT";
     1331        pDstSeg->cchName = 3;
     1332        pDstSeg->SelFlat = 0;
     1333        pDstSeg->Sel16bit = 0;
     1334        pDstSeg->fFlags = 0;
     1335        pDstSeg->enmProt = KPROT_READONLY;
     1336        pDstSeg->cb = cbGot + cbJmpStubs;
     1337        pDstSeg->Alignment = 64;
     1338        pDstSeg->LinkAddress = pModMachO->LinkAddress + pModMachO->GotRVA;
     1339        pDstSeg->offFile = -1;
     1340        pDstSeg->cbFile  = -1;
     1341        pDstSeg->RVA = pModMachO->GotRVA;
     1342        pDstSeg->cbMapped = KLDR_ALIGN_ADDR(cbGot + cbJmpStubs, pDstSeg->Alignment);
     1343        pDstSeg->MapAddress = 0;
    15491344
    15501345        pSegExtra->iOrgSegNo = KU32_MAX;
    15511346        pSegExtra->cSections = 0;
    15521347        pSegExtra->paSections = NULL;
    1553     }
    1554 
    1555     /*
    1556      * Adjust mapping addresses calculating the image size.
    1557      */
    1558     pSeg = &pModMachO->pMod->aSegments[0];
    1559     switch (pModMachO->Hdr.filetype)
    1560     {
    1561         case MH_OBJECT:
    1562         case MH_EXECUTE:
    1563         case MH_DYLIB: /** @todo dylib */
    1564         case MH_DSYM:
    1565         case MH_KEXT_BUNDLE:
    1566         {
    1567             KLDRADDR cb1;
    1568             KSIZE cb2;
    1569 
    1570             for (i = 0; i < cSegments - 1; i++)
    1571             {
    1572                 cb1 = pSeg[i + 1].LinkAddress - pSeg[i].LinkAddress;
    1573                 cb2 = (KSIZE)cb1;
    1574                 pSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
    1575             }
    1576             cb1 = KLDR_ALIGN_ADDR(pSeg[i].cb, pSeg[i].Alignment);
    1577             cb2 = (KSIZE)cb1;
    1578             pSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
    1579 
    1580             pModMachO->cbImage = pSeg[i].RVA + cb1;
    1581             break;
    1582         }
    1583     }
    1584 
     1348
     1349        pModMachO->cbImage += pDstSeg->cbMapped;
     1350    }
    15851351
    15861352    return 0;
  • trunk/kLdr/kLdrModNative.c

    r54 r58  
    322322    pMod->pszName = kHlpGetFilename(pMod->pszFilename); /** @todo get soname */
    323323    pMod->cchName = cchFilename - (pMod->pszName - pMod->pszFilename);
     324    pMod->fFlags = 0;
    324325#if defined(__i386__) || defined(__X86__) || defined(_M_IX86)
    325326    pMod->enmCpu = KCPU_I386;
  • trunk/kLdr/kLdrModPE.c

    r54 r58  
    234234    pMod->pszName = kHlpGetFilename(pMod->pszFilename);
    235235    pMod->cchName = cchFilename - (pMod->pszName - pMod->pszFilename);
     236    pMod->fFlags = 0;
    236237    switch (s.FileHdr.Machine)
    237238    {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette