Changeset 2962 for trunk


Ignore:
Timestamp:
Feb 11, 2007, 6:55:04 PM (19 years ago)
Author:
bird
Message:

Symbol enum and querying works.

Location:
trunk/kLdr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdr.h

    r2961 r2962  
    650650/** Request a segmented symbol address. */
    651651#define KLDRSYMKIND_REQ_SEGMENTED           0x40000000
     652/** Request type mask. */
     653#define KLDRSYMKIND_REQ_TYPE_MASK           0x40000000
    652654/** @} */
    653655
  • trunk/kLdr/kLdrModMachO.c

    r2961 r2962  
    7474     * This is -1 if the section doesn't have any fixups. */
    7575    off_t                   offFixups;
     76    /** Mach-O section flags. */
     77    uint32_t                fFlags;
     78    /** kLdr segment index. */
     79    uint32_t                iSegment;
    7680    /** Pointer to the Mach-O section structure. */
    77     void                   *pvMachoSection;
    78                                      
     81    void                   *pvMachoSection;                                     
    7982} KLDRMODMACHOSECT, *PKLDRMODMACHOSECT;
    8083
     
    103106    /** Pointer to the module. (Follows the section table.) */
    104107    PKLDRMOD                pMod;
    105     /** Pointer to the RDR mapping of the raw file bits. NULL if not mapped. */
     108    /** Pointer to the RDR file mapping of the raw file bits. NULL if not mapped. */
    106109    const void             *pvBits;
    107110    /** Pointer to the user mapping. */
    108     const void             *pvMapping;
     111    void                   *pvMapping;
    109112
    110113    /** The link address. */
     
    131134    off_t                   offStrings;
    132135    /** The size of the of the string table. */
    133     uint32_t                cbStrings;
     136    uint32_t                cchStrings;
    134137    /** Pointer to the loaded string table. */
    135138    char                   *pchStrings;
     139
     140    /** The number of sections. */
     141    uint32_t                cSections;
     142    /** Pointer to the section array running in parallel to the Mach-O one. */
     143    PKLDRMODMACHOSECT       paSections;
     144
    136145    /** Array of segments parallel to the one in KLDRMOD. */
    137146    KLDRMODMACHOSEG         aSegments[1];
     
    153162                                             uint32_t *pcSegments, uint32_t *pcSections, uint32_t *pcbStringPool);
    154163static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool);
     164static int  kldrModMachOAdjustBaseAddress(PKLDRMODMACHO pModMachO, PKLDRADDR pBaseAddress);
     165
    155166/*static int  kldrModMachOLoadLoadCommands(PKLDRMODMACHO pModMachO);*/
    156167static int  kldrModMachOLoadObjSymTab(PKLDRMODMACHO pModMachO);
    157168static int  kldrModMachOLoadFixups(PKLDRMODMACHO pModMachO, off_t offFixups, uint32_t cFixups, void **pvFixups);
    158169
     170static int  kldrModMachODoQuerySymbol32Bit(PKLDRMODMACHO pModMachO, const macho_nlist_32_t *paSyms, uint32_t cSyms, const char *pchStrings,
     171                                           uint32_t cchStrings, KLDRADDR BaseAddress, uint32_t iSymbol, const char *pchSymbol,
     172                                           size_t cchSymbol, PKLDRADDR puValue, uint32_t *pfKind);
     173static int  kldrModMachODoEnumSymbols32Bit(PKLDRMODMACHO pModMachO, const macho_nlist_32_t *paSyms, uint32_t cSyms,
     174                                           const char *pchStrings, uint32_t cchStrings, KLDRADDR BaseAddress,
     175                                           uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser);
    159176static int  kldrModMachOObjDoImports(PKLDRMODMACHO pModMachO, PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    160177static int  kldrModMachOObjDoFixups(PKLDRMODMACHO pModMachO, void *pvMapping, KLDRADDR NewBaseAddress);
     
    376393    pModMachO->pvaSymbols = NULL;
    377394    pModMachO->offStrings = 0;
    378     pModMachO->cbStrings = 0;
     395    pModMachO->cchStrings = 0;
    379396    pModMachO->pchStrings = NULL;
     397    pModMachO->cSections = cSections;
     398    pModMachO->paSections = (PKLDRMODMACHOSECT)&pModMachO->aSegments[pModMachO->pMod->cSegments];
    380399
    381400    /*
     
    778797    PKLDRSEG pSeg = &pModMachO->pMod->aSegments[0];
    779798    PKLDRMODMACHOSEG pSegExtra = &pModMachO->aSegments[0];
    780     PKLDRMODMACHOSECT pSectExtra = (PKLDRMODMACHOSECT)&pModMachO->aSegments[pModMachO->pMod->cSegments];
     799    PKLDRMODMACHOSECT pSectExtra = pModMachO->paSections;
    781800    const uint32_t cSegments = pModMachO->pMod->cSegments;
    782801    uint32_t i;
     
    812831                        case MH_OBJECT:
    813832                        {
    814                             /* Don't load debug symbols. (test this) */
     833                            /* Section data extract. */
     834                            pSectExtra->cb = pSect->size;
     835                            pSectExtra->RVA = pSect->addr;
     836                            pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
     837                            pSectExtra->cFixups = pSect->nreloc;
     838                            pSectExtra->paFixups = NULL;
     839                            pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
     840                            pSectExtra->fFlags = pSect->flags;
     841                            pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
     842                            pSectExtra->pvMachoSection = pSect;
     843
     844                            /* Don't load debug symbols. (test this!) */
    815845                            if (pSect->flags & S_ATTR_DEBUG)
    816846                                break;
     
    820850                            {
    821851                                /* close the previous segment */
    822                                 if (pSegExtra != &pModMachO->aSegments[1])
     852                                if (pSegExtra != &pModMachO->aSegments[0])
    823853                                    pSegExtra[-1].cSections = pSectExtra - pSegExtra[-1].paSections;
    824854
     
    880910                                /** @todo update the protection... */
    881911                            }
    882 
    883                             /* Section info. */
    884                             pSectExtra->cb = pSect->size;
    885                             pSectExtra->RVA = pSect->addr;
    886                             pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
    887                             pSectExtra->cFixups = pSect->nreloc;
    888                             pSectExtra->paFixups = NULL;
    889                             pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
    890                             pSectExtra->pvMachoSection = pSect;
    891912                            pSectExtra++;
    892913                            break;
     
    910931                        pModMachO->cSymbols = u.pSymTab->nsyms;
    911932                        pModMachO->offStrings = u.pSymTab->stroff;
    912                         pModMachO->cbStrings = u.pSymTab->strsize;
     933                        pModMachO->cchStrings = u.pSymTab->strsize;
    913934                        break;
    914935                }
     
    9941015
    9951016/**
    996  * Performs the mapping of the image.
    997  *
    998  * This can be used to do the internal mapping as well as the
    999  * user requested mapping. fForReal indicates which is desired.
    1000  *
    1001  * @returns 0 on success, non-zero OS or kLdr status code on failure.
    1002  * @param   pModMachO          The interpreter module instance
    1003  * @param   fForReal        If set, do the user mapping. if clear, do the internal mapping.
    1004  */
    1005 static int kldrModMachODoMap(PKLDRMODMACHO pModMachO, unsigned fForReal)
    1006 {
    1007 #if 0
    1008     PKLDRMOD    pMod = pModMachO->pMod;
    1009     unsigned    fFixed;
    1010     void       *pvBase;
    1011     int         rc;
    1012     uint32_t    i;
    1013 
    1014     /*
    1015      * Map it.
    1016      */
    1017     /* fixed image? */
    1018     fFixed = fForReal
    1019           && (   pMod->enmType == KLDRTYPE_EXECUTABLE_FIXED
    1020               || pMod->enmType == KLDRTYPE_SHARED_LIBRARY_FIXED);
    1021     if (!fFixed)
    1022         pvBase = NULL;
    1023     else
    1024     {
    1025         pvBase = (void *)(uintptr_t)pMod->aSegments[0].LinkAddress;
    1026         if ((uintptr_t)pvBase != pMod->aSegments[0].LinkAddress)
    1027             return KLDR_ERR_ADDRESS_OVERFLOW;
    1028     }
    1029 
    1030     /* try do the prepare */
    1031     rc = kLdrRdrMap(pMod->pRdr, &pvBase, pMod->cSegments, pMod->aSegments, fFixed);
    1032     if (rc)
    1033         return rc;
    1034 
    1035     /*
    1036      * Update the segments with their map addresses.
    1037      */
    1038     if (fForReal)
    1039     {
    1040         for (i = 0; i < pMod->cSegments; i++)
    1041         {
    1042             if (pMod->aSegments[i].RVA != NIL_KLDRADDR)
    1043                 pMod->aSegments[i].MapAddress = (uintptr_t)pvBase + (uintptr_t)pMod->aSegments[i].RVA;
    1044         }
    1045         pModMachO->pvMapping = pvBase;
    1046     }
    1047     else
    1048         pModMachO->pvBits = pvBase;
    1049 #endif
    1050     return 0;
    1051 }
    1052 
    1053 
    1054 /**
    1055  * Unmaps a image mapping.
    1056  *
    1057  * This can be used to do the internal mapping as well as the
    1058  * user requested mapping. fForReal indicates which is desired.
    1059  *
    1060  * @returns 0 on success, non-zero OS or kLdr status code on failure.
    1061  * @param   pModMachO          The interpreter module instance
    1062  * @param   pvMapping       The mapping to unmap.
    1063  */
    1064 static int kldrModMachODoUnmap(PKLDRMODMACHO pModMachO, const void *pvMapping)
    1065 {
    1066 #if 0
    1067     PKLDRMOD    pMod = pModMachO->pMod;
    1068     int         rc;
    1069     uint32_t    i;
    1070 
    1071     /*
    1072      * Try unmap the image.
    1073      */
    1074     rc = kLdrRdrUnmap(pMod->pRdr, (void *)pvMapping, pMod->cSegments, pMod->aSegments);
    1075     if (rc)
    1076         return rc;
    1077 
    1078     /*
    1079      * Update the segments to reflect that they aren't mapped any longer.
    1080      */
    1081     if (pModMachO->pvMapping == pvMapping)
    1082     {
    1083         pModMachO->pvMapping = NULL;
    1084         for (i = 0; i < pMod->cSegments; i++)
    1085             pMod->aSegments[i].MapAddress = 0;
    1086     }
    1087     if (pModMachO->pvBits == pvMapping)
    1088         pModMachO->pvBits = NULL;
    1089 #endif
    1090 
    1091     return 0;
    1092 }
    1093 
    1094 
    1095 /**
    1096  * Gets usable bits and the right base address.
     1017 * Gets the right base address.
    10971018 *
    10981019 * @returns 0 on success.
    1099  * @returns A non-zero status code if the BaseAddress isn't right or some problem is encountered
    1100  *          featch in a temp mapping the bits.
    1101  * @param   pModMachO          The interpreter module instance
    1102  * @param   ppvBits         The bits address, IN & OUT.
     1020 * @returns A non-zero status code if the BaseAddress isn't right.
     1021 * @param   pModMachO       The interpreter module instance
    11031022 * @param   pBaseAddress    The base address, IN & OUT. Optional.
    11041023 */
    1105 static int kldrModMachOBitsAndBaseAddress(PKLDRMODMACHO pModMachO, const void **ppvBits, PKLDRADDR pBaseAddress)
    1106 {
    1107     int rc = 0;
    1108 
    1109     /*
    1110      * Correct the base address.
    1111      *
    1112      * We don't use the base address for interpreting the bits in this
    1113      * interpreter, which makes things relativly simple.
    1114      */
    1115     if (pBaseAddress)
    1116     {
    1117         if (*pBaseAddress == KLDRMOD_BASEADDRESS_MAP)
    1118             *pBaseAddress = pModMachO->pMod->aSegments[0].MapAddress;
    1119         else if (*pBaseAddress == KLDRMOD_BASEADDRESS_LINK)
    1120             *pBaseAddress = pModMachO->LinkAddress;
    1121     }
    1122 
    1123     /*
    1124      * Get bits.
    1125      */
    1126     if (ppvBits && !*ppvBits)
    1127     {
    1128         if (pModMachO->pvMapping)
    1129             *ppvBits = pModMachO->pvMapping;
    1130         else if (pModMachO->pvBits)
    1131             *ppvBits = pModMachO->pvBits;
    1132         else
    1133         {
    1134             /* create an internal mapping. */
    1135             rc = kldrModMachODoMap(pModMachO, 0 /* not for real */);
    1136             if (rc)
    1137                 return rc;
    1138             KLDRMODMACHO_ASSERT(pModMachO->pvBits);
    1139             *ppvBits = pModMachO->pvBits;
    1140         }
    1141     }
     1024static int kldrModMachOAdjustBaseAddress(PKLDRMODMACHO pModMachO, PKLDRADDR pBaseAddress)
     1025{
     1026    /*
     1027     * Adjust the base address.
     1028     */
     1029    if (*pBaseAddress == KLDRMOD_BASEADDRESS_MAP)
     1030        *pBaseAddress = pModMachO->pMod->aSegments[0].MapAddress;
     1031    else if (*pBaseAddress == KLDRMOD_BASEADDRESS_LINK)
     1032        *pBaseAddress = pModMachO->LinkAddress;
    11421033
    11431034    return 0;
    11441035}
     1036
    11451037
    11461038
     
    11491041                                   const char *pchSymbol, size_t cchSymbol, const char *pszVersion,
    11501042                                   PFNKLDRMODGETIMPORT pfnGetForwarder, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind)
    1151 
    1152 {
    1153 #if 0
    1154     PKLDRMODMACHO                      pModMachO = (PKLDRMODMACHO)pMod->pvData;
    1155     const uint32_t                 *paExportRVAs;
    1156     const IMAGE_EXPORT_DIRECTORY   *pExpDir;
    1157     uint32_t                        iExpOrd;
    1158     uint32_t                        uRVA;
    1159     int                             rc;
    1160 
    1161     /*
    1162      * Make sure we've got mapped bits and resolve any base address aliases.
    1163      */
    1164     rc = kldrModMachOBitsAndBaseAddress(pModMachO, &pvBits, &BaseAddress);
     1043{
     1044    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
     1045    int rc;
     1046
     1047    /*
     1048     * Resolve defaults.
     1049     */
     1050    rc  = kldrModMachOAdjustBaseAddress(pModMachO, &BaseAddress);
    11651051    if (rc)
    11661052        return rc;
    1167     if (    pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
    1168         <   sizeof(IMAGE_EXPORT_DIRECTORY))
    1169         return KLDR_ERR_SYMBOL_NOT_FOUND;
    1170     if (pszVersion && *pszVersion)
    1171         return KLDR_ERR_SYMBOL_NOT_FOUND;
    1172 
    1173     pExpDir = KLDRMODMACHO_RVA2TYPE(pvBits,
    1174                                  pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
    1175                                  PIMAGE_EXPORT_DIRECTORY);
    1176     if (!pchSymbol)
    1177     {
    1178         /*
    1179          * Simple, calculate the unbased ordinal and bounds check it.
     1053
     1054    /*
     1055     * Refuse segmented requests for now.
     1056     */
     1057    if (    pfKind
     1058        &&  (*pfKind & KLDRSYMKIND_REQ_TYPE_MASK) != KLDRSYMKIND_REQ_FLAT)
     1059        return KLDR_ERR_TODO;
     1060
     1061    /*
     1062     * Take action according to file type.
     1063     */
     1064    if (pModMachO->Hdr.filetype == MH_OBJECT)
     1065    {
     1066        rc = kldrModMachOLoadObjSymTab(pModMachO);
     1067        if (!rc)
     1068        {
     1069            if (    pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE
     1070                ||  pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE_OE)
     1071                rc = kldrModMachODoQuerySymbol32Bit(pModMachO, (macho_nlist_32_t *)pModMachO->pvaSymbols, pModMachO->cSymbols,
     1072                                                    pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress, iSymbol, pchSymbol,
     1073                                                    cchSymbol, puValue, pfKind);
     1074            else
     1075                rc = KLDR_ERR_TODO; /** @todo duplicate kldrModMachOQuerySymbol32 for parsing 64-bit symbols when everything is working. */
     1076                /*rc = kldrModMachODoQuerySymbol64Bit(pModMachO, (macho_nlist_64_t *)pModMachO->pvaSymbols, pModMachO->cSymbols,
     1077                                                    pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress, iSymbol, pchSymbol,
     1078                                                    cchSymbol, puValue, pfKind);*/
     1079
     1080        }
     1081    }
     1082    else
     1083        rc = KLDR_ERR_TODO;
     1084
     1085    return rc;
     1086}
     1087
     1088
     1089
     1090/**
     1091 * Lookup a symbol in a 32-bit symbol table.
     1092 *
     1093 * @returns See kLdrModQuerySymbol.
     1094 * @param   pModMachO   
     1095 * @param   paSyms      Pointer to the symbol table.
     1096 * @param   cSyms       Number of symbols in the table.
     1097 * @param   pchStrings  Pointer to the string table.
     1098 * @param   cchStrings  Size of the string table.
     1099 * @param   BaseAddress Adjusted base address, see kLdrModQuerySymbol.
     1100 * @param   iSymbol     See kLdrModQuerySymbol.
     1101 * @param   pchSymbol   See kLdrModQuerySymbol.
     1102 * @param   cchSymbol   See kLdrModQuerySymbol.
     1103 * @param   puValue     See kLdrModQuerySymbol.
     1104 * @param   pfKind      See kLdrModQuerySymbol.
     1105 */
     1106static int kldrModMachODoQuerySymbol32Bit(PKLDRMODMACHO pModMachO, const macho_nlist_32_t *paSyms, uint32_t cSyms, const char *pchStrings,
     1107                                          uint32_t cchStrings, KLDRADDR BaseAddress, uint32_t iSymbol, const char *pchSymbol, size_t cchSymbol,
     1108                                          PKLDRADDR puValue, uint32_t *pfKind)
     1109{
     1110    /*
     1111     * Find a valid symbol matching the search criteria.
     1112     */
     1113    if (iSymbol == NIL_KLDRMOD_SYM_ORDINAL)
     1114    {
     1115        /* simplify validation. */
     1116        if (cchStrings <= cchSymbol)
     1117            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1118        cchStrings -= cchSymbol;
     1119
     1120        for (iSymbol = 0; iSymbol < cSyms; iSymbol++)
     1121        {
     1122            const char *psz;
     1123
     1124            /* Skip irrellevant and non-public symbols. */
     1125            if (paSyms[iSymbol].n_type & MACHO_N_STAB)
     1126                continue;
     1127            if ((paSyms[iSymbol].n_type & MACHO_N_TYPE) == MACHO_N_UNDF)
     1128                continue;
     1129            if (!(paSyms[iSymbol].n_type & MACHO_N_EXT)) /*??*/
     1130                continue;
     1131            if (paSyms[iSymbol].n_type & MACHO_N_PEXT) /*??*/
     1132                continue;
     1133           
     1134            /* get name */
     1135            if (!paSyms[iSymbol].n_un.n_strx)
     1136                continue;
     1137            if ((uint32_t)paSyms[iSymbol].n_un.n_strx >= cchStrings)
     1138                continue;
     1139            psz = &pchStrings[paSyms[iSymbol].n_un.n_strx];
     1140            if (psz[cchSymbol])
     1141                continue;
     1142            if (kLdrHlpMemComp(psz, pchSymbol, cchSymbol))
     1143                continue;
     1144
     1145            /* match! */
     1146            break;
     1147        }
     1148        if (iSymbol >= cSyms)
     1149            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1150    }
     1151    else
     1152    {
     1153        if (iSymbol >= cSyms)
     1154            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1155        if (paSyms[iSymbol].n_type & MACHO_N_STAB)
     1156            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1157        if ((paSyms[iSymbol].n_type & MACHO_N_TYPE) == MACHO_N_UNDF)
     1158            return KLDR_ERR_SYMBOL_NOT_FOUND;
     1159    }
     1160
     1161    /*
     1162     * Calc the return values.
     1163     */
     1164    if (pfKind)
     1165    {
     1166        if (    pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE
     1167            ||  pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE_OE)
     1168            *pfKind = KLDRSYMKIND_32BIT | KLDRSYMKIND_NO_TYPE;
     1169        else
     1170            *pfKind = KLDRSYMKIND_64BIT | KLDRSYMKIND_NO_TYPE;
     1171        if (paSyms[iSymbol].n_desc & N_WEAK_DEF)
     1172            *pfKind |= KLDRSYMKIND_WEAK;
     1173    }
     1174
     1175    switch (paSyms[iSymbol].n_type & MACHO_N_TYPE)
     1176    {
     1177        case MACHO_N_SECT:
     1178        {
     1179            PKLDRMODMACHOSECT pSect;
     1180            KLDRADDR RVA;
     1181            if ((uint32_t)(paSyms[iSymbol].n_sect - 1) >= pModMachO->cSections)
     1182                return KLDR_ERR_MACHO_BAD_SYMBOL;
     1183            pSect = &pModMachO->paSections[paSyms[iSymbol].n_sect - 1];
     1184
     1185            RVA = paSyms[iSymbol].n_value - pModMachO->LinkAddress;
     1186            if (RVA - pSect->RVA >= pSect->cb)
     1187                return KLDR_ERR_MACHO_BAD_SYMBOL;
     1188            if (puValue)
     1189                *puValue = RVA + BaseAddress;
     1190
     1191            if (    pfKind
     1192                &&  (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE)))
     1193                *pfKind = (*pfKind & ~KLDRSYMKIND_TYPE_MASK) | KLDRSYMKIND_CODE;
     1194            break;
     1195        }
     1196
     1197        case MACHO_N_ABS:
     1198            if (puValue)
     1199                *puValue = paSyms[iSymbol].n_value;
     1200            /*if (pfKind)
     1201                pfKind |= KLDRSYMKIND_ABS;*/
     1202            break;
     1203
     1204        case MACHO_N_PBUD:
     1205        case MACHO_N_INDR:
     1206            /** @todo implement indirect and prebound symbols. */
     1207        default:
     1208            KLDRMODMACHO_ASSERT(0);
     1209            return KLDR_ERR_TODO;
     1210    }
     1211
     1212    return 0;
     1213}
     1214
     1215
     1216/** @copydoc kLdrModEnumSymbols */
     1217static int kldrModMachOEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
     1218                                   uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
     1219{
     1220    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
     1221    int rc;
     1222
     1223    /*
     1224     * Resolve defaults.
     1225     */
     1226    rc  = kldrModMachOAdjustBaseAddress(pModMachO, &BaseAddress);
     1227    if (rc)
     1228        return rc;
     1229
     1230    /*
     1231     * Take action according to file type.
     1232     */
     1233    if (pModMachO->Hdr.filetype == MH_OBJECT)
     1234    {
     1235        rc = kldrModMachOLoadObjSymTab(pModMachO);
     1236        if (!rc)
     1237        {
     1238            if (    pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE
     1239                ||  pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE_OE)
     1240                rc = kldrModMachODoEnumSymbols32Bit(pModMachO, (macho_nlist_32_t *)pModMachO->pvaSymbols, pModMachO->cSymbols,
     1241                                                    pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress,
     1242                                                    fFlags, pfnCallback, pvUser);
     1243            else
     1244                rc = KLDR_ERR_TODO; /** @todo duplicate kldrModMachOQuerySymbol32 for parsing 64-bit symbols when everything is working. */
     1245                /*rc = kldrModMachODoEnumSymbols32Bit(pModMachO, (macho_nlist_32_t *)pModMachO->pvaSymbols, pModMachO->cSymbols,
     1246                                                    pModMachO->pchStrings, pModMachO->cchStrings, BaseAddress, pfnCallback, pvUser);*/
     1247        }
     1248    }
     1249    else
     1250        rc = KLDR_ERR_TODO;
     1251
     1252    return rc;
     1253}
     1254
     1255
     1256/**
     1257 * Enum a 32-bit symbol table.
     1258 *
     1259 * @returns See kLdrModQuerySymbol.
     1260 * @param   pModMachO   
     1261 * @param   paSyms      Pointer to the symbol table.
     1262 * @param   cSyms       Number of symbols in the table.
     1263 * @param   pchStrings  Pointer to the string table.
     1264 * @param   cchStrings  Size of the string table.
     1265 * @param   BaseAddress Adjusted base address, see kLdrModEnumSymbols.
     1266 * @param   fFlags      See kLdrModEnumSymbols.
     1267 * @param   pfnCallback See kLdrModEnumSymbols.
     1268 * @param   pvUser      See kLdrModEnumSymbols.
     1269 */
     1270static int kldrModMachODoEnumSymbols32Bit(PKLDRMODMACHO pModMachO, const macho_nlist_32_t *paSyms, uint32_t cSyms,
     1271                                          const char *pchStrings, uint32_t cchStrings, KLDRADDR BaseAddress,
     1272                                          uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
     1273{
     1274    const uint32_t fKindBase = pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE
     1275                            || pModMachO->Hdr.magic == IMAGE_MACHO32_SIGNATURE_OE
     1276                             ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT;
     1277    uint32_t iSym;
     1278    int rc;
     1279
     1280    /*
     1281     * Iterate the symbol table.
     1282     */
     1283    for (iSym = 0; iSym < cSyms; iSym++)
     1284    {
     1285        uint32_t fKind;
     1286        KLDRADDR uValue;
     1287        const char *psz;
     1288        size_t cch;
     1289
     1290        /* Skip debug symbols and undefined symbols. */
     1291        if (paSyms[iSym].n_type & MACHO_N_STAB)
     1292            continue;
     1293        if ((paSyms[iSym].n_type & MACHO_N_TYPE) == MACHO_N_UNDF)
     1294            continue;
     1295
     1296        /* Skip non-public symbols unless they are requested explicitly. */
     1297        if (!(fFlags & KLDRMOD_ENUM_SYMS_FLAGS_ALL))
     1298        {
     1299            if (!(paSyms[iSym].n_type & MACHO_N_EXT)) /*??*/
     1300                continue;
     1301            if (paSyms[iSym].n_type & MACHO_N_PEXT) /*??*/
     1302                continue;
     1303            if (!paSyms[iSym].n_un.n_strx)
     1304                continue;
     1305        }
     1306
     1307        /*
     1308         * Gather symbol info
    11801309         */
    1181         iExpOrd = iSymbol - pExpDir->Base;
    1182         if (iExpOrd >= KLDR_MAX(pExpDir->NumberOfNames, pExpDir->NumberOfFunctions))
    1183             return KLDR_ERR_SYMBOL_NOT_FOUND;
    1184     }
    1185     else
    1186     {
    1187         /*
    1188          * Do a binary search for the name.
    1189          * (The name table is sorted in ascending ordered by the linker.)
    1190          */
    1191         const uint32_t *paRVANames = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfNames, const uint32_t *);
    1192         const uint16_t *paOrdinals = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfNameOrdinals, const uint16_t *);
    1193         int32_t         iStart = 1; /* one based binary searching is simpler. */
    1194         int32_t         iEnd = pExpDir->NumberOfNames;
    1195 
    1196         for (;;)
     1310
     1311        /* name */
     1312        if ((uint32_t)paSyms[iSym].n_un.n_strx >= cchStrings)
     1313            return KLDR_ERR_MACHO_BAD_SYMBOL;
     1314        psz = &pchStrings[paSyms[iSym].n_un.n_strx];
     1315        cch = kLdrHlpStrLen(psz);
     1316        if (!cch)
     1317            psz = NULL;
     1318
     1319        /* kind & value */
     1320        fKind = fKindBase;
     1321        if (paSyms[iSym].n_desc & N_WEAK_DEF)
     1322            fKind |= KLDRSYMKIND_WEAK;
     1323        switch (paSyms[iSym].n_type & MACHO_N_TYPE)
    11971324        {
    1198             int32_t     i;
    1199             int         diff;
    1200             const char *pszName;
    1201 
    1202             /* done? */
    1203             if (iStart > iEnd)
     1325            case MACHO_N_SECT:
    12041326            {
    1205 #ifdef KLDRMODMACHO_STRICT /* Make sure the linker and we both did our job right. */
    1206                 for (i = 0; i < (int32_t)pExpDir->NumberOfNames; i++)
    1207 
    1208                 {
    1209                     pszName = KLDRMODMACHO_RVA2TYPE(pvBits, paRVANames[i], const char *);
    1210                     KLDRMODMACHO_ASSERT(kLdrHlpStrNComp(pszName, pchSymbol, cchSymbol) || pszName[cchSymbol]);
    1211                     KLDRMODMACHO_ASSERT(i == 0 || kLdrHlpStrComp(pszName, KLDRMODMACHO_RVA2TYPE(pvBits, paRVANames[i - 1], const char *)));
    1212                 }
    1213 #endif
    1214                 return KLDR_ERR_SYMBOL_NOT_FOUND;
    1215             }
    1216 
    1217             i = (iEnd - iStart) / 2 + iStart;
    1218             pszName = KLDRMODMACHO_RVA2TYPE(pvBits, paRVANames[i - 1], const char *);
    1219             diff = kLdrHlpStrNComp(pszName, pchSymbol, cchSymbol);
    1220             if (!diff)
    1221                 diff = pszName[cchSymbol] - 0;
    1222             if (diff < 0)
    1223                 iStart = i + 1;     /* The symbol must be after the current name. */
    1224             else if (diff)
    1225                 iEnd = i - 1;       /* The symbol must be before the current name. */
    1226             else
    1227             {
    1228                 iExpOrd = paOrdinals[i - 1];    /* match! */
     1327                PKLDRMODMACHOSECT pSect;
     1328                if ((uint32_t)(paSyms[iSym].n_sect - 1) >= pModMachO->cSections)
     1329                    return KLDR_ERR_MACHO_BAD_SYMBOL;
     1330                pSect = &pModMachO->paSections[paSyms[iSym].n_sect - 1];
     1331
     1332                uValue = paSyms[iSym].n_value - pModMachO->LinkAddress;
     1333                if (uValue - pSect->RVA >= pSect->cb)
     1334                    return KLDR_ERR_MACHO_BAD_SYMBOL;
     1335                uValue += BaseAddress;
     1336
     1337                if (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE))
     1338                    fKind |= KLDRSYMKIND_CODE;
     1339                else
     1340                    fKind |= KLDRSYMKIND_NO_TYPE;
    12291341                break;
    12301342            }
     1343
     1344            case MACHO_N_ABS:
     1345                uValue = paSyms[iSym].n_value;
     1346                fKind |= KLDRSYMKIND_NO_TYPE /*KLDRSYMKIND_ABS*/;
     1347                break;
     1348
     1349            case MACHO_N_PBUD:
     1350            case MACHO_N_INDR:
     1351                /** @todo implement indirect and prebound symbols. */
     1352            default:
     1353                KLDRMODMACHO_ASSERT(0);
     1354                return KLDR_ERR_TODO;
    12311355        }
    1232     }
    1233 
    1234     /*
    1235      * Lookup the address in the 'symbol' table.
    1236      */
    1237     paExportRVAs = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfFunctions, const uint32_t *);
    1238     uRVA = paExportRVAs[iExpOrd];
    1239     if (    uRVA - pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
    1240         <   pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
    1241         return kldrModMachODoForwarderQuery(pModMachO, pvBits, KLDRMODMACHO_RVA2TYPE(pvBits, uRVA, const char *),
    1242                                          pfnGetForwarder, pvUser, puValue, pfKind);
    1243 
    1244     /*
    1245      * Set the return value.
    1246      */
    1247     if (puValue)
    1248         *puValue = BaseAddress + uRVA;
    1249     if (pfKind)
    1250         *pfKind = (pModMachO->Hdrs.FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
    1251                    ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
    1252                 | KLDRSYMKIND_NO_TYPE;
    1253 #endif
    1254     return 0;
    1255 }
    1256 
    1257 
    1258 /** @copydoc kLdrModEnumSymbols */
    1259 static int kldrModMachOEnumSymbols(PKLDRMOD pMod, const void *pvBits, KLDRADDR BaseAddress,
    1260                                 uint32_t fFlags, PFNKLDRMODENUMSYMS pfnCallback, void *pvUser)
    1261 {
    1262 #if 0
    1263     PKLDRMODMACHO                      pModMachO = (PKLDRMODMACHO)pMod->pvData;
    1264     const uint32_t                 *paFunctions;
    1265     const IMAGE_EXPORT_DIRECTORY   *pExpDir;
    1266     const uint32_t                 *paRVANames;
    1267     const uint16_t                 *paOrdinals;
    1268     uint32_t                        iFunction;
    1269     uint32_t                        cFunctions;
    1270     uint32_t                        cNames;
    1271     int                             rc;
    1272 
    1273     /*
    1274      * Make sure we've got mapped bits and resolve any base address aliases.
    1275      */
    1276     rc = kldrModMachOBitsAndBaseAddress(pModMachO, &pvBits, &BaseAddress);
    1277     if (rc)
    1278         return rc;
    1279 
    1280     if (    pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size
    1281         <   sizeof(IMAGE_EXPORT_DIRECTORY))
    1282         return 0; /* no exports to enumerate, return success. */
    1283 
    1284     pExpDir = KLDRMODMACHO_RVA2TYPE(pvBits,
    1285                                  pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress,
    1286                                  PIMAGE_EXPORT_DIRECTORY);
    1287 
    1288     /*
    1289      * Enumerate the ordinal exports.
    1290      */
    1291     paRVANames = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfNames, const uint32_t *);
    1292     paOrdinals = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfNameOrdinals, const uint16_t *);
    1293     paFunctions = KLDRMODMACHO_RVA2TYPE(pvBits, pExpDir->AddressOfFunctions, const uint32_t *);
    1294     cFunctions = pExpDir->NumberOfFunctions;
    1295     cNames = pExpDir->NumberOfNames;
    1296     for (iFunction = 0; iFunction < cFunctions; iFunction++)
    1297     {
    1298         unsigned        fFoundName;
    1299         uint32_t        iName;
    1300         const uint32_t  uRVA = paFunctions[iFunction];
    1301         const KLDRADDR  uValue = BaseAddress + uRVA;
    1302         uint32_t        fKind = (pModMachO->Hdrs.FileHeader.SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32)
    1303                               ? KLDRSYMKIND_32BIT : KLDRSYMKIND_64BIT)
    1304                               | KLDRSYMKIND_NO_TYPE;
    1305         if (    uRVA - pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
    1306             <   pModMachO->Hdrs.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
    1307             fKind |= KLDRSYMKIND_FORWARDER;
    13081356
    13091357        /*
    1310          * Any symbol names?
     1358         * Do callback.
    13111359         */
    1312         fFoundName = 0;
    1313         for (iName = 0; iName < cNames; iName++)
    1314         {
    1315             const char *pszName;
    1316             if (paOrdinals[iName] != iFunction)
    1317                 continue;
    1318             fFoundName = 1;
    1319             pszName = KLDRMODMACHO_RVA2TYPE(pvBits, paRVANames[iName], const char *);
    1320             rc = pfnCallback(pMod, iFunction + pExpDir->Base, pszName, kLdrHlpStrLen(pszName), NULL,
    1321                              uValue, fKind, pvUser);
    1322             if (rc)
    1323                 return rc;
    1324         }
    1325 
    1326         /*
    1327          * If no names, call once with the ordinal only.
    1328          */
    1329         if (!fFoundName)
    1330         {
    1331             rc = pfnCallback(pMod, iFunction + pExpDir->Base, NULL, 0, NULL, uValue, fKind, pvUser);
    1332             if (rc)
    1333                 return rc;
    1334         }
    1335     }
    1336 #endif
     1360        rc = pfnCallback(pModMachO->pMod, iSym, psz, cch, NULL, uValue, fKind, pvUser);
     1361        if (rc)
     1362            return rc;
     1363    }
    13371364    return 0;
    13381365}
     
    15021529static int kldrModMachOMap(PKLDRMOD pMod)
    15031530{
    1504     PKLDRMODMACHO  pModMachO = (PKLDRMODMACHO)pMod->pvData;
    1505     int         rc;
     1531    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
     1532    unsigned fFixed;
     1533    uint32_t i;
     1534    void *pvBase;
     1535    int rc;
    15061536
    15071537    /*
     
    15121542
    15131543    /*
    1514      * We've got a common worker which does this.
    1515      */
    1516     rc = kldrModMachODoMap(pModMachO, 1 /* the real thing */);
    1517     if (rc)
    1518         return rc;
    1519     KLDRMODMACHO_ASSERT(pModMachO->pvMapping);
     1544     * Map it.
     1545     */
     1546    /* fixed image? */
     1547    fFixed = pMod->enmType == KLDRTYPE_EXECUTABLE_FIXED
     1548          || pMod->enmType == KLDRTYPE_SHARED_LIBRARY_FIXED;
     1549    if (!fFixed)
     1550        pvBase = NULL;
     1551    else
     1552    {
     1553        pvBase = (void *)(uintptr_t)pMod->aSegments[0].LinkAddress;
     1554        if ((uintptr_t)pvBase != pMod->aSegments[0].LinkAddress)
     1555            return KLDR_ERR_ADDRESS_OVERFLOW;
     1556    }
     1557
     1558    /* try do the prepare */
     1559    if (pModMachO->fMapUsingLoadCommandSections)
     1560        return KLDR_ERR_TODO; /* deal with this if it ever occurs. */
     1561    else
     1562    {
     1563        rc = kLdrRdrMap(pMod->pRdr, &pvBase, pMod->cSegments, pMod->aSegments, fFixed);
     1564        if (rc)
     1565            return rc;
     1566    }
     1567
     1568    /*
     1569     * Update the segments with their map addresses.
     1570     */
     1571    for (i = 0; i < pMod->cSegments; i++)
     1572    {
     1573        if (pMod->aSegments[i].RVA != NIL_KLDRADDR)
     1574            pMod->aSegments[i].MapAddress = (uintptr_t)pvBase + (uintptr_t)pMod->aSegments[i].RVA;
     1575    }
     1576    pModMachO->pvMapping = pvBase;
     1577
    15201578    return 0;
    15211579}
     
    15251583static int kldrModMachOUnmap(PKLDRMOD pMod)
    15261584{
    1527     PKLDRMODMACHO  pModMachO = (PKLDRMODMACHO)pMod->pvData;
    1528     int         rc;
     1585    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
     1586    uint32_t i;
     1587    int rc;
    15291588
    15301589    /*
     
    15351594
    15361595    /*
    1537      * We've got a common worker which does this.
    1538      */
    1539     rc = kldrModMachODoUnmap(pModMachO, pModMachO->pvMapping);
    1540     if (rc)
    1541         return rc;
    1542     KLDRMODMACHO_ASSERT(pModMachO->pvMapping);
     1596     * Try unmap the image.
     1597     */
     1598    if (pModMachO->fMapUsingLoadCommandSections)
     1599        return KLDR_ERR_TODO; /* deal with this if it ever occurs. */
     1600    else
     1601    {
     1602        rc = kLdrRdrUnmap(pMod->pRdr, pModMachO->pvMapping, pMod->cSegments, pMod->aSegments);
     1603        if (rc)
     1604            return rc;
     1605    }
     1606
     1607    /*
     1608     * Update the segments to reflect that they aren't mapped any longer.
     1609     */
     1610    pModMachO->pvMapping = NULL;
     1611    for (i = 0; i < pMod->cSegments; i++)
     1612        pMod->aSegments[i].MapAddress = 0;
     1613
    15431614    return 0;
    1544 
    15451615}
    15461616
     
    15491619static int kldrModMachOAllocTLS(PKLDRMOD pMod)
    15501620{
    1551     PKLDRMODMACHO  pModMachO = (PKLDRMODMACHO)pMod->pvData;
     1621    PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
    15521622
    15531623    /*
     
    15561626    if (!pModMachO->pvMapping)
    15571627        return KLDR_ERR_NOT_MAPPED;
    1558 
    15591628    return 0;
    15601629}
     
    15791648
    15801649    /* the file provider does it all */
    1581     return kLdrRdrRefresh(pMod->pRdr, (void *)pModMachO->pvMapping, pMod->cSegments, pMod->aSegments);
     1650    return kLdrRdrRefresh(pMod->pRdr, pModMachO->pvMapping, pMod->cSegments, pMod->aSegments);
    15821651}
    15831652
     
    15981667     * Before doing anything we'll have to make all pages writable.
    15991668     */
    1600     rc = kLdrRdrProtect(pMod->pRdr, (void *)pModMachO->pvMapping, pMod->cSegments, pMod->aSegments, 1 /* unprotect */);
    1601     if (rc)
    1602         return rc;
    1603 
    1604 #if 0
    1605     /*
    1606      * Apply base relocations.
    1607      */
    1608     rc = kldrModMachODoFixups(pModMachO, (void *)pModMachO->pvMapping, (uintptr_t)pModMachO->pvMapping,
    1609                               pModMachO->Hdrs.OptionalHeader.ImageBase);
    1610 
    1611     /*
    1612      * Resolve imports.
    1613      */
    1614     if (!rc)
    1615         rc = kldrModMachODoImports(pModMachO, (void *)pModMachO->pvMapping, pfnGetImport, pvUser);
    1616 #endif
     1669    if (pModMachO->fMapUsingLoadCommandSections)
     1670        return KLDR_ERR_TODO; /* deal with this if it ever occurs. */
     1671    else
     1672    {
     1673        rc = kLdrRdrProtect(pMod->pRdr, pModMachO->pvMapping, pMod->cSegments, pMod->aSegments, 1 /* unprotect */);
     1674        if (rc)
     1675            return rc;
     1676    }
     1677
     1678    /*
     1679     * Resolve imports and apply base relocations.
     1680     */
     1681    rc = kldrModMachORelocateBits(pMod, pModMachO->pvMapping, (uintptr_t)pModMachO->pvMapping, pModMachO->LinkAddress,
     1682                                  pfnGetImport, pvUser);
    16171683
    16181684    /*
    16191685     * Restore protection.
    16201686     */
    1621     rc2 = kLdrRdrProtect(pMod->pRdr, (void *)pModMachO->pvMapping, pMod->cSegments, pMod->aSegments, 0 /* protect */);
     1687    if (pModMachO->fMapUsingLoadCommandSections)
     1688        rc2 = KLDR_ERR_TODO; /* deal with this if it ever occurs. */
     1689    else
     1690        rc2 = kLdrRdrProtect(pMod->pRdr, pModMachO->pvMapping, pMod->cSegments, pMod->aSegments, 0 /* protect */);
    16221691    if (!rc && rc2)
    16231692        rc = rc2;
     
    16731742
    16741743                /* Get the symbol name and try resolve it. */
    1675                 if ((uint32_t)paSyms[iSym].n_un.n_strx >= pModMachO->cbStrings)
     1744                if ((uint32_t)paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    16761745                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    16771746                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
     
    17211790
    17221791                /* Get the symbol name and try resolve it. */
    1723                 if (paSyms[iSym].n_un.n_strx >= pModMachO->cbStrings)
     1792                if (paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    17241793                    return KLDR_ERR_MACHO_BAD_SYMBOL;
    17251794                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
     
    18601929        /* sanity */
    18611930        if (    !pModMachO->offSymbols
    1862             ||  (pModMachO->cbStrings && !pModMachO->offStrings))
     1931            ||  (pModMachO->cchStrings && !pModMachO->offStrings))
    18631932            return KLDR_ERR_MACHO_BAD_OBJECT_FILE;
    18641933
     
    18751944        if (pvSyms)
    18761945        {
    1877             if (pModMachO->cbStrings)
    1878                 pvStrings = kldrHlpAlloc(pModMachO->cbStrings);
     1946            if (pModMachO->cchStrings)
     1947                pvStrings = kldrHlpAlloc(pModMachO->cchStrings);
    18791948            else
    18801949                pvStrings = kldrHlpAllocZ(4);
     
    18831952                /* read */
    18841953                rc = kLdrRdrRead(pModMachO->pMod->pRdr, pvSyms, cbSyms, pModMachO->offSymbols);
    1885                 if (!rc && pModMachO->cbStrings)
    1886                     rc = kLdrRdrRead(pModMachO->pMod->pRdr, pvStrings, pModMachO->cbStrings, pModMachO->offStrings);
     1954                if (!rc && pModMachO->cchStrings)
     1955                    rc = kLdrRdrRead(pModMachO->pMod->pRdr, pvStrings, pModMachO->cchStrings, pModMachO->offStrings);
    18871956                if (!rc)
    18881957                {
     
    20272096     * If not iterate the load commands and execute the segment / section loads.
    20282097     */
    2029     if (!pModMachO->fMapUsingLoadCommandSections)
     2098    if (pModMachO->fMapUsingLoadCommandSections)
     2099        return KLDR_ERR_TODO; /* deal with this if it ever occurs. */
     2100    else
    20302101    {
    20312102        for (i = 0; i < pMod->cSegments; i++)
     
    20442115                return rc;
    20452116        }
    2046     }
    2047     else
    2048     {
    2049         /** @todo implement this */
    2050         return KLDR_ERR_TODO;
    20512117    }
    20522118
  • trunk/kLdr/kLdrModMachO.h

    r2961 r2962  
    709709#define MACHO_N_EXT     UINT8_C(0x01)   /**< External symbol (when set) (N_EXT). */
    710710#define MACHO_N_TYPE    UINT8_C(0x0e)   /**< Symbol type (N_TYPE without the 8th bit). */
    711 #define MACHO_N_PEXT    UINT8_C(0x10)   /**< Private extern symbol (when set). Mach-O specific. */
     711#define MACHO_N_PEXT    UINT8_C(0x10)   /**< Private extern symbol (when set). (M) */
    712712#define MACHO_N_STAB    UINT8_C(0xe0)   /**< Debug symbol mask (N_STAB). */
    713713
     
    715715#define MACHO_N_UNDF    UINT8_C(0x00)   /**< MACHO_N_TYPE: Undefined symbol (N_UNDF). n_sect = NO_SECT. */
    716716#define MACHO_N_ABS     UINT8_C(0x02)   /**< MACHO_N_TYPE: Absolute symbol (N_UNDF). n_sect = NO_SECT. */
    717 #define MACHO_N_INDR    UINT8_C(0x0a)   /**< MACHO_N_TYPE: Indirect symbol, n_value is the index of the symbol. Mach-O specific. */
    718 #define MACHO_N_PBUD    UINT8_C(0x0c)   /**< MACHO_N_TYPE: Prebound undefined symbo (defined in a dylib). Mach-O specific. */
    719 #define MACHO_N_SECT    UINT8_C(0x0e)   /**< MACHO_N_TYPE: Defined in the section given by n_sects. Mach-O specific. */
     717#define MACHO_N_INDR    UINT8_C(0x0a)   /**< MACHO_N_TYPE: Indirect symbol, n_value is the index of the symbol. (M) */
     718#define MACHO_N_PBUD    UINT8_C(0x0c)   /**< MACHO_N_TYPE: Prebound undefined symbo (defined in a dylib). (M) */
     719#define MACHO_N_SECT    UINT8_C(0x0e)   /**< MACHO_N_TYPE: Defined in the section given by n_sects. (M) */
    720720
    721721/* Debug symbols. */
Note: See TracChangeset for help on using the changeset viewer.