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); } }
Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; unsigned I; Export* E; /* Read the type */ unsigned Type = ReadVar (F); /* Read the address size */ unsigned char AddrSize = Read8 (F); /* Create a new export without a name */ E = NewExport (Type, AddrSize, INVALID_STRING_ID, O); /* Read the constructor/destructor decls if we have any */ ConDesCount = SYM_GET_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; /* Read the data into temp storage */ ReadData (F, ConDes, ConDesCount); /* Re-order the data. In the file, each decl is encoded into a byte ** which contains the type and the priority. In memory, we will use ** an array of types which contain the priority. */ for (I = 0; I < ConDesCount; ++I) { E->ConDes[CD_GET_TYPE (ConDes[I])] = CD_GET_PRIO (ConDes[I]); } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (SYM_IS_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Read the size */ if (SYM_HAS_SIZE (Type)) { E->Size = ReadVar (F); } /* Last are the locations */ ReadLineInfoList (F, O, &E->DefLines); ReadLineInfoList (F, O, &E->RefLines); /* If this symbol is exported as a condes, and the condes type declares a ** forced import, add this import to the object module. */ for (I = 0; I < CD_TYPE_COUNT; ++I) { const ConDesImport* CDI; if (E->ConDes[I] != CD_PRIO_NONE && (CDI = ConDesGetImport (I)) != 0) { unsigned J; /* Generate a new import, and add it to the module's import list. */ Import* Imp = GenImport (CDI->Name, CDI->AddrSize); Imp->Obj = O; CollAppend (&O->Imports, Imp); /* Add line info for the export that is actually the condes that ** forces the import. Then, add line info for the config. file. ** The export's info is added first because the import pretends ** that it came from the object module instead of the config. file. */ for (J = 0; J < CollCount (&E->DefLines); ++J) { CollAppend (&Imp->RefLines, DupLineInfo (CollAt (&E->DefLines, J))); } CollAppend (&Imp->RefLines, GenLineInfo (&CDI->Pos)); } } /* Return the new export */ return E; }