From 358ccf236e016bb70fdc99fbb77ccec0cc02356c Mon Sep 17 00:00:00 2001 From: uz Date: Sun, 21 Aug 2011 19:08:23 +0000 Subject: [PATCH] Write spans out in a separate object file section. This allows to merge duplicate spans in an object file and more extensions to come. git-svn-id: svn://svn.cc65.org/cc65/trunk@5250 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ar65/objfile.c | 2 + src/ca65/lineinfo.c | 20 +--- src/ca65/main.c | 8 +- src/ca65/objfile.c | 30 ++++- src/ca65/objfile.h | 14 ++- src/ca65/span.c | 257 +++++++++++++++++++++++++++++++++++++++---- src/ca65/span.h | 29 ++++- src/ca65/symtab.c | 6 +- src/common/objdefs.h | 6 +- src/ld65/library.c | 7 +- src/ld65/lineinfo.c | 2 +- src/ld65/objfile.c | 24 ++++ src/ld65/objfile.h | 11 +- src/ld65/scopes.c | 2 +- src/ld65/span.c | 20 ++-- src/ld65/span.h | 10 +- src/od65/dump.c | 39 ++++--- src/od65/fileio.c | 12 +- 18 files changed, 392 insertions(+), 107 deletions(-) diff --git a/src/ar65/objfile.c b/src/ar65/objfile.c index 1696ecc0c..43862cb93 100644 --- a/src/ar65/objfile.c +++ b/src/ar65/objfile.c @@ -116,6 +116,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->AssertSize = Read32 (Obj); H->ScopeOffs = Read32 (Obj); H->ScopeSize = Read32 (Obj); + H->SpanOffs = Read32 (Obj); + H->SpanSize = Read32 (Obj); } diff --git a/src/ca65/lineinfo.c b/src/ca65/lineinfo.c index 50419c60e..e17aa251d 100644 --- a/src/ca65/lineinfo.c +++ b/src/ca65/lineinfo.c @@ -272,7 +272,7 @@ void EndLine (LineInfo* LI) /* End a line that is tracked by the given LineInfo structure */ { /* Close the spans for the line */ - CloseSpans (&LI->OpenSpans); + CloseSpanList (&LI->OpenSpans); /* Move the spans to the list of all spans for this line, then clear the * list of open spans. @@ -308,7 +308,7 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count) } /* Open the spans for this line info */ - OpenSpans (&LI->OpenSpans); + OpenSpanList (&LI->OpenSpans); /* Add the line info to the list of current line infos */ CollAppend (&CurLineInfo, LI); @@ -447,8 +447,6 @@ void WriteLineInfos (void) { unsigned I; - Collection EmptySpans = STATIC_COLLECTION_INITIALIZER; - /* Tell the object file module that we're about to write line infos */ ObjStartLineInfos (); @@ -467,22 +465,12 @@ void WriteLineInfos (void) /* Write the type and count of the line info */ ObjWriteVar (LI->Key.Type); - /* Spans are only added to the debug file if debug information is - * requested. Otherwise we write an empty list. - */ - if (DbgSyms) { - WriteSpans (&LI->Spans); - } else { - /* Write out an empty list */ - WriteSpans (&EmptySpans); - } + /* Write the ids of the spans for this line */ + WriteSpanList (&LI->Spans); } /* End of line infos */ ObjEndLineInfos (); - - /* For the sake of completeness, but not really necessary */ - DoneCollection (&EmptySpans); } diff --git a/src/ca65/main.c b/src/ca65/main.c index 8dc77a38d..240bf2ef2 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -72,6 +72,7 @@ #include "scanner.h" #include "segment.h" #include "sizeof.h" +#include "span.h" #include "spool.h" #include "symbol.h" #include "symtab.h" @@ -561,7 +562,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) static void OptVerbose (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Increase verbosity */ { ++Verbosity; @@ -822,6 +823,9 @@ static void CreateObjFile (void) /* Write the assertions */ WriteAssertions (); + /* Write the spans */ + WriteSpans (); + /* Write an updated header and close the file */ ObjClose (); } @@ -950,7 +954,7 @@ int main (int argc, char* argv []) break; case 'V': - OptVersion (Arg, 0); + OptVersion (Arg, 0); break; case 'W': diff --git a/src/ca65/objfile.c b/src/ca65/objfile.c index f9fba1521..199bc13c5 100644 --- a/src/ca65/objfile.c +++ b/src/ca65/objfile.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -86,6 +86,8 @@ static ObjHeader Header = { 0, /* 32: Size of assertion table */ 0, /* 32: Offset into scope table */ 0, /* 32: Size of scope table */ + 0, /* 32: Offset into span table */ + 0, /* 32: Size of span table */ }; @@ -142,6 +144,8 @@ static void ObjWriteHeader (void) ObjWrite32 (Header.AssertSize); ObjWrite32 (Header.ScopeOffs); ObjWrite32 (Header.ScopeSize); + ObjWrite32 (Header.SpanOffs); + ObjWrite32 (Header.SpanSize); } @@ -304,7 +308,7 @@ void ObjWriteBuf (const StrBuf* S) * advance). */ ObjWriteVar (SB_GetLen (S)); - ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S)); + ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S)); } @@ -495,3 +499,19 @@ void ObjEndScopes (void) +void ObjStartSpans (void) +/* Mark the start of the span table */ +{ + Header.SpanOffs = ftell (F); +} + + + +void ObjEndSpans (void) +/* Mark the end of the span table */ +{ + Header.SpanSize = ftell (F) - Header.SpanOffs; +} + + + diff --git a/src/ca65/objfile.h b/src/ca65/objfile.h index 3abcd7cf6..91987b3d9 100644 --- a/src/ca65/objfile.h +++ b/src/ca65/objfile.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -149,6 +149,12 @@ void ObjStartScopes (void); void ObjEndScopes (void); /* Mark the end of the scope table */ +void ObjStartSpans (void); +/* Mark the start of the span table */ + +void ObjEndSpans (void); +/* Mark the end of the span table */ + /* End of objfile.h */ diff --git a/src/ca65/span.c b/src/ca65/span.c index 3346eda0a..2fa823a8b 100644 --- a/src/ca65/span.c +++ b/src/ca65/span.c @@ -34,21 +34,107 @@ /* common */ +#include "hashfunc.h" +#include "hashtab.h" #include "xmalloc.h" /* ca65 */ +#include "global.h" #include "objfile.h" #include "segment.h" #include "span.h" +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +static unsigned HT_GenHash (const void* Key); +/* Generate the hash over a key. */ + +static const void* HT_GetKey (const void* Entry); +/* Given a pointer to the user entry data, return a pointer to the key */ + +static int HT_Compare (const void* Key1, const void* Key2); +/* Compare two keys. The function must return a value less than zero if + * Key1 is smaller than Key2, zero if both are equal, and a value greater + * than zero if Key1 is greater then Key2. + */ + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ +/* Hash table functions */ +static const HashFunctions HashFunc = { + HT_GenHash, + HT_GetKey, + HT_Compare +}; + +/* Span hash table */ +static HashTable SpanTab = STATIC_HASHTABLE_INITIALIZER (1051, &HashFunc); + + + +/*****************************************************************************/ +/* Hash table functions */ +/*****************************************************************************/ + + + +static unsigned HT_GenHash (const void* Key) +/* Generate the hash over a key. */ +{ + /* Key is a Span pointer */ + const Span* S = Key; + + /* Hash over a combination of segment number, start and end */ + return HashInt ((S->Seg->Num << 28) ^ (S->Start << 14) ^ S->End); +} + + + +static const void* HT_GetKey (const void* Entry) +/* Given a pointer to the user entry data, return a pointer to the key */ +{ + return Entry; +} + + + +static int HT_Compare (const void* Key1, const void* Key2) +/* Compare two keys. The function must return a value less than zero if + * Key1 is smaller than Key2, zero if both are equal, and a value greater + * than zero if Key1 is greater then Key2. + */ +{ + /* Convert both parameters to Span pointers */ + const Span* S1 = Key1; + const Span* S2 = Key2; + + /* Compare segment number, then start and end */ + int Res = (int)S2->Seg->Num - (int)S1->Seg->Num; + if (Res == 0) { + Res = (int)S2->Start - (int)S1->Start; + if (Res == 0) { + Res = (int)S2->End - (int)S1->End; + } + } + + /* Done */ + return Res; +} + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -64,9 +150,12 @@ static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End) Span* S = xmalloc (sizeof (Span)); /* Initialize the struct */ + InitHashNode (&S->Node); + S->Id = ~0U; S->Seg = Seg; S->Start = Start; S->End = End; + S->Type = 0; /* Return the new struct */ return S; @@ -82,7 +171,68 @@ static void FreeSpan (Span* S) -void OpenSpans (Collection* Spans) +static Span* MergeSpan (Span* S) +/* Check if we have a span with the same data as S already. If so, free S and + * return the already existing one. If not, remember S and return it. + */ +{ + /* Check if we have such a span already. If so use the existing + * one and free the one from the collection. If not, add the one to + * the hash table and return it. + */ + Span* E = HT_Find (&SpanTab, S); + if (E) { + /* If S has a type and E not, move the type */ + CHECK (E->Type == 0); + E->Type = S->Type; + S->Type = 0; + /* Free S and return E */ + FreeSpan (S); + return E; + } else { + /* Assign the id, insert S, then return it */ + S->Id = HT_GetCount (&SpanTab); + HT_Insert (&SpanTab, S); + return S; + } +} + + + +Span* OpenSpan (void) +/* Open a span for the active segment and return it. */ +{ + return NewSpan (ActiveSeg, ActiveSeg->PC, ActiveSeg->PC); +} + + + +Span* CloseSpan (Span* S) +/* Close the given span. Be sure to replace the passed span by the one + * returned, since the span will get deleted if it is empty or may be + * replaced if a duplicate exists. + */ +{ + /* Set the end offset */ + if (S->Start == S->Seg->PC) { + /* Span is empty */ + FreeSpan (S); + return 0; + } else { + /* Span is not empty */ + S->End = S->Seg->PC; + + /* Check if we have such a span already. If so use the existing + * one and free the one from the collection. If not, add the one to + * the hash table and return it. + */ + return MergeSpan (S); + } +} + + + +void OpenSpanList (Collection* Spans) /* Open a list of spans for all existing segments to the given collection of * spans. The currently active segment will be inserted first with all others * following. @@ -109,7 +259,7 @@ void OpenSpans (Collection* Spans) -void CloseSpans (Collection* Spans) +void CloseSpanList (Collection* Spans) /* Close a list of spans. This will add new segments to the list, mark the end * of existing ones, and remove empty spans from the list. */ @@ -141,7 +291,9 @@ void CloseSpans (Collection* Spans) } else { /* Span is not empty */ S->End = S->Seg->PC; - CollReplace (Spans, S, J++); + + /* Merge duplicate spans, then insert it at the new position */ + CollReplace (Spans, MergeSpan (S), J++); } } @@ -151,37 +303,96 @@ void CloseSpans (Collection* Spans) -static void WriteSpan (const Span* S) -/* Write one span to the output file */ +void WriteSpanList (const Collection* Spans) +/* Write a list of spans to the output file */ { - /* Done accept empty spans */ - CHECK (S->End > S->Start); + unsigned I; - /* Write data for the span We will write the size instead of the end - * offset to save some bytes, since most spans are expected to be - * rather small. - */ - ObjWriteVar (S->Seg->Num); - ObjWriteVar (S->Start); - ObjWriteVar (S->End - S->Start); + /* We only write spans if debug info is enabled */ + if (DbgSyms == 0) { + /* Number of spans is zero */ + ObjWriteVar (0); + } else { + /* Write the number of spans */ + ObjWriteVar (CollCount (Spans)); + + /* Write the spans */ + for (I = 0; I < CollCount (Spans); ++I) { + /* Write the id of the next span */ + ObjWriteVar (((const Span*)CollConstAt (Spans, I))->Id); + } + } } -void WriteSpans (const Collection* Spans) -/* Write a list of spans to the output file */ +static int CollectSpans (void* Entry, void* Data) +/* Collect all spans in a collection sorted by id */ { - unsigned I; + /* Cast the pointers to real objects */ + Span* S = Entry; + Collection* C = Data; + + /* Place the entry into the collection */ + CollReplaceExpand (C, S, S->Id); + + /* Keep the span */ + return 0; +} + + + +void WriteSpans (void) +/* Write all spans to the object file */ +{ + /* Tell the object file module that we're about to start the spans */ + ObjStartSpans (); + + /* We will write scopes only if debug symbols are requested */ + if (DbgSyms) { + + unsigned I; - /* Write the number of spans */ - ObjWriteVar (CollCount (Spans)); + /* We must first collect all items in a collection sorted by id */ + Collection SpanList = STATIC_COLLECTION_INITIALIZER; + CollGrow (&SpanList, HT_GetCount (&SpanTab)); + + /* Walk over the hash table and fill the span list */ + HT_Walk (&SpanTab, CollectSpans, &SpanList); + + /* Write the span count to the file */ + ObjWriteVar (CollCount (&SpanList)); + + /* Write all spans */ + for (I = 0; I < CollCount (&SpanList); ++I) { + + /* Get the span and check it */ + const Span* S = CollAtUnchecked (&SpanList, I); + CHECK (S->End > S->Start); + + /* Write data for the span We will write the size instead of the + * end offset to save some bytes, since most spans are expected + * to be rather small. + */ + ObjWriteVar (S->Seg->Num); + ObjWriteVar (S->Start); + ObjWriteVar (S->End - S->Start); + } + + /* Free the collection with the spans */ + DoneCollection (&SpanList); + + } else { + + /* No debug info requested */ + ObjWriteVar (0); - /* Write the spans */ - for (I = 0; I < CollCount (Spans); ++I) { - /* Write the next span */ - WriteSpan (CollConstAt (Spans, I)); } + + /* Done writing the spans */ + ObjEndSpans (); } + diff --git a/src/ca65/span.h b/src/ca65/span.h index 04af807a2..a1b85b2dc 100644 --- a/src/ca65/span.h +++ b/src/ca65/span.h @@ -40,12 +40,14 @@ /* common */ #include "coll.h" +#include "gentype.h" +#include "hashtab.h" #include "inline.h" /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ @@ -56,9 +58,12 @@ struct Segment; /* Span definition */ typedef struct Span Span; struct Span{ + HashNode Node; /* Node for hash table */ + unsigned Id; /* Id of span */ struct Segment* Seg; /* Pointer to segment */ - unsigned long Start; /* Start of range */ - unsigned long End; /* End of range */ + unsigned Start; /* Start of range */ + unsigned End; /* End of range */ + unsigned Type; /* Type of data in span */ }; @@ -79,18 +84,30 @@ INLINE unsigned long GetSpanSize (const Span* R) # define GetSpanSize(R) ((R)->End - (R)->Start) #endif -void OpenSpans (Collection* Spans); +Span* OpenSpan (void); +/* Open a span for the active segment and return it. */ + +Span* CloseSpan (Span* S); +/* Close the given span. Be sure to replace the passed span by the one + * returned, since the span will get deleted if it is empty or may be + * replaced if a duplicate exists. + */ + +void OpenSpanList (Collection* Spans); /* Open a list of spans for all existing segments to the given collection of * spans. The currently active segment will be inserted first with all others * following. */ -void CloseSpans (Collection* Spans); +void CloseSpanList (Collection* Spans); /* Close all open spans by setting PC to the current PC for the segment. */ -void WriteSpans (const Collection* Spans); +void WriteSpanList (const Collection* Spans); /* Write a list of spans to the output file */ +void WriteSpans (void); +/* Write all spans to the object file */ + /* End of span.h */ diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index bc64b0364..e0d6f8309 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -235,7 +235,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, * space in any segment). */ if (CurrentScope->Type <= SCOPE_HAS_DATA) { - OpenSpans (&CurrentScope->Spans); + OpenSpanList (&CurrentScope->Spans); } } @@ -248,7 +248,7 @@ void SymLeaveLevel (void) * open the spans. */ if (CurrentScope->Type <= SCOPE_HAS_DATA) { - CloseSpans (&CurrentScope->Spans); + CloseSpanList (&CurrentScope->Spans); } /* If we have spans, the first one is the segment that was active, when the @@ -983,7 +983,7 @@ void WriteScopes (void) } /* Spans for this scope */ - WriteSpans (&S->Spans); + WriteSpanList (&S->Spans); /* Next scope */ S = S->Next; diff --git a/src/common/objdefs.h b/src/common/objdefs.h index c336e9599..fcd448874 100644 --- a/src/common/objdefs.h +++ b/src/common/objdefs.h @@ -46,10 +46,10 @@ /* Defines for magic and version */ #define OBJ_MAGIC 0x616E7A55 -#define OBJ_VERSION 0x000E +#define OBJ_VERSION 0x000F /* Size of an object file header */ -#define OBJ_HDR_SIZE (22*4) +#define OBJ_HDR_SIZE (24*4) /* Flag bits */ #define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */ @@ -83,6 +83,8 @@ struct ObjHeader { unsigned long AssertSize; /* 32: Size of assertion table */ unsigned long ScopeOffs; /* 32: Offset into scope table */ unsigned long ScopeSize; /* 32: Size of scope table */ + unsigned long SpanOffs; /* 32: Offset into span table */ + unsigned long SpanSize; /* 32: Size of span table */ }; diff --git a/src/ld65/library.c b/src/ld65/library.c index 038c2d9ca..e05831d0c 100644 --- a/src/ld65/library.c +++ b/src/ld65/library.c @@ -200,6 +200,8 @@ static void LibReadObjHeader (Library* L, ObjData* O) O->Header.AssertSize = Read32 (L->F); O->Header.ScopeOffs = Read32 (L->F); O->Header.ScopeSize = Read32 (L->F); + O->Header.SpanOffs = Read32 (L->F); + O->Header.SpanSize = Read32 (L->F); } @@ -220,7 +222,7 @@ static ObjData* ReadIndexEntry (Library* L) O->Flags = Read16 (L->F); O->MTime = Read32 (L->F); O->Start = Read32 (L->F); - Read32 (L->F); /* Skip Size */ + Read32 (L->F); /* Skip Size */ /* Done */ return O; @@ -243,6 +245,9 @@ static void ReadBasicData (Library* L, ObjData* O) /* Read the files list */ ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O); + /* Read the spans */ + ObjReadSpans (L->F, O->Start + O->Header.SpanOffs, O); + /* Read the line infos */ ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O); diff --git a/src/ld65/lineinfo.c b/src/ld65/lineinfo.c index 1e60d8162..f53738c4d 100644 --- a/src/ld65/lineinfo.c +++ b/src/ld65/lineinfo.c @@ -114,7 +114,7 @@ LineInfo* ReadLineInfo (FILE* F, ObjData* O) LI->File = CollAt (&O->Files, ReadVar (F)); LI->Pos.Name = LI->File->Name; LI->Type = ReadVar (F); - ReadSpans (&LI->Spans, F, O); + ReadSpanList (&LI->Spans, F, O); /* Return the struct read */ return LI; diff --git a/src/ld65/objfile.c b/src/ld65/objfile.c index 66bcc64fe..7e914a572 100644 --- a/src/ld65/objfile.c +++ b/src/ld65/objfile.c @@ -107,6 +107,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name) H->AssertSize = Read32 (Obj); H->ScopeOffs = Read32 (Obj); H->ScopeSize = Read32 (Obj); + H->SpanOffs = Read32 (Obj); + H->SpanSize = Read32 (Obj); } @@ -281,6 +283,25 @@ void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O) +void ObjReadSpans (FILE* F, unsigned long Pos, ObjData* O) +/* Read the span table from a file at the given offset */ +{ + unsigned I; + unsigned SpanCount; + + /* Seek to the correct position */ + FileSetPos (F, Pos); + + /* Read the data */ + SpanCount = ReadVar (F); + CollGrow (&O->Spans, SpanCount); + for (I = 0; I < SpanCount; ++I) { + CollAppend (&O->Spans, ReadSpan (F, O, I)); + } +} + + + void ObjAdd (FILE* Obj, const char* Name) /* Add an object file to the module list */ { @@ -302,6 +323,9 @@ void ObjAdd (FILE* Obj, const char* Name) /* Read the files list from the object file */ ObjReadFiles (Obj, O->Header.FileOffs, O); + /* Read the spans from the object file */ + ObjReadSpans (Obj, O->Header.SpanOffs, O); + /* Read the line infos from the object file */ ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O); diff --git a/src/ld65/objfile.h b/src/ld65/objfile.h index f26d5bdd5..1b7796625 100644 --- a/src/ld65/objfile.h +++ b/src/ld65/objfile.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -81,6 +81,9 @@ void ObjReadAssertions (FILE* F, unsigned long Pos, ObjData* O); void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O); /* Read the scope table from a file at the given offset */ +void ObjReadSpans (FILE* F, unsigned long Pos, ObjData* O); +/* Read the span table from a file at the given offset */ + void ObjAdd (FILE* F, const char* Name); /* Add an object file to the module list */ diff --git a/src/ld65/scopes.c b/src/ld65/scopes.c index 60f66044a..62a5e30a4 100644 --- a/src/ld65/scopes.c +++ b/src/ld65/scopes.c @@ -90,7 +90,7 @@ Scope* ReadScope (FILE* F, ObjData* Obj, unsigned Id) } /* Read the spans for this scope */ - ReadSpans (&S->Spans, F, Obj); + ReadSpanList (&S->Spans, F, Obj); /* Return the new Scope */ return S; diff --git a/src/ld65/span.c b/src/ld65/span.c index 68c505951..da8cd83dd 100644 --- a/src/ld65/span.c +++ b/src/ld65/span.c @@ -34,6 +34,7 @@ /* common */ +#include "attrib.h" #include "xmalloc.h" /* ld65 */ @@ -66,41 +67,38 @@ struct Span { -Span* NewSpan (ObjData* Obj, unsigned SecId, unsigned long Offs, unsigned long Size) +static Span* NewSpan (unsigned Id, unsigned Sec, unsigned long Offs, unsigned long Size) /* Create and return a new span */ { /* Allocate memory */ Span* S = xmalloc (sizeof (*S)); /* Initialize the fields */ - S->Id = CollCount (&Obj->Spans); - S->Sec = SecId; + S->Id = Id; + S->Sec = Sec; S->Offs = Offs; S->Size = Size; - /* Insert it into the collection of all spans of this object file */ - CollAppend (&Obj->Spans, S); - /* Return the result */ return S; } -Span* ReadSpan (FILE* F, ObjData* O) +Span* ReadSpan (FILE* F, ObjData* O attribute ((unused)), unsigned Id) /* Read a Span from a file and return it */ { /* Create a new Span and return it */ unsigned SecId = ReadVar (F); unsigned long Offs = ReadVar (F); unsigned Size = ReadVar (F); - return NewSpan (O, SecId, Offs, Size); + return NewSpan (Id, SecId, Offs, Size); } -void ReadSpans (Collection* Spans, FILE* F, ObjData* O) -/* Read a list of Spans from a file and return it */ +void ReadSpanList (Collection* Spans, FILE* F, ObjData* O) +/* Read a list of span ids from a file and return the spans for the ids */ { /* First is number of Spans */ unsigned Count = ReadVar (F); @@ -110,7 +108,7 @@ void ReadSpans (Collection* Spans, FILE* F, ObjData* O) /* Read the spans and add them */ while (Count--) { - CollAppend (Spans, ReadSpan (F, O)); + CollAppend (Spans, CollAt (&O->Spans, ReadVar (F))); } } diff --git a/src/ld65/span.h b/src/ld65/span.h index 54726f6de..f3b00e568 100644 --- a/src/ld65/span.h +++ b/src/ld65/span.h @@ -73,15 +73,11 @@ typedef struct Span Span; -Span* NewSpan (struct ObjData* Obj, unsigned SecId, unsigned long Offs, - unsigned long Size); -/* Create and return a new span */ - -Span* ReadSpan (FILE* F, struct ObjData* O); +Span* ReadSpan (FILE* F, struct ObjData* O, unsigned Id); /* Read a Span from a file and return it */ -void ReadSpans (Collection* Spans, FILE* F, struct ObjData* O); -/* Read a list of Spans from a file and return it */ +void ReadSpanList (Collection* Spans, FILE* F, struct ObjData* O); +/* Read a list of span ids from a file and return the spans for the ids */ void FreeSpan (Span* S); /* Free a span structure */ diff --git a/src/od65/dump.c b/src/od65/dump.c index 1025f6c28..e4ebcff7a 100644 --- a/src/od65/dump.c +++ b/src/od65/dump.c @@ -136,6 +136,20 @@ static void SkipLineInfoList (FILE* F) +static void SkipSpanList (FILE* F) +/* Skip a span list from the given file */ +{ + /* Count preceeds the list */ + unsigned long Count = ReadVar (F); + + /* Skip indices */ + while (Count--) { + (void) ReadVar (F); + } +} + + + static void SkipExpr (FILE* F) /* Skip an expression from the given file */ { @@ -772,13 +786,17 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset) for (I = 0; I < Count; ++I) { FilePos Pos; - - /* Type of line info */ - unsigned Type = ReadVar (F); + 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); @@ -834,8 +852,6 @@ void DumpObjScopes (FILE* F, unsigned long Offset) const char* Name; unsigned Len; - unsigned SpanCount; - unsigned J; /* Read the data */ unsigned ParentId = ReadVar (F); @@ -869,17 +885,8 @@ void DumpObjScopes (FILE* F, unsigned long Offset) printf (" Label id:%22u\n", LabelId); } - /* Spans */ - SpanCount = ReadVar (F); - printf (" Segment spans:\n"); - printf (" Count:%23u\n", SpanCount); - - for (J = 0; J < SpanCount; ++J) { - printf (" Index:%23u\n", J); - printf (" Segment:%19lu\n", ReadVar (F)); - printf (" Start:%13s0x%06lX\n", "", ReadVar (F)); - printf (" Size:%14s0x%06lX\n", "", ReadVar (F)); - } + /* Skip the spans */ + SkipSpanList (F); } /* Destroy the string pool */ diff --git a/src/od65/fileio.c b/src/od65/fileio.c index 4a061af94..a14935006 100644 --- a/src/od65/fileio.c +++ b/src/od65/fileio.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -53,7 +53,7 @@ void FileSetPos (FILE* F, unsigned long Pos) /* Seek to the given absolute position, fail on errors */ -{ +{ if (fseek (F, Pos, SEEK_SET) != 0) { Error ("Cannot seek: %s", strerror (errno)); } @@ -229,6 +229,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H) H->AssertSize = Read32 (F); H->ScopeOffs = Read32 (F); H->ScopeSize = Read32 (F); + H->SpanOffs = Read32 (F); + H->SpanSize = Read32 (F); } -- 2.39.5