Exemple #1
0
void ObjReadData (FILE* F, ObjData* O)
/* Read object file data from the given file. The function expects the Name
 * and Start fields to be valid. Header and basic data are read.
 */
{
    unsigned long Count;

    /* Seek to the start of the object file data */
    fseek (F, O->Start, SEEK_SET);

    /* Read the object file header */
    ObjReadHeader (F, &O->Header, O->Name);

    /* Read the string pool */
    fseek (F, O->Start + O->Header.StrPoolOffs, SEEK_SET);
    Count = ReadVar (F);
    CollGrow (&O->Strings, Count);
    while (Count--) {
        CollAppend (&O->Strings, ReadStr (F));
    }

    /* Read the exports */
    fseek (F, O->Start + O->Header.ExportOffs, SEEK_SET);
    Count = ReadVar (F);
    CollGrow (&O->Exports, Count);
    while (Count--) {

        unsigned char ConDes[CD_TYPE_COUNT];

        /* Skip data until we get to the name */
        unsigned Type = ReadVar (F);
        (void) Read8 (F);       /* AddrSize */
        ReadData (F, ConDes, SYM_GET_CONDES_COUNT (Type));

        /* Now this is what we actually need: The name of the export */
        CollAppend (&O->Exports, CollAt (&O->Strings, ReadVar (F)));

        /* Skip the export value */
        if (SYM_IS_EXPR (Type)) {
            /* Expression tree */
            SkipExpr (F);
        } else {
            /* Literal value */
            (void) Read32 (F);
        }

        /* Skip the size if necessary */
        if (SYM_HAS_SIZE (Type)) {
            (void) ReadVar (F);
        }

        /* Line info indices */
        SkipLineInfoList (F);
        SkipLineInfoList (F);
    }
}
Exemple #2
0
void ObjAdd (const char* Name)
/* Add an object file to the library */
{
    struct stat StatBuf;
    const char* Module;
    ObjHeader H;
    ObjData* O;

    /* Open the object file */
    FILE* Obj = fopen (Name, "rb");
    if (Obj == 0) {
        Error ("Could not open `%s': %s", Name, strerror (errno));
    }

    /* Get the modification time of the object file. There a race condition
     * here, since we cannot use fileno() (non standard identifier in standard
     * header file), and therefore not fstat. When using stat with the
     * file name, there's a risk that the file was deleted and recreated
     * while it was open. Since mtime and size are only used to check
     * if a file has changed in the debugger, we will ignore this problem
     * here.
     */
    if (FileStat (Name, &StatBuf) != 0) {
        Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
    }

    /* Read and check the header */
    ObjReadHeader (Obj, &H, Name);

    /* Make a module name from the file name */
    Module = GetModule (Name);

    /* Check if we already have a module with this name */
    O = FindObjData (Module);
    if (O == 0) {
        /* Not found, create a new entry */
        O = NewObjData ();
    } else {
        /* Found - check the file modification times of the internal copy
         * and the external one.
         */
        if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
            Warning ("Replacing module `%s' by older version in library `%s'",
                     O->Name, LibName);
        }

        /* Free data */
        ClearObjData (O);
    }

    /* Initialize the object module data structure */
    O->Name     = xstrdup (Module);
    O->Flags  	= OBJ_HAVEDATA;
    O->MTime  	= StatBuf.st_mtime;
    O->Start    = 0;

    /* Determine the file size. Note: Race condition here */
    fseek (Obj, 0, SEEK_END);
    O->Size     = ftell (Obj);

    /* Read the basic data from the object file */
    ObjReadData (Obj, O);

    /* Copy the complete object data to the library file and update the
     * starting offset
     */
    fseek (Obj, 0, SEEK_SET);
    O->Start    = LibCopyTo (Obj, O->Size);

    /* Done, close the file (we read it only, so no error check) */
    fclose (Obj);
}
Exemple #3
0
void ObjAdd (FILE* Obj, const char* Name)
/* Add an object file to the module list */
{
    /* Create a new structure for the object file data */
    ObjData* O = NewObjData ();

    /* The magic was already read and checked, so set it in the header */
    O->Header.Magic = OBJ_MAGIC;

    /* Read and check the header */
    ObjReadHeader (Obj, &O->Header, Name);

    /* Initialize the object module data structure */
    O->Name  = GetModule (Name);

    /* Read the string pool from the object file */
    ObjReadStrPool (Obj, O->Header.StrPoolOffs, O);

    /* Read the files list from the object file */
    ObjReadFiles (Obj, O->Header.FileOffs, O);

    /* Read the imports list from the object file */
    ObjReadImports (Obj, O->Header.ImportOffs, O);

    /* Read the object file exports and insert them into the exports list */
    ObjReadExports (Obj, O->Header.ExportOffs, O);

    /* Read the object debug symbols from the object file */
    ObjReadDbgSyms (Obj, O->Header.DbgSymOffs, O);

    /* Read the line infos from the object file */
    ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);

    /* Read the assertions from the object file */
    ObjReadAssertions (Obj, O->Header.AssertOffs, O);

    /* Read the scope table from the object file */
    ObjReadScopes (Obj, O->Header.ScopeOffs, O);

    /* Read the segment list from the object file. This must be last, since
     * the expressions stored in the code may reference segments or imported
     * symbols.
     */
    ObjReadSections (Obj, O->Header.SegOffs, O);

    /* Mark this object file as needed */
    O->Flags |= OBJ_REF;

    /* Done, close the file (we read it only, so no error check) */
    fclose (Obj);

    /* Insert the imports and exports to the global lists */
    InsertObjGlobals (O);

    /* Insert the object into the list of all used object files */
    InsertObjData (O);

    /* All references to strings are now resolved, so we can delete the module
     * string pool.
     */
    FreeObjStrings (O);
}