Changeset 3668 for trunk


Ignore:
Timestamp:
Sep 18, 2010, 4:41:20 PM (15 years ago)
Author:
bird
Message:

weakld.c: implemented searching of unix archives files.

File:
1 edited

Legend:

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

    r3667 r3668  
    158158    /** Filehandle if open */
    159159    FILE       *phFile;
     160    /** Where in the file the library starts. */
     161    off_t       off;
    160162    /** Set if it's a OMF library, clear if it's a unix archive. */
    161163    unsigned    fOmfLib;
     
    193195    /** Library relation - not used for libraries added thru wld_add_object(). */
    194196    PWLDLIB     pLib;
    195     /* Linked list next pointer */
     197    /** Pointer to the next module. */
    196198    struct wldmod *pNext;
    197199} WLDMOD, *PWLDMOD;
     
    452454static int          libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
    453455/**
    454  * Callback parameter structure used between libLoadUndefSymbolsFromArchLib 
     456 * Callback parameter structure used between libLoadUndefSymbolsFromArchLib
    455457 * and libLoadUndefSymbolsFromArchLibCallback
    456458 */
     
    466468    unsigned   *pcLoaded;
    467469} WLDLIBLOADUSFALPARAM, *PWLDLIBLOADUSFALPARAM;
    468 static int          libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);
     470static int          libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName, off_t offFile, off_t cbFile, void *pvUser);
    469471static int          libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
    470472static int          libLoadUndefSymbols(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded);
     
    474476 * @param   pFile       Stream positioned at the start of the file. Don't close.
    475477 * @param   pszName     The file name.
     478 * @param   offFile     The offset of the file in the stream @a pFile.
    476479 * @param   cbFile      The file size.
    477480 * @param   pvUser      The user parameter.
    478481 */
    479 typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t cbFile, void *pvUser);
     482typedef int (* PFNLIBENUMFILE)(FILE *pFile, const char *pszName, off_t offFile, off_t cbFile, void *pvUser);
    480483static int          libEnumFilesArch(PWLDLIB pLib, int fAll, PFNLIBENUMFILE pfnCallback, void *pvUser);
    481484static int          libErr(PWLDLIB pLib, const char *pszFormat, ...);
    482 #if 0
    483485static void         libWarn(PWLDLIB pLib, const char *pszFormat, ...);
    484 #endif
    485486/** @} */
    486487
     
    499500static int          symEnum(PWLD pWld, PWLDSYMTAB pSymTab, unsigned fFlags, unsigned fMask, PFNSYMENUM pfnEnum, void *pvUser);
    500501static int          symPrintUnDefEnum(PWLD pWld, PWLDSYM pSym, void *pvUser);
    501 static int          symMatchUnDef(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym);
     502static int          symMatchUnDef(PWLD pWld, const char *pszName, size_t cchName, PWLDSYM pSym);
     503static int          symMatchUnDefOmf(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym);
    502504/** Pointed to by the pvUser parameter of symSearchLibEnum(). */
    503505typedef struct symSearchLibEnum_param
     
    738740    {
    739741    }
    740    
     742
    741743    /* ensure it's open. */
    742744    phFile = libOpen(pLib);
    743745    if (!phFile)
    744746        return -1;
    745    
     747
    746748    if (pLib->fOmfLib)
    747749    {
     
    749751        if (fseek(phFile, pLib->LibHdr.offDict, SEEK_SET))
    750752            return libErr(pLib, "Failed to seek to extended dictionary (offset %d).", (int)pLib->LibHdr.offDict);
    751    
     753
    752754        /* read it */
    753755        pLib->pDict = xmalloc(pLib->LibHdr.cDictBlocks * 512);
    754756        if (fread(pLib->pDict, 512, pLib->LibHdr.cDictBlocks, phFile) == pLib->LibHdr.cDictBlocks)
    755757            return 0;
    756        
     758
    757759        libErr(pLib, "Failed to read extended dictionary.");
    758760    }
    759    
     761
    760762    free(pLib->pDict);
    761763    pLib->pDict = NULL;
     
    803805
    804806/**
    805  * Implementation of libLoadUndefSymbols for unix archives.
     807 * Common routine implementing libLoadUndefSymbol for OMF libraries as well as
     808 * do the searching of OMF members on behalf of libLoadUndefSymbolsFromArch.
    806809 *
    807810 * @returns see libLoadUndefSymbols
    808811 * @param   pWld        Linker instance.
    809  * @param   pLib        Library to search.
     812 * @param   pLib        Library being searched.  This does not have to be a
     813 *                      OMF library.
     814 * @param   pLibHdr     The library header read by the caller.
     815 * @param   offLib      The offset of the library to search in the library stream.
    810816 * @param   pSym        See libLoadUndefSymbols.
    811817 * @param   pcLoaded    Number of modules which was loaded from this library.
    812818 */
    813 static int          libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
     819static int          libLoadUndefSymbolsFromOmfLib2(PWLD pWld, PWLDLIB pLib, off_t offLib, POMFLIBHDR pLibHdr,
     820                                                   PWLDSYM pSym, unsigned *pcLoaded)
    814821{
    815822    FILE *          phFile = pLib->phFile;
    816823    unsigned char   uchEnd1, uchEnd2;
     824    OMFLIBHDR       LibHdr;
    817825    OMFREC          OmfRec;
    818826    off_t           offCurMod = 0;
     
    824832    unsigned char   uch, uch2;
    825833
    826 
    827     /* Position the library at the first module record. */
    828     if (fseek(phFile, pLib->u.Omf.LibHdr.chType == LIBHDR ? pLib->u.Omf.LibHdr.cb + 3 : 0, SEEK_SET))
     834    /* Position the stream at the first module record. */
     835    if (fseek(phFile, offLib + (pLibHdr->chType == LIBHDR ? pLibHdr->cb + 3 : 0), SEEK_SET))
    829836        return libErr(pLib, "Error when seeking to first module.");
    830837
    831     if (pLib->u.Omf.LibHdr.chType != LIBHDR)
     838    if (pLibHdr->chType != LIBHDR)
    832839    {
    833840        uchEnd1 = MODEND;
     
    932939                                    if (uch & 1)
    933940                                        ul = OMF_WORD();
    934                                     if (symMatchUnDef(pWld, u1.pch, pSym))
     941                                    if (symMatchUnDefOmf(pWld, u1.pch, pSym))
    935942                                        fLoad = 1;
    936943                                    break;
     
    952959                        ul = OMF_IS32BIT() ? OMF_DWORD() : OMF_WORD();
    953960                        us = OMF_GETINDEX();            /* typeindex */
    954                         if (symMatchUnDef(pWld, u1.pch, pSym))
     961                        if (symMatchUnDefOmf(pWld, u1.pch, pSym))
    955962                            fLoad = 1;
    956963                    }
     
    964971                        u1 = u; u.pch += 1 + *u.puch;   /* alias name */
    965972                        u2 = u; u.pch += 1 + *u.puch;   /* substitutt name. */
    966                         if (symMatchUnDef(pWld, u1.pch, pSym))
     973                        if (symMatchUnDefOmf(pWld, u1.pch, pSym))
    967974                            fLoad = 1;
    968975                    }
     
    991998                                return -1;
    992999                        }
    993                         if (symMatchUnDef(pWld, u1.pch, pSym))
     1000                        if (symMatchUnDefOmf(pWld, u1.pch, pSym))
    9941001                            fLoad = 1;
    9951002                    }
     
    10831090
    10841091/**
    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  */
    1093 static 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.
     1092 * Implementation of libLoadUndefSymbols for OMF libraries.
    11031093 *
    11041094 * @returns see libLoadUndefSymbols
     
    11081098 * @param   pcLoaded    Number of modules which was loaded from this library.
    11091099 */
     1100static int          libLoadUndefSymbolsFromOmfLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
     1101{
     1102    return libLoadUndefSymbolsFromOmfLib2(pWld, pLib, 0, &pLib->u.Omf.LibHdr, pSym, pcLoaded);
     1103}
     1104
     1105/**
     1106 * Callback used by libLoadUndefSymbolsFromArchLib
     1107 *
     1108 * @returns 0 or -1  see libLoadUndefSymbols.
     1109 * @param   phFile      The library stream, positioned at the start of the file.
     1110 * @param   pszName     The (short) file name.
     1111 * @param   offFile     The offset of the file in the stream @a pFile.
     1112 * @param   cbFile      The file size.
     1113 * @param   pvUser      Parameters.
     1114 */
     1115static int          libLoadUndefSymbolsFromArchLibCallback(FILE *pFile, const char *pszName,
     1116                                                           off_t offFile, off_t cbFile, void *pvUser)
     1117{
     1118    PWLDLIBLOADUSFALPARAM   pParam = (PWLDLIBLOADUSFALPARAM)pvUser;
     1119    size_t                  cbRead;
     1120    int                     rc;
     1121    union
     1122    {
     1123        OMFLIBHDR   OmfLib;
     1124        Elf32_Ehdr  Ehdr;
     1125    } uBuf;
     1126
     1127    cbRead = sizeof(uBuf);
     1128    if (cbRead > cbFile)
     1129        memset(&uBuf, 0, sizeof(uBuf));
     1130
     1131    if (fread(&uBuf, cbRead, 1, pFile) != 1)
     1132        return libErr(pParam->pLib, "failed to read archive member");
     1133    if (IS_ELF(uBuf.Ehdr))
     1134    {
     1135        WLDINFO(pParam->pWld, ("Considering AR/ELF %s(%s)\n", pParam->pLib->pszLibName, pszName));
     1136        /** @todo */
     1137        rc = 0;
     1138    }
     1139    else if (   uBuf.OmfLib.chType == THEADR
     1140             || uBuf.OmfLib.chType == LIBHDR)
     1141    {
     1142        WLDINFO(pParam->pWld, ("Considering AR/OMF %s(%s)\n", pParam->pLib->pszLibName, pszName));
     1143        rc = libLoadUndefSymbolsFromOmfLib2(pParam->pWld, pParam->pLib, offFile, &uBuf.OmfLib,
     1144                                            pParam->pSym, pParam->pcLoaded);
     1145    }
     1146    else
     1147    {
     1148        libWarn(pParam->pLib, "Skipping unknown member '%s'");
     1149        rc = 0;
     1150    }
     1151    if (rc == 42)
     1152        rc = 0;
     1153    return rc;
     1154}
     1155
     1156
     1157/**
     1158 * Implementation of libLoadUndefSymbols for unix archives.
     1159 *
     1160 * @returns see libLoadUndefSymbols
     1161 * @param   pWld        Linker instance.
     1162 * @param   pLib        Library to search.
     1163 * @param   pSym        See libLoadUndefSymbols.
     1164 * @param   pcLoaded    Number of modules which was loaded from this library.
     1165 */
    11101166static int          libLoadUndefSymbolsFromArchLib(PWLD pWld, PWLDLIB pLib, PWLDSYM pSym, unsigned *pcLoaded)
    11111167{
    11121168    WLDLIBLOADUSFALPARAM Param;
     1169WLDINFO(pWld, ("libLoadUndefSymbolsFromArchLib - %s\n", pLib->pszLibName));
    11131170
    11141171    Param.pWld      = pWld;
     
    11371194{
    11381195    if (!pLib->fOmfLib)
    1139         return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded); 
     1196        return libLoadUndefSymbolsFromArchLib(pWld, pLib, pSym, pcLoaded);
    11401197    return libLoadUndefSymbolsFromOmfLib(pWld, pLib, pSym, pcLoaded);
    11411198}
    11421199
    11431200
    1144 /** 
     1201/**
    11451202 * Validates a numeric ar_hdr field.
    11461203 *
    1147  * These are supposed to be padded with spaces, however, emximp seems to be 
    1148  * using null terminators as well (ar_mode for instance). 
     1204 * These are supposed to be padded with spaces, however, emximp seems to be
     1205 * using null terminators as well (ar_mode for instance).
    11491206 *
    11501207 * @returns 0 if valid, -1 if invalid (error shown).
     
    11771234        pachField++;
    11781235    }
    1179    
     1236
    11801237    return 0;
    11811238}
     
    12321289/**
    12331290 * Enumerates the files in the unix archive.
    1234  * 
     1291 *
    12351292 * @returns 0 if pfnCallback returned 0 for all the files.
    12361293 * @returns first non-zero value pfnCallback returns (stops enumeration).
     
    12681325    {
    12691326        struct ar_hdr   ArHdr;
     1327        off_t           offFile;
    12701328        off_t           cbFile;
    12711329        size_t          cbRead;
     
    12881346            || libArchValidateNumField(pLib, ArHdr.ar_size, sizeof(ArHdr.ar_size), 10, "ar_size") )
    12891347            return 0; /* bitched already */
    1290        
     1348
    12911349        cbFile   = libArchHdrGetSize(&ArHdr);
     1350        offFile  = offNext;
    12921351        offNext += cbFile;
    12931352        offNext += offNext & 1;         /* make even */
     
    12971356        if (cchExtraName)
    12981357        {
    1299             cbFile -= cchExtraName;
     1358            offFile += cchExtraName;
     1359            cbFile  -= cchExtraName;
    13001360            if (fseek(pFile, cchExtraName, SEEK_CUR))
    13011361                return libErr(pLib, "fseek past the extended name failed");
     
    13091369
    13101370        fSpecial = !strcmp(ArHdr.ar_name, "__.SYMDEF")
    1311                 || !strcmp(ArHdr.ar_name, "/") 
    1312                 || !strcmp(ArHdr.ar_name, "//") 
     1371                || !strcmp(ArHdr.ar_name, "/")
     1372                || !strcmp(ArHdr.ar_name, "//")
    13131373                || !strcmp(ArHdr.ar_name, "ARFILENAMES");
    13141374
    13151375        /* trailing slashes used to be fashionable. */
    1316         if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/') 
     1376        if (!fSpecial && i > 0 && ArHdr.ar_name[i] == '/')
    13171377            ArHdr.ar_name[i] = '\0';
    13181378
     
    13201380        if (   fAll
    13211381            || !fSpecial)
    1322         {           
    1323             rc = pfnCallback(pFile, ArHdr.ar_name, cbFile, pvUser);
     1382        {
     1383            rc = pfnCallback(pFile, ArHdr.ar_name, offFile, cbFile, pvUser);
    13241384            if (rc)
    13251385                return rc;
    13261386        }
    1327        
     1387
    13281388        /* advance to the next file */
    13291389        if (fseek(pFile, offNext, SEEK_SET))
    13301390            return libErr(pLib, "seek next failed.");
    13311391    }
    1332    
    1333     return 0;           
     1392
     1393    return 0;
    13341394}
    13351395
     
    13551415}
    13561416
    1357 #if 0
    13581417/**
    13591418 * Put out a warning for this library.
     
    13731432        fputc('\n', stderr);
    13741433}
    1375 #endif
    13761434
    13771435
     
    17241782
    17251783/**
     1784 * Checks the name with the specified undefined symbol, or all undefined
     1785 * symbols.
     1786 *
     1787 * @returns 1 if symbol matches.
     1788 * @returns 0 if symbol mis-matches.
     1789 * @param   pWld                Linker instance.
     1790 * @param   pachName            The symbol name.
     1791 * @param   cchName             The length of the symbol name
     1792 * @param   pSym                If NULL match all, if !NULL match this.
     1793 */
     1794static int          symMatchUnDef(PWLD pWld, const char *pszName, size_t cchName, PWLDSYM pSym)
     1795{
     1796    const char *psz;
     1797    unsigned    fFlags = 0;
     1798    unsigned    uHash = 0;
     1799    int        (*pfn)(const char *, const char *, size_t) = pWld->fFlags & WLDC_CASE_INSENSITIVE ? strnicmp : strncmp;
     1800
     1801    /* look for weak suffix and trucation */
     1802    for (psz = pszName + cchName - 1; psz > pszName; psz--)
     1803        if (    psz[0] == '$'
     1804            &&  psz[1] == 'w'
     1805            &&  psz[2] == '$')
     1806        {
     1807            cchName = psz - pszName;
     1808            if (cchName > 200)
     1809                break;
     1810        }
     1811
     1812    /** @todo: this isn't 100% correct when we're talking case insensitivity. */
     1813    if (!fFlags)
     1814        uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE);
     1815
     1816    /* compare */
     1817    if (pSym)
     1818        return SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn);
     1819
     1820    for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
     1821    {
     1822        if ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF)
     1823        {
     1824            if (SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn))
     1825                return 1;
     1826        }
     1827    }
     1828    return 0;
     1829}
     1830
     1831
     1832/**
    17261833 * Checks the OMF encoded name with the specified undefined
    17271834 * symbol, or all undefined symbols.
     
    17331840 * @param   pSym                If NULL match all, if !NULL match this.
    17341841 */
    1735 static int          symMatchUnDef(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym)
    1736 {
    1737     int         cchName = *pachPascalString;
    1738     const char *pszName = pachPascalString + 1;
    1739     const char *psz;
    1740     unsigned    fFlags = 0;
    1741     unsigned    uHash = 0;
    1742     int        (*pfn)(const char *, const char *, size_t) = pWld->fFlags & WLDC_CASE_INSENSITIVE ? strnicmp : strncmp;
    1743 
    1744     /* look for weak suffix and trucation */
    1745     for (psz = pszName + cchName - 1; psz > pszName; psz--)
    1746         if (    psz[0] == '$'
    1747             &&  psz[1] == 'w'
    1748             &&  psz[2] == '$')
    1749         {
    1750             cchName = psz - pszName;
    1751             if (cchName > 200)
    1752                 break;
    1753         }
    1754 
    1755     /* @todo: this isn't 100% correct when we're talking case in sensitivity. */
    1756     if (!fFlags)
    1757         uHash = symHash(pszName, cchName, pWld->fFlags & WLDC_CASE_INSENSITIVE);
    1758 
    1759     /* compare */
    1760     if (pSym)
    1761         return SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn);
    1762     else
    1763     {
    1764         for (pSym = pWld->Global.ap[uHash % WLDSYM_HASH_SIZE]; pSym; pSym = pSym->pHashNext)
    1765         {
    1766             if ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF)
    1767             {
    1768                 if (SYM_EQUAL2(pWld, pSym, pszName, fFlags, uHash, cchName, pfn))
    1769                     return 1;
    1770             }
    1771         }
    1772     }
    1773     return 0;
     1842static int          symMatchUnDefOmf(PWLD pWld, const unsigned char *pachPascalString, PWLDSYM pSym)
     1843{
     1844    return symMatchUnDef(pWld, pachPascalString + 1, *pachPascalString, pSym);
    17741845}
    17751846
     
    33633434        &&  fread(&pLib->u.Omf.LibHdr, sizeof(OMFREC), 1, phFile) == 1)
    33643435    {
    3365         int rc; 
     3436        int rc;
    33663437        if (pLib->u.Omf.LibHdr.chType == LIBHDR)
    33673438        {
     
    34093480        libErr(pLib, "Invalid library format or read error.");
    34103481    }
    3411    
     3482
    34123483    fclose(phFile);
    34133484    free(pLib);
Note: See TracChangeset for help on using the changeset viewer.