Changeset 488


Ignore:
Timestamp:
Jul 31, 2003, 4:45:07 PM (22 years ago)
Author:
bird
Message:

#483: Temporary commit (Again.).

Location:
trunk/src/emx/src/emxomf
Files:
2 edited

Legend:

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

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r487 r488  
    468468   */
    469469
    470 static FILE * find_objlib(char *pszfullname, const char *pszname,
    471                           const char * const *papszexts, int flibhacks)
     470static FILE * find_objlib2(char *pszfullname, const char *pszname, const char * const *papszexts, int flibhacks)
    472471{
    473472  const char *  psz;
     
    544543            phFile = fopen (pszfullname, "rb");
    545544
     545          if (!flibhacks && phFile)
     546            return phFile;
     547
    546548          if (phFile)
    547549            {
     
    556558              } libhdr;
    557559              #pragma pack()
    558               if (!flibhacks)
    559                 return phFile;
    560560              /* For .a libraries we will chech for a valid OMF library header. */
    561561              if (memicmp(pszfullname + strlen(pszfullname) - 2, ".a", 3))
    562562                  return phFile;
    563               if (  fread(&libhdr, 1, sizeof(libhdr), phFile) == sizeof(libhdr)
     563              if (   fread(&libhdr, 1, sizeof(libhdr), phFile) == sizeof(libhdr)
    564564                  && libhdr.rec_type == LIBHDR
    565565                  && libhdr.flags <= 1 /* ASSUME only first bit is used... */
     566                  && !fseek(phFile, 0, SEEK_SET)
    566567                  )
    567568                {
     
    581582
    582583
     584/* Wrapper around find_objlib which fixes the slashes - this looks better imho. */
     585
     586static FILE * find_objlib(char *pszfullname, const char *pszname, const char * const *papszexts, int flibhacks)
     587{
     588    FILE * phFile = find_objlib2(pszfullname, pszname, papszexts, flibhacks);
     589    while ((pszfullname = strchr(pszfullname, '/')) != NULL)
     590        *pszfullname++ = '\\';
     591    return phFile;
     592}
     593
     594
     595
    583596/* Weak prelinking for Method 2 Weak support. */
    584597
     
    588601  PWLD    pwld;
    589602
    590   pwld = wld_create (0);
     603  pwld = wld_create (WLDC_VERBOSE);
    591604  if (pwld)
    592605    {
  • trunk/src/emx/src/emxomf/weakld.c

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r487 r488  
    4646*******************************************************************************/
    4747#define WLDSYM_HASH_SIZE    211
     48#define OMF_MAX_REC         1024
    4849
    4950
     
    5556#include <stdlib.h>
    5657#include <sys/types.h>
     58#include <sys/omflib.h>
    5759#include "defs.h"
    5860#include "grow.h"
    5961#include "weakld.h"
     62
    6063 
    6164/*******************************************************************************
     
    7174    /** Filehandle if open */
    7275    FILE *      phFile;
     76    /** Linked list next pointer. */
     77    struct wldlib * pNext;
    7378} WLDLIB, *PWLDLIB;
    7479 
     
    8388    /** Filehandle if open. */
    8489    FILE *      phFile;
    85 
    86     /** Library relation. */
     90    /** Module offset into the file. */
     91    off_t       off;
     92    /** Library relation - not used for libraries added thru wld_add_object(). */
    8793    PWLDLIB     pLib;
    88     /** Library offset. */
    89     off_t       offLib;
     94    /* Linked list next pointer */
     95    struct wldmod *pNext;
    9096} WLDMOD, *PWLDMOD;
    9197 
     
    108114    /** Symbol flags. */
    109115    enum {
    110         /* Strong symbol. */
    111         WLDSF_STRONG    = 0,
    112         /** Weak symbol, can become strong. */
    113         WLDSF_WEAK      = 1,
    114         /** Undefined symbol, can become strong. */
    115         WLDSF_UNDEF     = 2,
    116         /** Communal data/code, become strong. */
    117         WLDSF_COMM      = 4,
    118         /** Import symbol. */
    119         WLDSF_IMPORT    = 8,
    120         /** Exported symbol. */
    121         WLDSF_EXPORT    = 16,
    122 
     116        /** @group Symbol state
     117         * @{ */
     118        /* Mask of the symbol state. */
     119        WLDSF_STATEMASK = 0x000f,
     120        /** Strong symbol.
     121         * A strong definition exists for this symbol (PUBDEF). */
     122        WLDSF_STRONG    = 0x0001,
     123        /** Communal data/code.
     124         * Communal definition exists for this symbol.
     125         * If a PUBDEF is found for this symbol it will become strong. */
     126        WLDSF_COMM      = 0x0002,
     127        /** Undefined symbol.
     128         * This symbol is not yet defined anywhere. */
     129        WLDSF_UNDEF     = 0x0003,
     130        /** Weak external.
     131         * This symbol doesn't need to be resolved as it have a default
     132         * resolution. pWeakDefault is pointing to the default resolution.
     133         * If an non weak EXTDEF is found in another module, it will become
     134         * WLDSF_UNDEF.
     135         */
     136        WLDSF_WKEXT     = 0x0004,
     137        /** @} */
     138
     139        /** Weak symbol.
     140         * This symbol doesn't need to be resolved (if WLDSF_UNDEF), or
     141         * it may be overridden by a EXTDEF with no WKEXT.
     142         * If this is an weak undefined symbol (extern weak, local default)
     143         * pWeakDefault Will point at it.
     144         */
     145        WLDSF_WEAK      = 0x0100,
     146
     147        /** Uncertain undefined symbol.
     148         * We're still processing the module containing this and the uncertainty
     149         * we're facing is that a WLDSF_UNDEF may changed to an WLDSF_WKEXT
     150         * upon encountering a WKEXT COMENT record. */
     151        WLDSF_UNCERTAIN = 0x0200,
     152
     153
     154        /** Import symbol.
     155         * This symbol is imported. */
     156        WLDSF_IMPORT    = 0x0400,
     157        /** Exported symbol.
     158         * This symbol is to be exported. */
     159        WLDSF_EXPORT    = 0x0800,
     160        /** Alias symbol.
     161         * This symbol is an alias for another symbol. pAliasFor will be set. */
     162        WLDSF_ALIAS     = 0x1000,
    123163    }                   eFlags;
    124164
     
    129169    const char*         pszImpMod;
    130170
     171    /** Ordinal - WLDSF_IMPORT or WLDSF_EXPORT.
     172     * 0 means no ordinal. */
     173    unsigned            iOrdinal;
     174
     175    /** Export flags */
     176    struct
     177    {
     178        unsigned    fResidentName : 1;  /* Put name in resident or non resident table. */
     179        unsigned    fNoName : 1;        /* No name at all. */
     180        unsigned    fNoData : 1;        /* ?? */
     181        unsigned    cParams;            /* callgate stuff, # of words to push */
     182    }                   fExport
     183
    131184    /** Symbol this is an alias for. */
    132185    struct wldsym *     pAliasFor;
     186
     187    /** Weak default resolution.
     188     * If this symbol in state WLDSF_WKEXT or have to WLDSF_WEAK flag set this
     189     * member indicates a default resolution for the symbol. For WLDSF_WEAK
     190     * this only make sense if the state is WLDSF_UNDEF.
     191     */
     192    struct wldsym *     pWeakDefault;
    133193
    134194    /** Next node in the hash bucket. */
     
    156216    /** Global symbols. */
    157217    WLDSYMTAB           Global;
     218
     219    /** Linked list (FIFO) of objects included in the link. */
     220    PWLDMOD             pObjs;
     221    PWLDMOD *           ppObjsAdd;
     222
     223    /** Linked list (FIFO) of libraries to be searched in the link. */
     224    PWLDMOD             pLibs;
     225    PWLDMOD *           ppLibsAdd;
    158226
    159227    /** string pool for miscellaneous string. */
     
    163231 
    164232
     233/** @group OMF stuff
     234 * @{ */
     235
     236/** OMF record header. */
     237#pragma pack(1)
     238typedef struct OMFREC
     239{
     240  unsigned char     chType;
     241  unsigned short    cb;
     242} OMFREC, *POMFREC;
     243#pragma pack()
     244
     245
     246/** OMF library header. */
     247#pragma pack(1)
     248typedef struct OMFLIBHDR
     249{
     250  unsigned char     chType;
     251  unsigned short    cb;
     252  unsigned long     offDict;
     253  unsigned short    cDictBlocks;
     254  unsigned char     fchFlags;
     255} OMFLIBHDR, *POMFLIBHDR;
     256#pragma pack()
     257
     258/** @} */
     259
    165260
    166261extern void *xrealloc (void *ptr, size_t n);
    167262extern void *xmalloc (size_t n);
    168263
     264static unsigned     hash(const char* pszSym, unsigned cch);
     265static FILE *       modOpen(PWLDMOD pMod);
     266static void         modClose(PWLDMOD pMod);
    169267
    170268
     
    197295}
    198296
     297/**
     298 * Report error in module.
     299 * @param   pMod        Pointer to module to report error on.
     300 * @param   pszFormat   Format string.
     301 * @param   ...         Format arguments.
     302 */
     303static void     modError(PWLDMOD pMod, const char *pszFormat, ...)
     304{
     305    va_list     args;
     306    if (pMod->pLib)
     307        fprintf(stderr, "weakld: %s(%s) - error: ", pMod->pLib->pszLibName, pMod->pszModName);
     308    else
     309        fprintf(stderr, "weakld: %s - error: ", pMod->pszModName);
     310
     311    va_start(args, pszFormat);
     312    vfprintf(stderr, pszFormat, args);
     313    va_end(args);
     314    if (pszFormat[strlen(pszFormat) - 1] != '\n')
     315        fputc('\n', stderr);
     316}
     317
     318
     319/**
     320 * Report warning in module.
     321 * @param   pMod        Pointer to module to report warning on.
     322 * @param   pszFormat   Format string.
     323 * @param   ...         Format arguments.
     324 */
     325static void     modWarn(PWLDMOD pMod, const char *pszFormat, ...)
     326{
     327    va_list     args;
     328    if (pMod->pLib)
     329        fprintf(stderr, "weakld: %s(%s) - warning: ", pMod->pLib->pszLibName, pMod->pszModName);
     330    else
     331        fprintf(stderr, "weakld: %s - warning: ", pMod->pszModName);
     332
     333    va_start(args, pszFormat);
     334    vfprintf(stderr, pszFormat, args);
     335    va_end(args);
     336    if (pszFormat[strlen(pszFormat) - 1] != '\n')
     337        fputc('\n', stderr);
     338}
     339
     340
     341
     342/**
     343 * Opens the module (if required) file for reading.
     344 *
     345 * @returns Pointer to file stream.
     346 * @param   pMod    Module to open.
     347 */
     348static FILE *   modOpen(PWLDMOD pMod)
     349{
     350    const char *pszFilename;
     351
     352    /* open the file */
     353    if (!pMod->phFile)
     354    {
     355        if (pMod->pLib && pMod->pLib->phFile)
     356            pMod->phFile = pMod->pLib->phFile;
     357        else
     358        {   /* fopen it */
     359            if (pMod->pLib)
     360            {
     361                pszFilename = pMod->pLib->pszLibName;
     362                pMod->phFile = pMod->pLib->phFile = fopen(pszFilename, "rb");
     363            }
     364            else
     365            {
     366                pszFilename = pMod->pszModName;
     367                pMod->phFile = fopen(pszFilename, "rb");
     368            }
     369        }
     370    }
     371
     372    /* Position the stream at the start of the module. */
     373    if (!pMod->phFile)
     374        modErrro(pMod, "failed to reopen.");
     375    else
     376    {
     377        if (fseek(pMod->phFile, pMod->off, SEEK_SET))
     378        {
     379            modErrro(pMod, "failed to seek to module start (%#x).", pMod->off);
     380            modClose(pMod);
     381            return NULL;
     382        }
     383    }
     384       
     385    return pMod->phFile;
     386}
     387
     388
     389/**
     390 * Closes the module.
     391 *
     392 * @param   pMod    Module to close.
     393 */
     394static void     modClose(PWLDMOD pMod)
     395{
     396    if (!pMod->phFile)
     397        return;
     398    if (!pMod->pLib || pMod->pLib->phFile != pMod->phFile)
     399        fclose(pMod->phFile);
     400    pMod->phFile = NULL;
     401}
     402
     403
     404/**
     405 * Reads an OMF module from a file.
     406 *
     407 * This may be part of a library file so, we'll only read from THEADR to
     408 * past the first MODEND or the Pass 1 comment record.
     409 * The function will return the module stream positioned after the last
     410 * record it read.
     411 *
     412 * @returns 0 on success.
     413 * @returns non zero on failure.
     414 * @param   pWld    Pointer to linker instance.
     415 * @param   pMod    Pointer to module
     416 */
     417static unsigned     pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod)
     418{
     419    FILE *          phFile;             /* Input file. */
     420    PWLDSYM         papExts[] = NULL;   /* Pointer to an array of EXTDEFs (as they appear) */
     421                                        /* We need them for the WKEXT processing. */
     422    int             cExts = 0;          /* Number of Entries in papExts. */
     423    int             fFirst = 1;         /* First record indicator. */
     424    /* generic stuff we'll use alot with not status associated. */
     425    int             cch;               
     426    PWLDSYM         pSym;
     427
     428
     429    /* open and position the file. */
     430    phFile = modOpen(pMod);
     431
     432    /* loop till we get a MODEND */
     433    for (;;)
     434    {
     435        OMFREC          OmfRec;             
     436        unsigned char   achBuffer[OMF_MAX_REC + 8];
     437        union
     438        {
     439            unsigned char *     puch;
     440            signed char *       pch;
     441            unsigned short *    pus;
     442            signed short *      ps;
     443            unsigned long *     pul;
     444            signed long *       pl;
     445        } u;
     446        /** macro for getting a OMF index out of the buffer */
     447        #define OMF_GETINDEX()  (*u.puch & 0x80 ? ((*u.pch++ & 0x7f) << 8) + *u.pch++ : *u.pch++)
     448        #define OMF_BYTE()      (*u.puch++)
     449        #define OMF_WORD()      (*u.pus++)
     450        #define OMF_MORE()      (u.puch - &achBuffer[0] < (int)OmfRec.cb - 1)
     451
     452        u.pv = &achBuffer[0];
     453
     454        /* read omf record header */
     455        if (fread(&OmfRec, sizeof(OmfRec), 1, phFile) != 1)
     456        {
     457            modError(pMod, "read error. (offset ~= %#x).", ftell(phFile));
     458            goto failure;
     459        }
     460        if (fFirst)
     461        {   /* some extra check for the first record. */
     462            fFirst = 0;
     463            if (OmfRec.chType != THEADR)
     464            {
     465                modError(pMod, "invalid object module (offset %#x).", pMod->off);
     466                goto failure;
     467            }
     468        }
     469   
     470        /* Read or skip the record. */
     471        switch (OmfRec.chType)
     472        {
     473            /* done */
     474            case MODEND: case MODEND | REC32:
     475            case LIBEND:
     476                fseek(phFile, OmfRec.cb, SEEK_CUR);
     477                goto done_skip;
     478            /* read */
     479            case EXTDEF: case EXTDEF | REC32:
     480            case PUBDEF: case PUBDEF | REC32:
     481            case ALIAS:  case ALIAS  | REC32:
     482            case COMDEF: case COMDEF | REC32:
     483            case COMDAT: case COMDAT | REC32:
     484            case COMENT: case COMENT | REC32:
     485            case LIBHDR:
     486                break;
     487            /* skip */
     488            default:
     489                fseek(phFile, OmfRec.cb, SEEK_CUR);
     490                continue;
     491        }
     492        if (fread(achBuffer, OmfRec.cb, 1, phFile) != 1)
     493        {
     494            modError(pMod, "read error. (offset ~= %#x)", ftell(phFile));
     495            goto failure;             
     496        }
     497
     498        /* Switch on type. */
     499        switch (OmfRec.chType)
     500        {
     501            case COMENT: case COMENT | REC32:
     502                switch (*++u.pch)
     503                {
     504                    case CLASS_PASS:
     505                         goto done_noskip;
     506                    case CLASS_WKEXT:
     507                    {   /* This is a bit tricky, we need to have an indexable array
     508                         * of the extdefs for this module. In addition we'll need to
     509                         * make sure we don't mark an EXTDEF from another module as
     510                         * weak.
     511                         */
     512                        while (OMF_MORE())
     513                        {
     514                            int iWeak = OMF_GETINDEX();
     515                            int iDefault = OMF_GETINDEX();
     516                            if (   iWeak     >= cExts
     517                                || iDefault  >= cExts
     518                                || !papExts[iWeak]
     519                                || !papExts[iDefault])
     520                                modError(pMod, "Invalid WKEXT record.");
     521                            if (papExts[iWeak]->eFlags & WLDSF_UNCERTAIN)
     522                            {
     523                                papExts[iWeak]->eFlags = (papExts[iWeak]->eFlags & ~WLDSF_STATEMASK) | WLDSF_WKEXT;
     524                                papExts[iWeak]->pWeakDefault = papExts[iDefault];
     525                            }
     526                            else if (   (papExts[iWeak]->eFlags & WLDSF_STATEMASK) == WLDSF_WKEXT
     527                                     &&  papExts[iWeak]->pWeakDefault != papExts[iDefault])
     528                                modWarn(pMod, "WKEXT '%s' allready declared with '%s' and not '%s' as default.",
     529                                        papExts[iWeak]->pszName, papExts[iWeak]->pWeakDefault->pszName, papExts[iDefault]->pszName);
     530                        }
     531                        break;
     532                    }
     533                   
     534                    case CLASS_OMFEXT:
     535                    {
     536                        switch (OMF_BYTE())
     537                        {   /*
     538                             * Import definition.
     539                             */
     540                            case OMFEXT_IMPDEF:
     541                            {
     542                                int fOrd = OMF_BYTE();
     543                                cch = OMF_BYTE();
     544                                pSym = symNew(pWld, WLDSF_STRONG | WLDSF_IMPORT, u.pch, cch);
     545                                if (!pSym) goto failure;
     546                                u.pch += cch;
     547                                cch = OMF_BYTE();
     548                                pSym->pszImpMod = strpool_addn(pWld->pStrMisc, u.pch, cch);
     549                                u.pch += cch;
     550                                if (fOrd)
     551                                    pSym->iOrdinal = OMF_WORD();
     552                                break;
     553                            }
     554
     555                            /*
     556                             * Export definition.
     557                             */
     558                            case OMFEXT_EXPDEF:
     559                            {
     560                                int fOrd = *u.pch & 1;
     561                                break;
     562                            }
     563                        }
     564
     565                    }
     566
     567                }
     568                break;
     569
     570            case EXTDEF: case EXTDEF | REC32:
     571            {
     572
     573                break;
     574            }
     575
     576            case PUBDEF: case PUBDEF | REC32:
     577            {
     578                break;
     579            }
     580
     581            case ALIAS: case ALIAS | REC32:
     582            {
     583                break;
     584            }
     585
     586            case COMDEF: case COMDEF | REC32:
     587            {
     588                break;
     589            }
     590
     591            case COMDAT: case COMDAT | REC32:
     592            {
     593                break;
     594            }
     595
     596            case LIBHDR:
     597                modError(pMod, "invalid object module (LIBHDR).");
     598                goto failure;
     599            default:
     600                fprintf(stderr, "we shall not be here!!\n");
     601                asm ("int $3");
     602                break;
     603        }
     604
     605        #undef OMF_GETINDEX
     606    }
     607
     608done_skip:
     609    /* Skip to end of record */
     610    fseek(phFile, OmfRec.cb, SEEK_CUR);
     611
     612done_noskip:
     613    /* Make all the EXTDEFs uncertain. */
     614    for (i = 0; i < cExts; i++)
     615        papExts[i]->eFlags &= ~WLDSF_UNCERTAIN;
     616
     617    return 0;
     618
     619failure:
     620    if (papExts)
     621        free(papExts);
     622    return -1;
     623}
     624
    199625
    200626
     
    225651    pWld->fFlags = fFlags;
    226652    pWld->pStrMisc = strpool_init();
     653    pWld->ppLibsAdd = &pWld->pObjs;
     654    pWld->ppObjsAdd = &pWld->pLibs;
    227655
    228656    /* done */
     
    271699int     wld_add_object(PWLD pWld, FILE *phFile, const char *pszName)
    272700{
     701    OMFREC  OmfRec = {0,0};
     702    int     rc = 0;
    273703    if (!phFile)
    274704        phFile = fopen(pszName, "rb");
     
    279709    }
    280710    if (pWld->fFlags & WLDC_VERBOSE)
    281         fprintf(stderr, "weakld: info: adding object %s\n", pszName);
    282 
    283     /* @todo process it! */
    284 
    285     return 0;
     711        fprintf(stderr, "weakld: info: adding object %s.\n", pszName);
     712
     713    /*
     714     * An object module is either a object or a library.
     715     * In anycase all the modules it contains is to be added to the link.
     716     */
     717    fread(&OmfRec, sizeof(OmfRec), 1, phFile);
     718    if (OmfRec.chType == THEADR)
     719    {
     720        /* Single Object */
     721        PWLDMOD pMod = xmalloc(sizeof(*pMod));
     722        memset(pMod, 0, sizeof(*pMod));
     723        pMod->pszModName = strpool_add(pWld->pStrMisc, pszName);
     724        pMod->phFile = phFile;
     725        *pWld->ppObjsAdd = pMod;
     726        pWld->ppObjsAdd = &pMod->pNext;
     727        rc = pass1ReadOMFMod(pWld, pMod);
     728    }
     729    else if (OmfRec.chType == LIBHDR)
     730    {
     731        /* Library of object modules */
     732        while (OmfRec.chType != LIBEND && OmfRec.chType != (LIBEND | REC32))
     733        {
     734            if (OmfRec.chType == THEADR || OmfRec.chType == (THEADR | REC32))
     735            {
     736                PWLDMOD     pMod = xmalloc(sizeof(*pMod));
     737                memset(pMod, 0, sizeof(*pMod));
     738                pMod->pszModName = strpool_add(pWld->pStrMisc, pszName);
     739                pMod->phFile = phFile;
     740                pMod->off = ftell(phFile) - sizeof(OmfRec);
     741                *pWld->ppObjsAdd = pMod;
     742                pWld->ppObjsAdd = &pMod->pNext;
     743                if (pWld->fFlags & WLDC_VERBOSE)
     744                {
     745                    char            achModName[256];
     746                    unsigned char   cchModName;
     747                    cchModName = fgetc(phFile);
     748                    achModName[fread(achModName, 1, cchModName, phFile)] = '\0';
     749                    fprintf(stderr, "weakld: info: adding library member '%s'.\n", achModName);
     750                }
     751                rc = pass1ReadOMFMod(pWld, pMod);
     752                if (rc)
     753                    break;
     754            }
     755            else
     756            {
     757                /* skip to the net record */
     758                fseek(phFile, OmfRec.cb, SEEK_CUR);
     759            }
     760
     761            /* read next record */
     762            fread(&OmfRec, sizeof(OmfRec), 1, phFile);
     763        }
     764    }
     765    else
     766    {
     767        fprintf(stderr, "weakld: invalid object file '%s'.\n", pszName);
     768        rc = -1;
     769    }
     770
     771    return rc;
    286772}
    287773
Note: See TracChangeset for help on using the changeset viewer.