Ignore:
Timestamp:
Sep 18, 2010, 3:06:59 AM (15 years ago)
Author:
bird
Message:

emxomfld/weakld: working on AR and ELF support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/emx/src/emxomf/weakld.c

    r3462 r3667  
    3535 * There is a couple of symbol types, but we can skip most of them for this
    3636 * pre-linking operation. We use one symbol type which is public or global
    37  * symbols if you like. Perhaps it would be wise to devide them into separat
     37 * symbols if you like. Perhaps it would be wise to divide them into separat
    3838 * type groups, but the choice was made to differenciate this using flags.
    3939 * So, symbol enumeration is done using flag masks.
     
    101101#include <sys/omflib.h>
    102102#include <sys/moddef.h>
     103#include <sys/elf.h>
     104#include <ar.h>
    103105#include "defs.h"
    104106#include "grow.h"
     
    155157    const char *pszLibName;
    156158    /** Filehandle if open */
    157     FILE *      phFile;
    158     /** Pointer to extended dictiorary. */
    159     void *      pDict;
    160     /** Library header. */
    161     OMFLIBHDR   LibHdr;
     159    FILE       *phFile;
     160    /** Set if it's a OMF library, clear if it's a unix archive. */
     161    unsigned    fOmfLib;
     162    /** Pointer to the extended dictionary (OMF) / symbol table (AR). */
     163    void       *pDict;
     164    union
     165    {
     166        struct
     167        {
     168            /** Library header. */
     169            OMFLIBHDR   LibHdr;
     170        } Omf;
     171        struct
     172        {
     173            /** Later. */
     174            unsigned    uDummy;
     175        } Ar;
     176    } u;
    162177    /** Linked list next pointer. */
    163     struct wldlib * pNext;
     178    struct wldlib *pNext;
    164179} WLDLIB, *PWLDLIB;
    165180
     
    414429static void         wldIntErr(PWLD pWld, PWLDMOD pMod, const char *pszFile, unsigned iLine, const char *pszFunction);
    415430static unsigned     pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch);
     431static unsigned     pass1ReadELFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch);
    416432/** Parameter structure for wldDefCallback(). */
    417433typedef struct wldDefCallback_param
     
    434450static void         libCloseDict(PWLDLIB pLib);
    435451static int          libTryLoadSymbolThruDictionary(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
     452static int          libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
     453/**
     454 * Callback parameter structure used between libLoadUndefSymbolsFromArchLib
     455 * and libLoadUndefSymbolsFromArchLibCallback
     456 */
     457typedef struct libLoadUndefSymbolsFromArchLib_param
     458{
     459    /** The linker instance. */
     460    PWLD        pWld;
     461    /** The library. */
     462    PWLDLIB     pLib;
     463    /** See libLoadUndefSymbols. */
     464    PWLDSYM     pSym;
     465    /** See libLoadUndefSymbols. */
     466    unsigned   *pcLoaded;
     467} WLDLIBLOADUSFALPARAM, *PWLDLIBLOADUSFALPARAM;
     468static int          libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);
     469static int          libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
    436470static int          libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
     471/**
     472 * Enumeration callback routine.
     473 * @returns Any non-zero value stops the enumeration and is passed to the caller.
     474 * @param   pFile       Stream positioned at the start of the file. Don't close.
     475 * @param   pszName     The file name.
     476 * @param   cbFile      The file size.
     477 * @param   pvUser      The user parameter.
     478 */
     479typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);
     480static int          libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser);
    437481static int          libErr(PWLDLIB pLib, const char *pszFormat, ...);
    438482#if 0
     
    678722#if 0
    679723    FILE *phFile;
     724
    680725    /* been here, done that? */
    681     if (pLib->pDict)
     726    if (pLib->upDict)
    682727        return 0;
    683728
    684     /* check if it acutally is a library and have an ext dict */
    685     if (    pLib->LibHdr.chType != LIBHDR
    686         ||  pLib->LibHdr.offDict != 0
    687         ||  pLib->LibHdr.cDictBlocks != 0)
    688         return 1;
    689 
     729    if (pLib->fOmfLib)
     730    {
     731        /* check if it acutally is a library and have an ext dict */
     732        if (    pLib->u.Omf.LibHdr.chType != LIBHDR
     733            ||  pLib->u.Omf.LibHdr.offDict != 0
     734            ||  pLib->u.Omf.LibHdr.cDictBlocks != 0)
     735            return 1;
     736    }
     737    else
     738    {
     739    }
     740   
    690741    /* ensure it's open. */
    691742    phFile = libOpen(pLib);
    692743    if (!phFile)
    693744        return -1;
    694 
    695     /* position us */
    696     if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET))
    697         return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict);
    698 
    699     /* read it */
    700     pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512);
    701     if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks)
    702         return 0;
    703     libErr(pLib, "Failed to read extended dictionary.");
     745   
     746    if (pLib->fOmfLib)
     747    {
     748        /* position us */
     749        if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET))
     750            return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict);
     751   
     752        /* read it */
     753        pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512);
     754        if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks)
     755            return 0;
     756       
     757        libErr(pLib, "Failed to read extended dictionary.");
     758    }
     759   
    704760    free(pLib->pDict);
    705761    pLib->pDict = NULL;
    706762    return -1;
     763
    707764#else
    708765    /* till we support processing the dictionary, we pretend there is none. */
    709766    pLib->pDict = NULL;
    710     return -1;
     767    return 1;
    711768#endif
    712769}
     
    741798static int          libTryLoadSymbolThruDictionary(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
    742799{
    743     return libLoadUndefSymbols(pWld, pLib, pSym, pcLoaded); /* @todo implement this function! */
    744 }
    745 
    746 
    747 /**
    748  * Read thru an module looking for definitions for undef symbols.
    749  * If a definition is found we'll load the module containing it.
    750  *
    751  * @returns 0 on non failure.
    752  * @returns 42 if none found.
    753  * @returns -1 on link abort error.
    754  * @param   pWld    Linker instance.
    755  * @param   pLib    Library to search.
    756  * @param   pSym    Undefined symbol to search for.
    757  *                  If NULL we'll try and see if any defined global symbol we
    758  *                  encounter is undefined.
     800    return libLoadUndefSymbols(pWld, pLib, pSym, pcLoaded); /** @todo implement this function! */
     801}
     802
     803
     804/**
     805 * Implementation of libLoadUndefSymbols for unix archives.
     806 *
     807 * @returns see libLoadUndefSymbols
     808 * @param   pWld        Linker instance.
     809 * @param   pLib        Library to search.
     810 * @param   pSym        See libLoadUndefSymbols.
    759811 * @param   pcLoaded    Number of modules which was loaded from this library.
    760812 */
    761 static int          libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
     813static int          libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
    762814{
    763815    FILE *          phFile = pLib->phFile;
     
    774826
    775827    /* Position the library at the first module record. */
    776     if (fseek(phFile, pLib->LibHdr.chType == LIBHDR ? pLib->LibHdr.cb + 3 : 0, SEEK_SET))
     828    if (fseek(phFile, pLib->u.Omf.LibHdr.chType == LIBHDR ? pLib->u.Omf.LibHdr.cb + 3 : 0, SEEK_SET))
    777829        return libErr(pLib, "Error when seeking to first module.");
    778830
    779     if (pLib->LibHdr.chType != LIBHDR)
     831    if (pLib->u.Omf.LibHdr.chType != LIBHDR)
    780832    {
    781833        uchEnd1 = MODEND;
     
    10041056            if (OmfRec.chType == MODEND || OmfRec.chType == (MODEND | REC32))
    10051057            {
    1006                 unsigned    cbPage = pLib->LibHdr.cb + 3;
     1058                unsigned    cbPage = pLib->u.Omf.LibHdr.cb + 3;
    10071059                off_t       off = ftell(phFile) + offSkip;
    10081060                off -= cbPage * (off / cbPage); /* don't trust this to be 2**n. */
     
    10311083
    10321084/**
     1085 * Callback used by libLoadUndefSymbolsFromArchLib
     1086 *
     1087 * @returns 0 or -1  see libLoadUndefSymbols.
     1088 * @param   phFile      The library stream, positioned at the start of the file. 
     1089 * @param   pszName     The (short) file name.
     1090 * @param   cbFile      The file size.
     1091 * @param   pvUser      Parameters.
     1092 */
     1093static int          libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser)
     1094
     1095    PWLDLIBLOADUSFALPARAM pParam = (PWLDLIBLOADUSFALPARAM)pvUser;
     1096    /** @todo */
     1097    return 0;
     1098}
     1099
     1100
     1101/**
     1102 * Implementation of libLoadUndefSymbols for unix archives.
     1103 *
     1104 * @returns see libLoadUndefSymbols
     1105 * @param   pWld        Linker instance.
     1106 * @param   pLib        Library to search.
     1107 * @param   pSym        See libLoadUndefSymbols.
     1108 * @param   pcLoaded    Number of modules which was loaded from this library.
     1109 */
     1110static int          libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
     1111{
     1112    WLDLIBLOADUSFALPARAM Param;
     1113
     1114    Param.pWld      = pWld;
     1115    Param.pLib      = pLib;
     1116    Param.pSym      = pSym;
     1117    Param.pcLoaded  = pcLoaded;
     1118    return libEnumFilesArch(pLib, 0 /*fAll*/, libLoadUndefSymbolsFromArchLibCallback, &Param);
     1119}
     1120
     1121
     1122/**
     1123 * Read thru a library looking for definitions for undef symbols.
     1124 * If a definition is found we'll load the module containing it.
     1125 *
     1126 * @returns 0 on non failure.
     1127 * @returns 42 if none found.
     1128 * @returns -1 on link abort error.
     1129 * @param   pWld    Linker instance.
     1130 * @param   pLib    Library to search.
     1131 * @param   pSym    Undefined symbol to search for.
     1132 *                  If NULL we'll try and see if any defined global symbol we
     1133 *                  encounter is undefined.
     1134 * @param   pcLoaded    Number of modules which was loaded from this library.
     1135 */
     1136static int          libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
     1137{
     1138    if (!pLib->fOmfLib)
     1139        return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded);
     1140    return libLoadUndefSymbolsFromOmfLib(pWld, pLib, pSym, pcLoaded);
     1141}
     1142
     1143
     1144/**
     1145 * Validates a numeric ar_hdr field.
     1146 *
     1147 * These are supposed to be padded with spaces, however, emximp seems to be
     1148 * using null terminators as well (ar_mode for instance).
     1149 *
     1150 * @returns 0 if valid, -1 if invalid (error shown).
     1151 * @param   pachField       The field.
     1152 * @param   cchField        The field length.
     1153 * @param   uBase           10 for decimal, 8 for octal.
     1154 * @param   pszName         The field name.
     1155 */
     1156static int libArchValidateNumField(PWLDLIB pLib, char const *pachField, size_t cchField, unsigned uBase, const char *pszName)
     1157{
     1158    while (cchField > 0)
     1159    {
     1160        unsigned ch = *pachField;
     1161        if (ch - '0' >= uBase)
     1162        {
     1163            if (ch == ' ' || !ch)
     1164                break;
     1165            return libErr(pLib, "bad archive header field: %s", pszName);
     1166        }
     1167        cchField--;
     1168        pachField++;
     1169    }
     1170
     1171    while (cchField > 0)
     1172    {
     1173        char ch = *pachField;
     1174        if (ch != ' ' && ch)
     1175            return libErr(pLib, "bad archive header field: %s", pszName);
     1176        cchField--;
     1177        pachField++;
     1178    }
     1179   
     1180    return 0;
     1181}
     1182
     1183/**
     1184 * Checks the name field to see if there is a BSD style variable sized name
     1185 * field following the header.
     1186 *
     1187 * @returns 0 if none, length if something.
     1188 * @param   pArHdr          The archive header.
     1189 */
     1190static unsigned libArchHdrGetExtNameLen(struct ar_hdr *pArHdr)
     1191{
     1192    unsigned cchExtName = 0;
     1193    if (!memcmp(&pArHdr->ar_name[0], AR_EFMT1, sizeof(AR_EFMT1) - 1))
     1194    {
     1195        int         cch = sizeof(pArHdr->ar_name) - sizeof(AR_EFMT1) - 1;
     1196        const char *pch = &pArHdr->ar_name[sizeof(AR_EFMT1) - 1];
     1197        while (cch-- > 0)
     1198        {
     1199            unsigned uDig = (unsigned char)*pch++ - '0';
     1200            if (uDig > 10)
     1201                break;
     1202            cchExtName *= 10;
     1203            cchExtName += uDig;
     1204        }
     1205    }
     1206    return cchExtName;
     1207}
     1208
     1209
     1210/**
     1211 * Converts the size field of the header into something we can use.
     1212 * @returns ar_size as off_t.
     1213 * @param   pArHdr          The archive header.
     1214 */
     1215static off_t libArchHdrGetSize(struct ar_hdr *pArHdr)
     1216{
     1217    off_t       cb  = 0;
     1218    int         cch = sizeof(pArHdr->ar_size);
     1219    const char *pch = &pArHdr->ar_size[0];
     1220    while (cch-- > 0)
     1221    {
     1222        unsigned uDig = (unsigned char)*pch++ - '0';
     1223        if (uDig > 10)
     1224            break;
     1225        cb *= 10;
     1226        cb += uDig;
     1227    }
     1228    return cb;
     1229}
     1230
     1231
     1232/**
     1233 * Enumerates the files in the unix archive.
     1234 *
     1235 * @returns 0 if pfnCallback returned 0 for all the files.
     1236 * @returns first non-zero value pfnCallback returns (stops enumeration).
     1237 * @returns -1 if the library is invalid.
     1238 * @param   pLib        The Library to enumerate
     1239 * @param   fAll        Whether to include the special files or not.
     1240 * @param   pfnCallback The callback to invoke for each file.
     1241 * @param   pvUser      The user argument to pass to the callback.
     1242 */
     1243static int          libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser)
     1244{
     1245    int     rc      = 0;
     1246    FILE   *pFile   = pLib->phFile;
     1247    off_t   offNext;
     1248    char    szMagic[SARMAG + 1];
     1249
     1250    if (pLib->fOmfLib)
     1251        return libErr(pLib, "OMF library, expected ARCH!");
     1252
     1253    /*
     1254     * Read+reverify the magic.
     1255     */
     1256    if (   fseek(pFile, 0, SEEK_SET) != 0
     1257        || fread(&szMagic[0], SARMAG, 1, pFile) != 1)
     1258        return libErr(pLib, "failed to read library magic");
     1259    szMagic[SARMAG] = '\0';
     1260    if (strcmp(szMagic, ARMAG) != 0)
     1261        return libErr(pLib, "invalid library magic");
     1262
     1263    /*
     1264     * Process the archive, file by file.
     1265     */
     1266    offNext = SARMAG;
     1267    while (!feof(pFile))
     1268    {
     1269        struct ar_hdr   ArHdr;
     1270        off_t           cbFile;
     1271        size_t          cbRead;
     1272        int             cchExtraName;
     1273        int             fSpecial;
     1274        int             i;
     1275
     1276        /* read + verify the archive header */
     1277        cbRead = fread(&ArHdr, 1, sizeof(ArHdr), pFile);
     1278        if (cbRead != sizeof(ArHdr))
     1279            return cbRead == 0 && feof(pFile) ? 0 : libErr(pLib, "fread error");
     1280        offNext += sizeof(ArHdr);
     1281
     1282        if (memcmp(ArHdr.ar_fmag, ARFMAG, sizeof(ArHdr.ar_fmag)))
     1283            return libErr(pLib, "Bad ar_fmag value");
     1284        if (   libArchValidateNumField(pLib, ArHdr.ar_date, sizeof(ArHdr.ar_date), 10, "ar_date")
     1285            || libArchValidateNumField(pLib, ArHdr.ar_uid,  sizeof(ArHdr.ar_uid),  10, "ar_uid")
     1286            || libArchValidateNumField(pLib, ArHdr.ar_gid,  sizeof(ArHdr.ar_gid),  10, "ar_gid")
     1287            || libArchValidateNumField(pLib, ArHdr.ar_mode, sizeof(ArHdr.ar_mode),  8, "ar_mode")
     1288            || libArchValidateNumField(pLib, ArHdr.ar_size, sizeof(ArHdr.ar_size), 10, "ar_size") )
     1289            return 0; /* bitched already */
     1290       
     1291        cbFile   = libArchHdrGetSize(&ArHdr);
     1292        offNext += cbFile;
     1293        offNext += offNext & 1;         /* make even */
     1294
     1295        /* skip the extended name field if present (BSD). */
     1296        cchExtraName = libArchHdrGetExtNameLen(&ArHdr);
     1297        if (cchExtraName)
     1298        {
     1299            cbFile -= cchExtraName;
     1300            if (fseek(pFile, cchExtraName, SEEK_CUR))
     1301                return libErr(pLib, "fseek past the extended name failed");
     1302        }
     1303
     1304        /* strip trailing spaces from the header name. */
     1305        i = sizeof(ArHdr.ar_name);
     1306        ArHdr.ar_name[i] = '\0';
     1307        while (i-- > 0 && ArHdr.ar_name[i] == ' ')
     1308            ArHdr.ar_name[i] = '\0';
     1309
     1310        fSpecial = !strcmp(ArHdr.ar_name, "__.SYMDEF")
     1311                || !strcmp(ArHdr.ar_name, "/")
     1312                || !strcmp(ArHdr.ar_name, "//")
     1313                || !strcmp(ArHdr.ar_name, "ARFILENAMES");
     1314
     1315        /* trailing slashes used to be fashionable. */
     1316        if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/')
     1317            ArHdr.ar_name[i] = '\0';
     1318
     1319        /* ignore the archive symbol table. */
     1320        if (   fAll
     1321            || !fSpecial)
     1322        {           
     1323            rc = pfnCallback(pFile, ArHdr.ar_name, cbFile, pvUser);
     1324            if (rc)
     1325                return rc;
     1326        }
     1327       
     1328        /* advance to the next file */
     1329        if (fseek(pFile, offNext, SEEK_SET))
     1330            return libErr(pLib, "seek next failed.");
     1331    }
     1332   
     1333    return 0;           
     1334}
     1335
     1336
     1337/**
    10331338 * Put out an error for this library.
     1339 * @returns -1.
    10341340 * @param   pLib        Library which the warning occured in.
    10351341 * @param   pszFormat   Message format.
     
    25692875
    25702876
    2571 
     2877/**
     2878 * Reads an ELF module from a file.
     2879 *
     2880 * @returns 0 on success.
     2881 * @returns non zero on failure.
     2882 * @param   pWld        Pointer to linker instance.
     2883 * @param   pMod        Pointer to module
     2884 * @param   fLibSearch  Set if we're doing library search at this time.
     2885 */
     2886static unsigned     pass1ReadELFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch)
     2887{
     2888    /** @todo implement me. */
     2889    return 0;
     2890}
    25722891
    25732892
     
    26873006
    26883007/**
     3008 * Checks if the ELF header is valid.
     3009 *
     3010 * @returns 1 if it is, 0 if it isn't.
     3011 * @param   pEhdr   The ELF header.
     3012 * @param   pszName The file name to use when reporting errors.
     3013 */
     3014static int wldIsValidElfHdr(Elf32_Ehdr const *pEhdr, const char *pszName)
     3015{
     3016    if (!IS_ELF(*pEhdr))
     3017        fprintf(stderr, "weakld: '%s': not ELF file..\n", pszName);
     3018    else if (   pEhdr->e_ident[EI_CLASS] != ELFCLASS32
     3019             && pEhdr->e_ident[EI_CLASS] != ELFCLASSNONE)
     3020        fprintf(stderr, "weakld: '%s': wrong ELF class.\n", pszName);
     3021    else if (   pEhdr->e_ident[EI_DATA] != ELFDATA2LSB
     3022             && pEhdr->e_ident[EI_DATA] != ELFDATANONE)
     3023        fprintf(stderr, "weakld: '%s': wrong ELF endian.\n", pszName);
     3024    else if (pEhdr->e_ident[EI_VERSION] != EV_CURRENT)
     3025        fprintf(stderr, "weakld: '%s': wrong ELF version.\n", pszName);
     3026    /* Ignore EI_OSABI, EI_ABIVERSION and EI_PAD. */
     3027    else if (pEhdr->e_type != ET_REL)
     3028        fprintf(stderr, "weakld: '%s': not relocatable ELF file.\n", pszName);
     3029    else if (   pEhdr->e_machine != EM_386
     3030             && pEhdr->e_machine != EM_486)
     3031        fprintf(stderr, "weakld: '%s': not 386 or 486 ELF file.\n", pszName);
     3032    else if (pEhdr->e_version != EV_CURRENT)
     3033        fprintf(stderr, "weakld: '%s': wrong ELF version (#2).\n", pszName);
     3034    else if (pEhdr->e_ehsize != sizeof(*pEhdr))
     3035        fprintf(stderr, "weakld: '%s': wrong ELF header size.\n", pszName);
     3036    else if (pEhdr->e_phoff && pEhdr->e_phoff < sizeof(*pEhdr))
     3037        fprintf(stderr, "weakld: '%s': bad ELF program header offset.\n", pszName);
     3038    else if (pEhdr->e_shoff && pEhdr->e_shoff < sizeof(*pEhdr))
     3039        fprintf(stderr, "weakld: '%s': bad ELF section header offset.\n", pszName);
     3040    else if (pEhdr->e_phentsize != sizeof(Elf32_Phdr) && (pEhdr->e_phnum || pEhdr->e_phentsize))
     3041        fprintf(stderr, "weakld: '%s': wrong ELF program header size: %d\n", pszName, pEhdr->e_phentsize);
     3042    else if (pEhdr->e_shentsize != sizeof(Elf32_Shdr) && (pEhdr->e_shnum || pEhdr->e_shentsize))
     3043        fprintf(stderr, "weakld: '%s': wrong ELF section header size: %d\n", pszName, pEhdr->e_shentsize);
     3044    else
     3045        return 1;
     3046    return 0;
     3047}
     3048
     3049/**
    26893050 * Adds a object module to the linking process.
    26903051 * The object module will be analysed and the file handle closed.
     
    27033064int     WLDAddObject(PWLD pWld, FILE *phFile, const char *pszName)
    27043065{
    2705     OMFREC  OmfRec = {0,0};
     3066    union
     3067    {
     3068        OMFREC          OmfRec;
     3069        Elf32_Ehdr      Ehdr;
     3070    }       uBuf;
    27063071    int     rc = 0;
    27073072    if (!phFile)
     
    27133078    }
    27143079    WLDINFO(pWld, ("adding object %s.", pszName));
     3080    if (fread(&uBuf.OmfRec, sizeof(uBuf.OmfRec), 1, phFile) != 1)
     3081    {
     3082        fprintf(stderr, "weakld: error reading object file '%s'.\n", pszName);
     3083        fclose(phFile);
     3084        return -1;
     3085    }
    27153086
    27163087    /*
    2717      * An object module is either a object or a library.
     3088     * An object module is either a object (OMF or ELF) or a library (OMF).
    27183089     * In anycase all the modules it contains is to be added to the link.
    27193090     */
    2720     fread(&OmfRec, sizeof(OmfRec), 1, phFile);
    2721     if (OmfRec.chType == THEADR)
     3091    if (uBuf.OmfRec.chType == THEADR)
    27223092    {
    27233093        /* Single Object */
     
    27313101        modClose(pMod);
    27323102    }
    2733     else if (OmfRec.chType == LIBHDR)
     3103    else if (uBuf.OmfRec.chType == LIBHDR)
    27343104    {
    27353105        /* Library of object modules */
    2736         while (OmfRec.chType != LIBEND && OmfRec.chType != (LIBEND | REC32))
    2737         {
    2738             if (OmfRec.chType == THEADR || OmfRec.chType == (THEADR | REC32))
     3106        while (uBuf.OmfRec.chType != LIBEND && uBuf.OmfRec.chType != (LIBEND | REC32))
     3107        {
     3108            if (uBuf.OmfRec.chType == THEADR || uBuf.OmfRec.chType == (THEADR | REC32))
    27393109            {
    27403110                PWLDMOD     pMod = xmalloc(sizeof(*pMod));
     
    27423112                pMod->pszModName = strpool_add(pWld->pStrMisc, pszName);
    27433113                pMod->phFile = phFile;
    2744                 pMod->off = ftell(phFile) - sizeof(OmfRec);
     3114                pMod->off = ftell(phFile) - sizeof(uBuf.OmfRec);
    27453115                *pWld->ppObjsAdd = pMod;
    27463116                pWld->ppObjsAdd = &pMod->pNext;
     
    27613131            {
    27623132                /* skip to the net record */
    2763                 fseek(phFile, OmfRec.cb, SEEK_CUR);
     3133                fseek(phFile, uBuf.OmfRec.cb, SEEK_CUR);
    27643134            }
    27653135
    27663136            /* read next record */
    2767             fread(&OmfRec, sizeof(OmfRec), 1, phFile);
     3137            fread(&uBuf.OmfRec, sizeof(uBuf.OmfRec), 1, phFile);
    27683138        }
    27693139        fclose(phFile);
     3140    }
     3141    else if (   uBuf.Ehdr.e_ident[EI_MAG0] == ELFMAG0
     3142             && uBuf.Ehdr.e_ident[EI_MAG1] == ELFMAG1
     3143             && uBuf.Ehdr.e_ident[EI_MAG2] == ELFMAG2
     3144             && fread((char *)&uBuf.Ehdr + sizeof(uBuf.OmfRec),
     3145                      sizeof(uBuf.Ehdr) - sizeof(uBuf.OmfRec), 1, phFile) == 1
     3146             && uBuf.Ehdr.e_ident[EI_MAG3] == ELFMAG3)
     3147    {
     3148        if (wldIsValidElfHdr(&uBuf.Ehdr, pszName))
     3149        {
     3150            /* Single Object */
     3151            PWLDMOD pMod = xmalloc(sizeof(*pMod));
     3152            memset(pMod, 0, sizeof(*pMod));
     3153            pMod->pszModName = strpool_add(pWld->pStrMisc, pszName);
     3154            pMod->phFile = phFile;
     3155            *pWld->ppObjsAdd = pMod;
     3156            pWld->ppObjsAdd = &pMod->pNext;
     3157            rc = pass1ReadELFMod(pWld, pMod, 0);
     3158            modClose(pMod);
     3159        }
     3160        else
     3161        {
     3162            fclose(phFile);
     3163            rc = -1;
     3164        }
    27703165    }
    27713166    else
     
    29463341int     WLDAddLibrary(PWLD pWld, FILE *phFile, const char *pszName)
    29473342{
    2948     PWLDLIB     pLib;
    2949     int         rc = 0;
     3343    PWLDLIB pLib;
    29503344
    29513345    if (!phFile)
     
    29653359    pLib->pNext = NULL;
    29663360
    2967     /* read the library header. */
     3361    /* read the library header, detect the format. */
    29683362    if (    !fseek(phFile, 0, SEEK_SET)
    2969         &&  fread(&pLib->LibHdr, sizeof(OMFREC), 1, phFile) == 1
    2970         &&  (   pLib->LibHdr.chType != LIBHDR
    2971              || fread(&pLib->LibHdr.offDict, sizeof(pLib->LibHdr) - sizeof(OMFREC), 1, phFile) == 1
    2972                 )
    2973         )
    2974     {
    2975         /* link it in */
    2976         *pWld->ppLibsAdd = pLib;
    2977         pWld->ppLibsAdd = &pLib->pNext;
    2978         libClose(pLib);
     3363        &&  fread(&pLib->u.Omf.LibHdr, sizeof(OMFREC), 1, phFile) == 1)
     3364    {
     3365        int rc;
     3366        if (pLib->u.Omf.LibHdr.chType == LIBHDR)
     3367        {
     3368            pLib->fOmfLib = 1;
     3369            if (fread(&pLib->u.Omf.LibHdr.offDict, sizeof(pLib->u.Omf.LibHdr) - sizeof(OMFREC), 1, phFile) == 1)
     3370                rc = 0;
     3371            else
     3372                rc = libErr(pLib, "Failed reading OMF library header.");
     3373        }
     3374        else if (pLib->u.Omf.LibHdr.chType == THEADR)
     3375            pLib->fOmfLib = 1;
     3376        else if (!memcmp(&pLib->u.Omf.LibHdr, ARMAG, sizeof(OMFREC)))
     3377        {
     3378            char achMagic[SARMAG];
     3379            if (fread(achMagic, SARMAG - sizeof(OMFREC), 1, phFile) == 1)
     3380            {
     3381                if (!memcmp(achMagic, ARMAG + sizeof(OMFREC), SARMAG - sizeof(OMFREC)))
     3382                {
     3383                    pLib->fOmfLib = 0;
     3384                    pLib->u.Ar.uDummy = 0;
     3385                    rc = 0;
     3386                }
     3387                else
     3388                    rc = libErr(pLib, "Invalid library format.");
     3389            }
     3390            else
     3391                rc = libErr(pLib, "Failed reading AR library magic.");
     3392        }
     3393        else
     3394            rc = libErr(pLib, "Invalid library format.");
     3395
     3396        if (rc == 0)
     3397        {
     3398            /* link it in */
     3399            *pWld->ppLibsAdd = pLib;
     3400            pWld->ppLibsAdd = &pLib->pNext;
     3401            libClose(pLib);
     3402
     3403            return 0;
     3404        }
    29793405    }
    29803406    else
     
    29823408        /* We failed. */
    29833409        libErr(pLib, "Invalid library format or read error.");
    2984         fclose(phFile);
    2985         free(pLib);
    2986         rc = -1;
    2987     }
    2988 
    2989     return rc;
     3410    }
     3411   
     3412    fclose(phFile);
     3413    free(pLib);
     3414    return  -1;
    29903415}
    29913416
     
    36124037    pid_t           pid = getpid();
    36134038    static char     s_szTmp[_MAX_PATH + 1];
    3614    
     4039
    36154040    /* We need to apply _realrealpath to the tmpdir, so resolve that once and for all. */
    36164041    if (!s_szTmp[0])
Note: See TracChangeset for help on using the changeset viewer.