]> git.sur5r.net Git - cc65/blobdiff - src/ar65/objfile.c
Allow to set the ProDOS type and auxtype on creating new files in a similiar way...
[cc65] / src / ar65 / objfile.c
index 93fcfbf429a39ee86c4a4b00b5273d698a12dc37..11d4de8f7e55332c7224a0656aa6897889433b34 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                          */
 /*                                                                          */
 /*                                                                          */
-/* (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      */
@@ -35,7 +35,7 @@
 
 #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"
@@ -92,19 +94,27 @@ void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
     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);
 }
 
 
@@ -127,6 +137,14 @@ void ObjWriteHeader (FILE* Obj, ObjHeader* H)
     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);
 }
 
 
@@ -138,6 +156,7 @@ void ObjAdd (const char* Name)
     const char* Module;
     ObjHeader H;
     ObjData* O;
+    unsigned I;
 
     /* Open the object file */
     FILE* Obj = fopen (Name, "rb");
@@ -145,8 +164,15 @@ void ObjAdd (const char* Name)
        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));
     }
 
@@ -171,9 +197,9 @@ void ObjAdd (const char* Name)
     }
 
     /* 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;
@@ -185,6 +211,14 @@ void ObjAdd (const char* Name)
     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);
@@ -198,13 +232,20 @@ void ObjAdd (const char* Name)
     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);
@@ -224,10 +265,12 @@ void ObjExtract (const char* Name)
 {
     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);
@@ -246,7 +289,7 @@ void ObjExtract (const char* 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 */
@@ -255,15 +298,25 @@ void ObjExtract (const char* Name)
     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);
@@ -284,6 +337,3 @@ void ObjExtract (const char* Name)
 
 
 
-
-
-