static void ReadIndexEntry (void) /* Read one entry in the index */ { /* Create a new entry and insert it into the list */ ObjData* O = NewObjData (); /* Module name/flags/MTime/Start/Size */ O->Name = ReadStr (Lib); O->Flags = Read16 (Lib); O->MTime = Read32 (Lib); O->Start = Read32 (Lib); O->Size = Read32 (Lib); }
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); }
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); }