Export* ReadExport (FILE* F, ObjData* O) /* Read an export from a file */ { unsigned ConDesCount; Export* E; /* Read the type */ unsigned char Type = Read8 (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 = GET_EXP_CONDES_COUNT (Type); if (ConDesCount > 0) { unsigned char ConDes[CD_TYPE_COUNT]; unsigned I; /* 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. This array was * cleared by the constructor (NewExport), so we must only set the * fields that contain values. */ for (I = 0; I < ConDesCount; ++I) { unsigned ConDesType = CD_GET_TYPE (ConDes[I]); unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]); E->ConDes[ConDesType] = ConDesPrio; } } /* Read the name */ E->Name = MakeGlobalStringId (O, ReadVar (F)); /* Read the value */ if (IS_EXP_EXPR (Type)) { E->Expr = ReadExpr (F, O); } else { E->Expr = LiteralExpr (Read32 (F), O); } /* Last is the file position where the definition was done */ ReadFilePos (F, &E->Pos); /* Return the new export */ return E; }
Import* ReadImport (FILE* F, ObjData* Obj) /* Read an import from a file and return it */ { Import* I; /* Read the import address size */ unsigned char AddrSize = Read8 (F); /* Create a new import */ I = NewImport (AddrSize, Obj); /* Read the name */ I->Name = MakeGlobalStringId (Obj, ReadVar (F)); /* Read the file position */ ReadFilePos (F, &I->Pos); /* Check the address size */ if (I->AddrSize == ADDR_SIZE_DEFAULT || I->AddrSize > ADDR_SIZE_LONG) { /* Beware: This function may be called in cases where the object file * is not read completely into memory. In this case, the file list is * invalid. Be sure not to access it in this case. */ if (ObjHasFiles (I->Obj)) { Error ("Invalid import size in for `%s', imported from %s(%lu): 0x%02X", GetString (I->Name), GetSourceFileName (I->Obj, I->Pos.Name), I->Pos.Line, I->AddrSize); } else { Error ("Invalid import size in for `%s', imported from %s: 0x%02X", GetString (I->Name), GetObjFileName (I->Obj), I->AddrSize); } } /* Return the new import */ return I; }
void DumpObjLineInfo (FILE* F, unsigned long Offset) /* Dump the line info from an object file */ { ObjHeader H; Collection StrPool = AUTO_COLLECTION_INITIALIZER; unsigned Count; unsigned I; /* Seek to the header position and read the header */ FileSetPos (F, Offset); ReadObjHeader (F, &H); /* Seek to the start of the string pool and read it */ FileSetPos (F, Offset + H.StrPoolOffs); ReadStrPool (F, &StrPool); /* Seek to the start of line infos */ FileSetPos (F, Offset + H.LineInfoOffs); /* Output a header */ printf (" Line info:\n"); /* Check if the object file was compiled with debug info */ if ((H.Flags & OBJ_FLAGS_DBGINFO) == 0) { /* Print that there no line infos and bail out */ printf (" Count:%27u\n", 0); return; } /* Read the number of line infos and print it */ Count = ReadVar (F); printf (" Count:%27u\n", Count); /* Read and print all line infos */ for (I = 0; I < Count; ++I) { FilePos Pos; unsigned Type; /* File position of line info */ ReadFilePos (F, &Pos); /* Type of line info */ Type = ReadVar (F); /* Skip the spans */ SkipSpanList (F); /* Print the header */ printf (" Index:%27u\n", I); /* Print the data */ printf (" Type:%26u\n", LI_GET_TYPE (Type)); printf (" Count:%25u\n", LI_GET_COUNT (Type)); printf (" Line:%26u\n", Pos.Line); printf (" Col:%27u\n", Pos.Col); printf (" Name:%26u\n", Pos.Name); } /* Destroy the string pool */ DestroyStrPool (&StrPool); }