/* */
/* */
/* */
-/* (C) 1998 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <string.h>
#include <errno.h>
-#if defined(__WATCOMC__) || defined(_MSC_VER)
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__)
/* The Windows compilers have the file in the wrong directory */
# include <sys/utime.h>
#else
#include <time.h>
#include <sys/stat.h>
-#include "../common/xmalloc.h"
+/* common */
+#include "xmalloc.h"
+/* ar65 */
#include "error.h"
#include "objdata.h"
#include "fileio.h"
if (H->Version != OBJ_VERSION) {
Error ("Object file `%s' has wrong version", Name);
}
- H->Flags = Read16 (Obj);
- H->OptionOffs = Read32 (Obj);
- H->OptionSize = Read32 (Obj);
- H->FileOffs = Read32 (Obj);
- H->FileSize = Read32 (Obj);
- H->SegOffs = Read32 (Obj);
- H->SegSize = Read32 (Obj);
- H->ImportOffs = Read32 (Obj);
- H->ImportSize = Read32 (Obj);
- H->ExportOffs = Read32 (Obj);
- H->ExportSize = Read32 (Obj);
- H->DbgSymOffs = Read32 (Obj);
- H->DbgSymSize = Read32 (Obj);
+ H->Flags = Read16 (Obj);
+ H->OptionOffs = Read32 (Obj);
+ H->OptionSize = Read32 (Obj);
+ H->FileOffs = Read32 (Obj);
+ H->FileSize = Read32 (Obj);
+ H->SegOffs = Read32 (Obj);
+ H->SegSize = Read32 (Obj);
+ H->ImportOffs = Read32 (Obj);
+ H->ImportSize = Read32 (Obj);
+ H->ExportOffs = Read32 (Obj);
+ H->ExportSize = Read32 (Obj);
+ H->DbgSymOffs = Read32 (Obj);
+ H->DbgSymSize = Read32 (Obj);
+ H->LineInfoOffs = Read32 (Obj);
+ H->LineInfoSize = Read32 (Obj);
+ H->StrPoolOffs = Read32 (Obj);
+ H->StrPoolSize = Read32 (Obj);
+ H->AssertOffs = Read32 (Obj);
+ H->AssertSize = Read32 (Obj);
+ H->ScopeOffs = Read32 (Obj);
+ H->ScopeSize = Read32 (Obj);
}
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);
}
const char* Module;
ObjHeader H;
ObjData* O;
+ unsigned I;
/* Open the object file */
FILE* Obj = fopen (Name, "rb");
Error ("Could not open `%s': %s", Name, strerror (errno));
}
- /* Get the modification time of the object file */
- if (fstat (fileno (Obj), &StatBuf) != 0) {
+ /* 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 (stat (Name, &StatBuf) != 0) {
Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
}
}
/* Initialize the object module data structure */
- O->Name = xstrdup (Module);
- O->Flags = OBJ_HAVEDATA;
- O->MTime = StatBuf.st_mtime;
+ 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;
fseek (Obj, H.ExportOffs, SEEK_SET);
ReadData (Obj, O->Exports, O->ExportSize);
+ /* 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);
+ }
+
/* Skip the object file header */
O->Start = ftell (NewLib);
fseek (NewLib, OBJ_HDR_SIZE, SEEK_CUR);
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.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);
{
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);
Error ("Cannot open target file `%s': %s", Name, strerror (errno));
}
- /* Copy the first four segments including the header to the new file */
+ /* Copy anything to the new file that has no special handling */
LibCopyFrom (O->Start, O->Size, Obj);
/* Write imports and exports */
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.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);
-
-
-