mirror of
https://github.com/cc65/cc65.git
synced 2025-01-11 11:30:13 +00:00
Change how data is stored in the library. To simplify things, the index
(=directory) entry is now shorter, and additional data necessary for checking in the archiver is not stored in the directory but read from the object file data in the library. git-svn-id: svn://svn.cc65.org/cc65/trunk@4944 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
8386b47074
commit
5855137d8c
@ -46,11 +46,12 @@
|
||||
|
||||
/* ar65 */
|
||||
#include "error.h"
|
||||
#include "global.h"
|
||||
#include "fileio.h"
|
||||
#include "objdata.h"
|
||||
#include "exports.h"
|
||||
#include "fileio.h"
|
||||
#include "global.h"
|
||||
#include "library.h"
|
||||
#include "objdata.h"
|
||||
#include "objfile.h"
|
||||
|
||||
|
||||
|
||||
@ -61,8 +62,8 @@
|
||||
|
||||
|
||||
/* File descriptor for the library file */
|
||||
FILE* NewLib = 0;
|
||||
static FILE* Lib = 0;
|
||||
FILE* NewLib = 0;
|
||||
static FILE* Lib = 0;
|
||||
static const char* LibName = 0;
|
||||
|
||||
/* The library header */
|
||||
@ -105,34 +106,15 @@ static void ReadHeader (void)
|
||||
static void ReadIndexEntry (void)
|
||||
/* Read one entry in the index */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
/* 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->Name = ReadStr (Lib);
|
||||
O->Flags = Read16 (Lib);
|
||||
O->MTime = Read32 (Lib);
|
||||
O->Start = Read32 (Lib);
|
||||
O->Size = Read32 (Lib);
|
||||
|
||||
/* Strings */
|
||||
O->StringCount = ReadVar (Lib);
|
||||
O->Strings = xmalloc (O->StringCount * sizeof (char*));
|
||||
for (I = 0; I < O->StringCount; ++I) {
|
||||
O->Strings[I] = ReadStr (Lib);
|
||||
}
|
||||
|
||||
/* Imports */
|
||||
O->ImportSize = ReadVar (Lib);
|
||||
O->Imports = xmalloc (O->ImportSize);
|
||||
ReadData (Lib, O->Imports, O->ImportSize);
|
||||
|
||||
/* Exports */
|
||||
O->ExportSize = ReadVar (Lib);
|
||||
O->Exports = xmalloc (O->ExportSize);
|
||||
ReadData (Lib, O->Exports, O->ExportSize);
|
||||
}
|
||||
|
||||
|
||||
@ -140,7 +122,7 @@ static void ReadIndexEntry (void)
|
||||
static void ReadIndex (void)
|
||||
/* Read the index of a library file */
|
||||
{
|
||||
unsigned Count;
|
||||
unsigned Count, I;
|
||||
|
||||
/* Seek to the start of the index */
|
||||
fseek (Lib, Header.IndexOffs, SEEK_SET);
|
||||
@ -150,14 +132,24 @@ static void ReadIndex (void)
|
||||
|
||||
/* Read all entries in the index */
|
||||
while (Count--) {
|
||||
ReadIndexEntry ();
|
||||
ReadIndexEntry ();
|
||||
}
|
||||
|
||||
/* Read basic object file data from the actual entries */
|
||||
for (I = 0; I < CollCount (&ObjPool); ++I) {
|
||||
|
||||
/* Get the object file entry */
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
|
||||
/* Read data */
|
||||
ObjReadData (Lib, O);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Writing file data structures */
|
||||
/* Writing file data structures */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -180,28 +172,12 @@ static void WriteHeader (void)
|
||||
static void WriteIndexEntry (const ObjData* O)
|
||||
/* Write one index entry */
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
/* Module name/flags/MTime/start/size */
|
||||
WriteStr (NewLib, O->Name);
|
||||
Write16 (NewLib, O->Flags & ~OBJ_HAVEDATA);
|
||||
Write32 (NewLib, O->MTime);
|
||||
Write32 (NewLib, O->Start);
|
||||
Write32 (NewLib, O->Size);
|
||||
|
||||
/* Strings */
|
||||
WriteVar (NewLib, O->StringCount);
|
||||
for (I = 0; I < O->StringCount; ++I) {
|
||||
WriteStr (NewLib, O->Strings[I]);
|
||||
}
|
||||
|
||||
/* Imports */
|
||||
WriteVar (NewLib, O->ImportSize);
|
||||
WriteData (NewLib, O->Imports, O->ImportSize);
|
||||
|
||||
/* Exports */
|
||||
WriteVar (NewLib, O->ExportSize);
|
||||
WriteData (NewLib, O->Exports, O->ExportSize);
|
||||
}
|
||||
|
||||
|
||||
@ -229,7 +205,7 @@ static void WriteIndex (void)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* High level stuff */
|
||||
/* High level stuff */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -321,116 +297,21 @@ void LibCopyFrom (unsigned long Pos, unsigned long Bytes, FILE* F)
|
||||
|
||||
|
||||
|
||||
static unsigned long GetVar (unsigned char** Buf)
|
||||
/* Get a variable sized value from Buf */
|
||||
{
|
||||
unsigned char C;
|
||||
unsigned long V = 0;
|
||||
unsigned Shift = 0;
|
||||
do {
|
||||
/* Read one byte */
|
||||
C = **Buf;
|
||||
++(*Buf);
|
||||
/* Add this char to the value */
|
||||
V |= ((unsigned long)(C & 0x7F)) << Shift;
|
||||
/* Next value */
|
||||
Shift += 7;
|
||||
} while (C & 0x80);
|
||||
|
||||
/* Return the result */
|
||||
return V;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SkipExpr (unsigned char** Buf)
|
||||
/* Skip an expression in Buf */
|
||||
{
|
||||
/* Get the operation and skip it */
|
||||
unsigned char Op = **Buf;
|
||||
++(*Buf);
|
||||
|
||||
/* Filter leaf nodes */
|
||||
switch (Op) {
|
||||
|
||||
case EXPR_NULL:
|
||||
return;
|
||||
|
||||
case EXPR_LITERAL:
|
||||
/* 32 bit literal value */
|
||||
*Buf += 4;
|
||||
return;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Variable seized symbol index */
|
||||
(void) GetVar (Buf);
|
||||
return;
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* 8 bit segment number */
|
||||
*Buf += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* What's left are unary and binary nodes */
|
||||
SkipExpr (Buf); /* Skip left */
|
||||
SkipExpr (Buf); /* Skip right */
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SkipLineInfoList (unsigned char** Buf)
|
||||
/* Skip a list of line infos in Buf */
|
||||
{
|
||||
/* Number of indices preceeds the list */
|
||||
unsigned long Count = GetVar (Buf);
|
||||
|
||||
/* Skip indices */
|
||||
while (Count--) {
|
||||
(void) GetVar (Buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void LibCheckExports (ObjData* O)
|
||||
/* Insert all exports from the given object file into the global list
|
||||
* checking for duplicates.
|
||||
*/
|
||||
{
|
||||
/* Get a pointer to the buffer */
|
||||
unsigned char* Exports = O->Exports;
|
||||
unsigned I;
|
||||
|
||||
/* Get the export count */
|
||||
unsigned Count = GetVar (&Exports);
|
||||
/* Let the user know what we do */
|
||||
Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, CollCount (&O->Exports));
|
||||
|
||||
/* Read the exports */
|
||||
Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, Count);
|
||||
while (Count--) {
|
||||
/* Insert the exports into the global table */
|
||||
for (I = 0; I < CollCount (&O->Exports); ++I) {
|
||||
|
||||
const char* Name;
|
||||
|
||||
/* Get the export tag and skip the address size */
|
||||
unsigned Type = GetVar (&Exports);
|
||||
++Exports;
|
||||
|
||||
/* condes decls may follow */
|
||||
Exports += SYM_GET_CONDES_COUNT (Type);
|
||||
|
||||
/* Next thing is index of name of symbol */
|
||||
Name = GetObjString (O, GetVar (&Exports));
|
||||
|
||||
/* Skip value of symbol */
|
||||
if (SYM_IS_EXPR (Type)) {
|
||||
/* Expression tree */
|
||||
SkipExpr (&Exports);
|
||||
} else {
|
||||
/* Constant 32 bit value */
|
||||
Exports += 4;
|
||||
}
|
||||
|
||||
/* Skip the line info */
|
||||
SkipLineInfoList (&Exports);
|
||||
/* Get the name of the export */
|
||||
const char* Name = CollConstAt (&O->Exports, I);
|
||||
|
||||
/* Insert the name into the hash table */
|
||||
Print (stdout, 1, " %s\n", Name);
|
||||
@ -458,8 +339,8 @@ void LibClose (void)
|
||||
*/
|
||||
for (I = 0; I < CollCount (&ObjPool); ++I) {
|
||||
|
||||
/* Get a pointer to the object */
|
||||
ObjData* O = CollAt (&ObjPool, I);
|
||||
/* Get a pointer to the object */
|
||||
ObjData* O = CollAtUnchecked (&ObjPool, I);
|
||||
|
||||
/* Check exports, make global export table */
|
||||
LibCheckExports (O);
|
||||
@ -507,7 +388,7 @@ void LibClose (void)
|
||||
}
|
||||
if (NewLib && fclose (NewLib) != 0) {
|
||||
Error ("Problem closing temporary library file: %s", strerror (errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -70,16 +70,14 @@ ObjData* NewObjData (void)
|
||||
|
||||
/* Initialize the data */
|
||||
O->Name = 0;
|
||||
|
||||
O->Flags = 0;
|
||||
O->MTime = 0;
|
||||
O->Start = 0;
|
||||
O->Size = 0;
|
||||
O->StringCount = 0;
|
||||
O->Strings = 0;
|
||||
O->ImportSize = 0;
|
||||
O->Imports = 0;
|
||||
O->ExportSize = 0;
|
||||
O->Exports = 0;
|
||||
|
||||
O->Strings = EmptyCollection;
|
||||
O->Exports = EmptyCollection;
|
||||
|
||||
/* Add it to the list */
|
||||
CollAppend (&ObjPool, O);
|
||||
@ -96,17 +94,31 @@ void FreeObjData (ObjData* O)
|
||||
unsigned I;
|
||||
|
||||
xfree (O->Name);
|
||||
xfree (O->Imports);
|
||||
xfree (O->Exports);
|
||||
for (I = 0; I < O->StringCount; ++I) {
|
||||
xfree (O->Strings[I]);
|
||||
for (I = 0; I < CollCount (&O->Strings); ++I) {
|
||||
xfree (CollAt (&O->Strings, I));
|
||||
}
|
||||
xfree (O->Strings);
|
||||
DoneCollection (&O->Strings);
|
||||
DoneCollection (&O->Exports);
|
||||
xfree (O);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ClearObjData (ObjData* O)
|
||||
/* Remove any data stored in O */
|
||||
{
|
||||
unsigned I;
|
||||
xfree (O->Name);
|
||||
O->Name = 0;
|
||||
for (I = 0; I < CollCount (&O->Strings); ++I) {
|
||||
xfree (CollAt (&O->Strings, I));
|
||||
}
|
||||
CollDeleteAll (&O->Strings);
|
||||
CollDeleteAll (&O->Exports);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ObjData* FindObjData (const char* Module)
|
||||
/* Search for the module with the given name and return it. Return NULL if the
|
||||
* module is not in the list.
|
||||
@ -157,15 +169,3 @@ void DelObjData (const char* Module)
|
||||
|
||||
|
||||
|
||||
const char* GetObjString (const ObjData* O, unsigned Index)
|
||||
/* Get a string from the string pool of an object file */
|
||||
{
|
||||
if (Index >= O->StringCount) {
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, O->Name);
|
||||
}
|
||||
return O->Strings[Index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -40,45 +40,48 @@
|
||||
|
||||
/* common */
|
||||
#include "coll.h"
|
||||
#include "objdefs.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Values for the Flags field */
|
||||
#define OBJ_HAVEDATA 0x0001 /* The object data is in the tmp file */
|
||||
#define OBJ_MARKED 0x0002 /* Generic marker bit */
|
||||
#define OBJ_HAVEDATA 0x0001 /* The object data is in the tmp file */
|
||||
|
||||
|
||||
/* Internal structure holding object file data */
|
||||
typedef struct ObjData ObjData;
|
||||
struct ObjData {
|
||||
char* Name; /* Module name */
|
||||
|
||||
/* Index entry */
|
||||
unsigned Flags;
|
||||
unsigned long MTime; /* Modifiation time of object file */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned long Size; /* Size of data in library */
|
||||
unsigned StringCount; /* Number of strings */
|
||||
char** Strings; /* Strings from the object file */
|
||||
unsigned long ImportSize; /* Size of imports */
|
||||
void* Imports; /* Imports as raw data */
|
||||
unsigned long ExportSize; /* Size of exports */
|
||||
void* Exports; /* Exports as raw data */
|
||||
unsigned long Start; /* Start offset of data in library */
|
||||
unsigned long Size; /* Size of data in library */
|
||||
|
||||
/* Object file header */
|
||||
ObjHeader Header;
|
||||
|
||||
/* Basic data needed for simple checks */
|
||||
Collection Strings; /* Strings from the object file */
|
||||
Collection Exports; /* Exports list from object file */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Collection with object files */
|
||||
/* Collection with all object files */
|
||||
extern Collection ObjPool;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -89,6 +92,9 @@ ObjData* NewObjData (void);
|
||||
void FreeObjData (ObjData* O);
|
||||
/* Free a complete struct */
|
||||
|
||||
void ClearObjData (ObjData* O);
|
||||
/* Remove any data stored in O */
|
||||
|
||||
ObjData* FindObjData (const char* Module);
|
||||
/* Search for the module with the given name and return it. Return NULL if the
|
||||
* module is not in the list.
|
||||
@ -97,9 +103,6 @@ ObjData* FindObjData (const char* Module);
|
||||
void DelObjData (const char* Module);
|
||||
/* Delete the object module from the list */
|
||||
|
||||
const char* GetObjString (const ObjData* O, unsigned Index);
|
||||
/* Get a string from the string pool of an object file */
|
||||
|
||||
|
||||
|
||||
/* End of objdata.h */
|
||||
|
@ -46,7 +46,10 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* common */
|
||||
#include "cddefs.h"
|
||||
#include "exprdefs.h"
|
||||
#include "fname.h"
|
||||
#include "symdefs.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* ar65 */
|
||||
@ -81,7 +84,7 @@ static const char* GetModule (const char* Name)
|
||||
|
||||
|
||||
|
||||
void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
/* Read the header of the object file checking the signature */
|
||||
{
|
||||
H->Magic = Read32 (Obj);
|
||||
@ -117,32 +120,106 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
|
||||
|
||||
|
||||
void ObjWriteHeader (FILE* Obj, ObjHeader* H)
|
||||
/* Write the header of the object file */
|
||||
static void SkipExpr (FILE* F)
|
||||
/* Skip an expression in F */
|
||||
{
|
||||
Write32 (Obj, H->Magic);
|
||||
Write16 (Obj, H->Version);
|
||||
Write16 (Obj, H->Flags);
|
||||
Write32 (Obj, H->OptionOffs);
|
||||
Write32 (Obj, H->OptionSize);
|
||||
Write32 (Obj, H->FileOffs);
|
||||
Write32 (Obj, H->FileSize);
|
||||
Write32 (Obj, H->SegOffs);
|
||||
Write32 (Obj, H->SegSize);
|
||||
Write32 (Obj, H->ImportOffs);
|
||||
Write32 (Obj, H->ImportSize);
|
||||
Write32 (Obj, H->ExportOffs);
|
||||
Write32 (Obj, H->ExportSize);
|
||||
Write32 (Obj, H->DbgSymOffs);
|
||||
Write32 (Obj, H->DbgSymSize);
|
||||
Write32 (Obj, H->LineInfoOffs);
|
||||
Write32 (Obj, H->LineInfoSize);
|
||||
Write32 (Obj, H->StrPoolOffs);
|
||||
Write32 (Obj, H->StrPoolSize);
|
||||
Write32 (Obj, H->AssertOffs);
|
||||
Write32 (Obj, H->AssertSize);
|
||||
Write32 (Obj, H->ScopeOffs);
|
||||
Write32 (Obj, H->ScopeSize);
|
||||
/* Get the operation and skip it */
|
||||
unsigned char Op = Read8 (F);
|
||||
|
||||
/* Handle then different expression nodes */
|
||||
switch (Op) {
|
||||
|
||||
case EXPR_NULL:
|
||||
break;
|
||||
|
||||
case EXPR_LITERAL:
|
||||
/* 32 bit literal value */
|
||||
(void) Read32 (F);
|
||||
break;
|
||||
|
||||
case EXPR_SYMBOL:
|
||||
/* Variable seized symbol index */
|
||||
(void) ReadVar (F);
|
||||
break;
|
||||
|
||||
case EXPR_SECTION:
|
||||
/* 8 bit segment number */
|
||||
(void) Read8 (F);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* What's left are unary and binary nodes */
|
||||
SkipExpr (F); /* Left */
|
||||
SkipExpr (F); /* right */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SkipLineInfoList (FILE* F)
|
||||
/* Skip a list of line infos in F */
|
||||
{
|
||||
/* Number of indices preceeds the list */
|
||||
unsigned long Count = ReadVar (F);
|
||||
|
||||
/* Skip indices */
|
||||
while (Count--) {
|
||||
(void) ReadVar (F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Line info indices */
|
||||
SkipLineInfoList (F);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -154,7 +231,6 @@ void ObjAdd (const char* Name)
|
||||
const char* Module;
|
||||
ObjHeader H;
|
||||
ObjData* O;
|
||||
unsigned I;
|
||||
|
||||
/* Open the object file */
|
||||
FILE* Obj = fopen (Name, "rb");
|
||||
@ -192,65 +268,29 @@ void ObjAdd (const char* Name)
|
||||
if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
|
||||
Warning ("Replacing module `%s' by older version", O->Name);
|
||||
}
|
||||
|
||||
/* Free data */
|
||||
ClearObjData (O);
|
||||
}
|
||||
|
||||
/* Initialize the object module data structure */
|
||||
O->Name = xstrdup (Module);
|
||||
O->Flags = OBJ_HAVEDATA;
|
||||
O->MTime = StatBuf.st_mtime;
|
||||
O->ImportSize = H.ImportSize;
|
||||
O->Imports = xmalloc (O->ImportSize);
|
||||
O->ExportSize = H.ExportSize;
|
||||
O->Exports = xmalloc (O->ExportSize);
|
||||
O->Name = xstrdup (Module);
|
||||
O->Flags = OBJ_HAVEDATA;
|
||||
O->MTime = StatBuf.st_mtime;
|
||||
O->Start = 0;
|
||||
|
||||
/* Read imports and exports */
|
||||
fseek (Obj, H.ImportOffs, SEEK_SET);
|
||||
ReadData (Obj, O->Imports, O->ImportSize);
|
||||
fseek (Obj, H.ExportOffs, SEEK_SET);
|
||||
ReadData (Obj, O->Exports, O->ExportSize);
|
||||
/* Determine the file size. Note: Race condition here */
|
||||
fseek (Obj, 0, SEEK_END);
|
||||
O->Size = ftell (Obj);
|
||||
|
||||
/* Read the string pool */
|
||||
fseek (Obj, H.StrPoolOffs, SEEK_SET);
|
||||
O->StringCount = ReadVar (Obj);
|
||||
O->Strings = xmalloc (O->StringCount * sizeof (char*));
|
||||
for (I = 0; I < O->StringCount; ++I) {
|
||||
O->Strings[I] = ReadStr (Obj);
|
||||
}
|
||||
/* Read the basic data from the object file */
|
||||
ObjReadData (Obj, O);
|
||||
|
||||
/* Skip the object file header */
|
||||
O->Start = ftell (NewLib);
|
||||
fseek (NewLib, OBJ_HDR_SIZE, SEEK_CUR);
|
||||
|
||||
/* Copy the remaining sections */
|
||||
fseek (Obj, H.DbgSymOffs, SEEK_SET);
|
||||
H.DbgSymOffs = LibCopyTo (Obj, H.DbgSymSize) - O->Start;
|
||||
fseek (Obj, H.OptionOffs, SEEK_SET);
|
||||
H.OptionOffs = LibCopyTo (Obj, H.OptionSize) - O->Start;
|
||||
fseek (Obj, H.SegOffs, SEEK_SET);
|
||||
H.SegOffs = LibCopyTo (Obj, H.SegSize) - O->Start;
|
||||
fseek (Obj, H.FileOffs, SEEK_SET);
|
||||
H.FileOffs = LibCopyTo (Obj, H.FileSize) - O->Start;
|
||||
fseek (Obj, H.LineInfoOffs, SEEK_SET);
|
||||
H.LineInfoOffs = LibCopyTo (Obj, H.LineInfoSize) - O->Start;
|
||||
fseek (Obj, H.AssertOffs, SEEK_SET);
|
||||
H.AssertOffs = LibCopyTo (Obj, H.AssertSize) - O->Start;
|
||||
fseek (Obj, H.ScopeOffs, SEEK_SET);
|
||||
H.ScopeOffs = LibCopyTo (Obj, H.ScopeSize) - O->Start;
|
||||
|
||||
/* Calculate the amount of data written */
|
||||
O->Size = ftell (NewLib) - O->Start;
|
||||
|
||||
/* Clear the remaining header fields */
|
||||
H.ImportOffs = H.ImportSize = 0;
|
||||
H.ExportOffs = H.ExportSize = 0;
|
||||
H.StrPoolOffs = H.StrPoolSize = 0;
|
||||
|
||||
/* Seek back and write the updated header */
|
||||
fseek (NewLib, O->Start, SEEK_SET);
|
||||
ObjWriteHeader (NewLib, &H);
|
||||
|
||||
/* Now seek again to end of file */
|
||||
fseek (NewLib, 0, SEEK_END);
|
||||
/* 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);
|
||||
@ -261,20 +301,14 @@ void ObjAdd (const char* Name)
|
||||
void ObjExtract (const char* Name)
|
||||
/* Extract a module from the library */
|
||||
{
|
||||
unsigned long ImportStart;
|
||||
unsigned long ExportStart;
|
||||
unsigned long StrPoolStart;
|
||||
unsigned long StrPoolSize;
|
||||
struct utimbuf U;
|
||||
ObjHeader H;
|
||||
FILE* Obj;
|
||||
unsigned I;
|
||||
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = GetModule (Name);
|
||||
|
||||
/* Try to find the module in the library */
|
||||
ObjData* O = FindObjData (Module);
|
||||
const ObjData* O = FindObjData (Module);
|
||||
|
||||
/* Bail out if the module does not exist */
|
||||
if (O == 0) {
|
||||
@ -287,39 +321,11 @@ void ObjExtract (const char* Name)
|
||||
Error ("Cannot open target file `%s': %s", Name, strerror (errno));
|
||||
}
|
||||
|
||||
/* Copy anything to the new file that has no special handling */
|
||||
/* Copy the complete object file data from the library to the new object
|
||||
* file.
|
||||
*/
|
||||
LibCopyFrom (O->Start, O->Size, Obj);
|
||||
|
||||
/* Write imports and exports */
|
||||
ImportStart = ftell (Obj);
|
||||
WriteData (Obj, O->Imports, O->ImportSize);
|
||||
ExportStart = ftell (Obj);
|
||||
WriteData (Obj, O->Exports, O->ExportSize);
|
||||
|
||||
/* Write the string pool */
|
||||
StrPoolStart = ftell (Obj);
|
||||
WriteVar (Obj, O->StringCount);
|
||||
for (I = 0; I < O->StringCount; ++I) {
|
||||
WriteStr (Obj, O->Strings[I]);
|
||||
}
|
||||
StrPoolSize = ftell (Obj) - StrPoolStart;
|
||||
|
||||
/* Seek back and read the header */
|
||||
fseek (Obj, 0, SEEK_SET);
|
||||
ObjReadHeader (Obj, &H, Name);
|
||||
|
||||
/* Update the header fields */
|
||||
H.ImportOffs = ImportStart;
|
||||
H.ImportSize = O->ImportSize;
|
||||
H.ExportOffs = ExportStart;
|
||||
H.ExportSize = O->ExportSize;
|
||||
H.StrPoolOffs = StrPoolStart;
|
||||
H.StrPoolSize = StrPoolSize;
|
||||
|
||||
/* Write the changed header */
|
||||
fseek (Obj, 0, SEEK_SET);
|
||||
ObjWriteHeader (Obj, &H);
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (Obj) != 0) {
|
||||
Error ("Problem closing object file `%s': %s", Name, strerror (errno));
|
||||
|
@ -40,8 +40,15 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* common */
|
||||
#include "objdefs.h"
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Forwards */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
struct ObjData;
|
||||
|
||||
|
||||
|
||||
@ -51,11 +58,10 @@
|
||||
|
||||
|
||||
|
||||
void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name);
|
||||
/* Read the header of the object file checking the signature */
|
||||
|
||||
void ObjWriteHeader (FILE* Obj, ObjHeader* H);
|
||||
/* Write the header of the object file */
|
||||
void ObjReadData (FILE* F, struct 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.
|
||||
*/
|
||||
|
||||
void ObjAdd (const char* Name);
|
||||
/* Add an object file to the library */
|
||||
@ -67,7 +73,7 @@ void ObjExtract (const char* Name);
|
||||
|
||||
/* End of objfile.h */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 1998-2010, Ullrich von Bassewitz */
|
||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -46,7 +46,7 @@
|
||||
|
||||
/* Defines for magic and version */
|
||||
#define LIB_MAGIC 0x7A55616E
|
||||
#define LIB_VERSION 0x000C
|
||||
#define LIB_VERSION 0x000D
|
||||
|
||||
/* Size of an library file header */
|
||||
#define LIB_HDR_SIZE 12
|
||||
|
Loading…
x
Reference in New Issue
Block a user