1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-29 10:29:30 +00:00

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
This commit is contained in:
uz 2011-08-21 19:08:23 +00:00
parent 37ac033370
commit 358ccf236e
18 changed files with 396 additions and 111 deletions

View File

@ -116,6 +116,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
H->AssertSize = Read32 (Obj); H->AssertSize = Read32 (Obj);
H->ScopeOffs = Read32 (Obj); H->ScopeOffs = Read32 (Obj);
H->ScopeSize = Read32 (Obj); H->ScopeSize = Read32 (Obj);
H->SpanOffs = Read32 (Obj);
H->SpanSize = Read32 (Obj);
} }

View File

@ -272,7 +272,7 @@ void EndLine (LineInfo* LI)
/* End a line that is tracked by the given LineInfo structure */ /* End a line that is tracked by the given LineInfo structure */
{ {
/* Close the spans for the line */ /* 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 /* Move the spans to the list of all spans for this line, then clear the
* list of open spans. * list of open spans.
@ -308,7 +308,7 @@ LineInfo* StartLine (const FilePos* Pos, unsigned Type, unsigned Count)
} }
/* Open the spans for this line info */ /* Open the spans for this line info */
OpenSpans (&LI->OpenSpans); OpenSpanList (&LI->OpenSpans);
/* Add the line info to the list of current line infos */ /* Add the line info to the list of current line infos */
CollAppend (&CurLineInfo, LI); CollAppend (&CurLineInfo, LI);
@ -447,8 +447,6 @@ void WriteLineInfos (void)
{ {
unsigned I; unsigned I;
Collection EmptySpans = STATIC_COLLECTION_INITIALIZER;
/* Tell the object file module that we're about to write line infos */ /* Tell the object file module that we're about to write line infos */
ObjStartLineInfos (); ObjStartLineInfos ();
@ -467,22 +465,12 @@ void WriteLineInfos (void)
/* Write the type and count of the line info */ /* Write the type and count of the line info */
ObjWriteVar (LI->Key.Type); ObjWriteVar (LI->Key.Type);
/* Spans are only added to the debug file if debug information is /* Write the ids of the spans for this line */
* requested. Otherwise we write an empty list. WriteSpanList (&LI->Spans);
*/
if (DbgSyms) {
WriteSpans (&LI->Spans);
} else {
/* Write out an empty list */
WriteSpans (&EmptySpans);
}
} }
/* End of line infos */ /* End of line infos */
ObjEndLineInfos (); ObjEndLineInfos ();
/* For the sake of completeness, but not really necessary */
DoneCollection (&EmptySpans);
} }

View File

@ -72,6 +72,7 @@
#include "scanner.h" #include "scanner.h"
#include "segment.h" #include "segment.h"
#include "sizeof.h" #include "sizeof.h"
#include "span.h"
#include "spool.h" #include "spool.h"
#include "symbol.h" #include "symbol.h"
#include "symtab.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)), static void OptVerbose (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused))) const char* Arg attribute ((unused)))
/* Increase verbosity */ /* Increase verbosity */
{ {
++Verbosity; ++Verbosity;
@ -822,6 +823,9 @@ static void CreateObjFile (void)
/* Write the assertions */ /* Write the assertions */
WriteAssertions (); WriteAssertions ();
/* Write the spans */
WriteSpans ();
/* Write an updated header and close the file */ /* Write an updated header and close the file */
ObjClose (); ObjClose ();
} }
@ -950,7 +954,7 @@ int main (int argc, char* argv [])
break; break;
case 'V': case 'V':
OptVersion (Arg, 0); OptVersion (Arg, 0);
break; break;
case 'W': case 'W':

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* 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: Size of assertion table */
0, /* 32: Offset into scope table */ 0, /* 32: Offset into scope table */
0, /* 32: Size of 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.AssertSize);
ObjWrite32 (Header.ScopeOffs); ObjWrite32 (Header.ScopeOffs);
ObjWrite32 (Header.ScopeSize); ObjWrite32 (Header.ScopeSize);
ObjWrite32 (Header.SpanOffs);
ObjWrite32 (Header.SpanSize);
} }
@ -304,7 +308,7 @@ void ObjWriteBuf (const StrBuf* S)
* advance). * advance).
*/ */
ObjWriteVar (SB_GetLen (S)); 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;
}

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@ -149,6 +149,12 @@ void ObjStartScopes (void);
void ObjEndScopes (void); void ObjEndScopes (void);
/* Mark the end of the scope table */ /* 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 */ /* End of objfile.h */

View File

@ -34,21 +34,107 @@
/* common */ /* common */
#include "hashfunc.h"
#include "hashtab.h"
#include "xmalloc.h" #include "xmalloc.h"
/* ca65 */ /* ca65 */
#include "global.h"
#include "objfile.h" #include "objfile.h"
#include "segment.h" #include "segment.h"
#include "span.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 */ /* 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 */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@ -64,9 +150,12 @@ static Span* NewSpan (Segment* Seg, unsigned long Start, unsigned long End)
Span* S = xmalloc (sizeof (Span)); Span* S = xmalloc (sizeof (Span));
/* Initialize the struct */ /* Initialize the struct */
InitHashNode (&S->Node);
S->Id = ~0U;
S->Seg = Seg; S->Seg = Seg;
S->Start = Start; S->Start = Start;
S->End = End; S->End = End;
S->Type = 0;
/* Return the new struct */ /* Return the new struct */
return S; 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 /* 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 * spans. The currently active segment will be inserted first with all others
* following. * 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 /* 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. * of existing ones, and remove empty spans from the list.
*/ */
@ -141,7 +291,9 @@ void CloseSpans (Collection* Spans)
} else { } else {
/* Span is not empty */ /* Span is not empty */
S->End = S->Seg->PC; 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) void WriteSpanList (const Collection* Spans)
/* Write one span to the output file */
{
/* Done accept empty spans */
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);
}
void WriteSpans (const Collection* Spans)
/* Write a list of spans to the output file */ /* Write a list of spans to the output file */
{ {
unsigned I; unsigned I;
/* Write the number of spans */ /* We only write spans if debug info is enabled */
ObjWriteVar (CollCount (Spans)); if (DbgSyms == 0) {
/* Number of spans is zero */
ObjWriteVar (0);
} else {
/* Write the number of spans */
ObjWriteVar (CollCount (Spans));
/* Write the spans */ /* Write the spans */
for (I = 0; I < CollCount (Spans); ++I) { for (I = 0; I < CollCount (Spans); ++I) {
/* Write the next span */ /* Write the id of the next span */
WriteSpan (CollConstAt (Spans, I)); ObjWriteVar (((const Span*)CollConstAt (Spans, I))->Id);
}
} }
} }
static int CollectSpans (void* Entry, void* Data)
/* Collect all spans in a collection sorted by id */
{
/* 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;
/* 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);
}
/* Done writing the spans */
ObjEndSpans ();
}

View File

@ -40,12 +40,14 @@
/* common */ /* common */
#include "coll.h" #include "coll.h"
#include "gentype.h"
#include "hashtab.h"
#include "inline.h" #include "inline.h"
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@ -56,9 +58,12 @@ struct Segment;
/* Span definition */ /* Span definition */
typedef struct Span Span; typedef struct Span Span;
struct Span{ struct Span{
HashNode Node; /* Node for hash table */
unsigned Id; /* Id of span */
struct Segment* Seg; /* Pointer to segment */ struct Segment* Seg; /* Pointer to segment */
unsigned long Start; /* Start of range */ unsigned Start; /* Start of range */
unsigned long End; /* End 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) # define GetSpanSize(R) ((R)->End - (R)->Start)
#endif #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 /* 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 * spans. The currently active segment will be inserted first with all others
* following. * following.
*/ */
void CloseSpans (Collection* Spans); void CloseSpanList (Collection* Spans);
/* Close all open spans by setting PC to the current PC for the segment. */ /* 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 */ /* Write a list of spans to the output file */
void WriteSpans (void);
/* Write all spans to the object file */
/* End of span.h */ /* End of span.h */

View File

@ -235,7 +235,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
* space in any segment). * space in any segment).
*/ */
if (CurrentScope->Type <= SCOPE_HAS_DATA) { if (CurrentScope->Type <= SCOPE_HAS_DATA) {
OpenSpans (&CurrentScope->Spans); OpenSpanList (&CurrentScope->Spans);
} }
} }
@ -248,7 +248,7 @@ void SymLeaveLevel (void)
* open the spans. * open the spans.
*/ */
if (CurrentScope->Type <= SCOPE_HAS_DATA) { 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 /* 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 */ /* Spans for this scope */
WriteSpans (&S->Spans); WriteSpanList (&S->Spans);
/* Next scope */ /* Next scope */
S = S->Next; S = S->Next;

View File

@ -46,10 +46,10 @@
/* Defines for magic and version */ /* Defines for magic and version */
#define OBJ_MAGIC 0x616E7A55 #define OBJ_MAGIC 0x616E7A55
#define OBJ_VERSION 0x000E #define OBJ_VERSION 0x000F
/* Size of an object file header */ /* Size of an object file header */
#define OBJ_HDR_SIZE (22*4) #define OBJ_HDR_SIZE (24*4)
/* Flag bits */ /* Flag bits */
#define OBJ_FLAGS_DBGINFO 0x0001 /* File has debug info */ #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 AssertSize; /* 32: Size of assertion table */
unsigned long ScopeOffs; /* 32: Offset into scope table */ unsigned long ScopeOffs; /* 32: Offset into scope table */
unsigned long ScopeSize; /* 32: Size of 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 */
}; };

View File

@ -200,6 +200,8 @@ static void LibReadObjHeader (Library* L, ObjData* O)
O->Header.AssertSize = Read32 (L->F); O->Header.AssertSize = Read32 (L->F);
O->Header.ScopeOffs = Read32 (L->F); O->Header.ScopeOffs = Read32 (L->F);
O->Header.ScopeSize = 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->Flags = Read16 (L->F);
O->MTime = Read32 (L->F); O->MTime = Read32 (L->F);
O->Start = Read32 (L->F); O->Start = Read32 (L->F);
Read32 (L->F); /* Skip Size */ Read32 (L->F); /* Skip Size */
/* Done */ /* Done */
return O; return O;
@ -243,6 +245,9 @@ static void ReadBasicData (Library* L, ObjData* O)
/* Read the files list */ /* Read the files list */
ObjReadFiles (L->F, O->Start + O->Header.FileOffs, O); 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 */ /* Read the line infos */
ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O); ObjReadLineInfos (L->F, O->Start + O->Header.LineInfoOffs, O);

View File

@ -114,7 +114,7 @@ LineInfo* ReadLineInfo (FILE* F, ObjData* O)
LI->File = CollAt (&O->Files, ReadVar (F)); LI->File = CollAt (&O->Files, ReadVar (F));
LI->Pos.Name = LI->File->Name; LI->Pos.Name = LI->File->Name;
LI->Type = ReadVar (F); LI->Type = ReadVar (F);
ReadSpans (&LI->Spans, F, O); ReadSpanList (&LI->Spans, F, O);
/* Return the struct read */ /* Return the struct read */
return LI; return LI;

View File

@ -107,6 +107,8 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
H->AssertSize = Read32 (Obj); H->AssertSize = Read32 (Obj);
H->ScopeOffs = Read32 (Obj); H->ScopeOffs = Read32 (Obj);
H->ScopeSize = 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) void ObjAdd (FILE* Obj, const char* Name)
/* Add an object file to the module list */ /* 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 */ /* Read the files list from the object file */
ObjReadFiles (Obj, O->Header.FileOffs, O); 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 */ /* Read the line infos from the object file */
ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O); ObjReadLineInfos (Obj, O->Header.LineInfoOffs, O);

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* 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); void ObjReadScopes (FILE* F, unsigned long Pos, ObjData* O);
/* Read the scope table from a file at the given offset */ /* 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); void ObjAdd (FILE* F, const char* Name);
/* Add an object file to the module list */ /* Add an object file to the module list */

View File

@ -90,7 +90,7 @@ Scope* ReadScope (FILE* F, ObjData* Obj, unsigned Id)
} }
/* Read the spans for this scope */ /* Read the spans for this scope */
ReadSpans (&S->Spans, F, Obj); ReadSpanList (&S->Spans, F, Obj);
/* Return the new Scope */ /* Return the new Scope */
return S; return S;

View File

@ -34,6 +34,7 @@
/* common */ /* common */
#include "attrib.h"
#include "xmalloc.h" #include "xmalloc.h"
/* ld65 */ /* 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 */ /* Create and return a new span */
{ {
/* Allocate memory */ /* Allocate memory */
Span* S = xmalloc (sizeof (*S)); Span* S = xmalloc (sizeof (*S));
/* Initialize the fields */ /* Initialize the fields */
S->Id = CollCount (&Obj->Spans); S->Id = Id;
S->Sec = SecId; S->Sec = Sec;
S->Offs = Offs; S->Offs = Offs;
S->Size = Size; S->Size = Size;
/* Insert it into the collection of all spans of this object file */
CollAppend (&Obj->Spans, S);
/* Return the result */ /* Return the result */
return S; 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 */ /* Read a Span from a file and return it */
{ {
/* Create a new Span and return it */ /* Create a new Span and return it */
unsigned SecId = ReadVar (F); unsigned SecId = ReadVar (F);
unsigned long Offs = ReadVar (F); unsigned long Offs = ReadVar (F);
unsigned Size = 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) void ReadSpanList (Collection* Spans, FILE* F, ObjData* O)
/* Read a list of Spans from a file and return it */ /* Read a list of span ids from a file and return the spans for the ids */
{ {
/* First is number of Spans */ /* First is number of Spans */
unsigned Count = ReadVar (F); unsigned Count = ReadVar (F);
@ -110,7 +108,7 @@ void ReadSpans (Collection* Spans, FILE* F, ObjData* O)
/* Read the spans and add them */ /* Read the spans and add them */
while (Count--) { while (Count--) {
CollAppend (Spans, ReadSpan (F, O)); CollAppend (Spans, CollAt (&O->Spans, ReadVar (F)));
} }
} }

View File

@ -73,15 +73,11 @@ typedef struct Span Span;
Span* NewSpan (struct ObjData* Obj, unsigned SecId, unsigned long Offs, Span* ReadSpan (FILE* F, struct ObjData* O, unsigned Id);
unsigned long Size);
/* Create and return a new span */
Span* ReadSpan (FILE* F, struct ObjData* O);
/* Read a Span from a file and return it */ /* Read a Span from a file and return it */
void ReadSpans (Collection* Spans, FILE* F, struct ObjData* O); void ReadSpanList (Collection* Spans, FILE* F, struct ObjData* O);
/* Read a list of Spans from a file and return it */ /* Read a list of span ids from a file and return the spans for the ids */
void FreeSpan (Span* S); void FreeSpan (Span* S);
/* Free a span structure */ /* Free a span structure */

View File

@ -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) static void SkipExpr (FILE* F)
/* Skip an expression from the given file */ /* Skip an expression from the given file */
{ {
@ -772,13 +786,17 @@ void DumpObjLineInfo (FILE* F, unsigned long Offset)
for (I = 0; I < Count; ++I) { for (I = 0; I < Count; ++I) {
FilePos Pos; FilePos Pos;
unsigned Type;
/* Type of line info */
unsigned Type = ReadVar (F);
/* File position of line info */ /* File position of line info */
ReadFilePos (F, &Pos); ReadFilePos (F, &Pos);
/* Type of line info */
Type = ReadVar (F);
/* Skip the spans */
SkipSpanList (F);
/* Print the header */ /* Print the header */
printf (" Index:%27u\n", I); printf (" Index:%27u\n", I);
@ -834,8 +852,6 @@ void DumpObjScopes (FILE* F, unsigned long Offset)
const char* Name; const char* Name;
unsigned Len; unsigned Len;
unsigned SpanCount;
unsigned J;
/* Read the data */ /* Read the data */
unsigned ParentId = ReadVar (F); unsigned ParentId = ReadVar (F);
@ -869,17 +885,8 @@ void DumpObjScopes (FILE* F, unsigned long Offset)
printf (" Label id:%22u\n", LabelId); printf (" Label id:%22u\n", LabelId);
} }
/* Spans */ /* Skip the spans */
SpanCount = ReadVar (F); SkipSpanList (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));
}
} }
/* Destroy the string pool */ /* Destroy the string pool */

View File

@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2011, Ullrich von Bassewitz */
/* Römerstraße 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@ -53,7 +53,7 @@
void FileSetPos (FILE* F, unsigned long Pos) void FileSetPos (FILE* F, unsigned long Pos)
/* Seek to the given absolute position, fail on errors */ /* Seek to the given absolute position, fail on errors */
{ {
if (fseek (F, Pos, SEEK_SET) != 0) { if (fseek (F, Pos, SEEK_SET) != 0) {
Error ("Cannot seek: %s", strerror (errno)); Error ("Cannot seek: %s", strerror (errno));
} }
@ -229,6 +229,8 @@ void ReadObjHeader (FILE* F, ObjHeader* H)
H->AssertSize = Read32 (F); H->AssertSize = Read32 (F);
H->ScopeOffs = Read32 (F); H->ScopeOffs = Read32 (F);
H->ScopeSize = Read32 (F); H->ScopeSize = Read32 (F);
H->SpanOffs = Read32 (F);
H->SpanSize = Read32 (F);
} }