Addr = NewAddr;
}
- /* Relocate line information for this segment */
- RelocLineInfo (S->Seg);
-
} else if (S->Load == M) {
/* Handle ALIGN_LOAD */
unsigned I;
unsigned SymBaseId = 0;
unsigned ScopeBaseId = 0;
+ unsigned SpanBaseId = 0;
for (I = 0; I < CollCount (&ObjDataList); ++I) {
/* Get this module */
/* Assign base ids */
O->SymBaseId = SymBaseId;
O->ScopeBaseId = ScopeBaseId;
+ O->SpanBaseId = SpanBaseId;
/* Bump the base ids */
SymBaseId += CollCount (&O->DbgSyms);
ScopeBaseId += CollCount (&O->Scopes);
+ SpanBaseId += CollCount (&O->Spans);
}
/* Assign the ids to the file infos */
/* Output version information */
fprintf (F, "version\tmajor=2,minor=0\n");
-
+
/* Output a line with the item numbers so the debug info module is able
* to preallocate the required memory.
*/
-void FragResolveLineInfos (Fragment* F)
-/* Resolve the back pointers for the line infos */
-{
- unsigned I;
-
- /* Walk over all line infos for this fragment */
- for (I = 0; I < CollCount (&F->LineInfos); ++I) {
- /* Get a pointer to this line info */
- LineInfo* LI = CollAtUnchecked (&F->LineInfos, I);
-
- /* Add the back pointer to the line info */
- CollAppend (&LI->Fragments, F);
- }
-}
-
-
-
Fragment* NewFragment (unsigned char Type, unsigned Size, struct Section* S);
/* Create a new fragment and insert it into the section S */
-void FragResolveLineInfos (Fragment* F);
-/* Resolve the back pointers for the line infos */
-
#if defined(HAVE_INLINE)
INLINE const char* GetFragmentSourceName (const Fragment* F)
/* Return the name of the source file for this fragment */
#include "error.h"
#include "fileinfo.h"
#include "fileio.h"
-#include "fragment.h"
#include "lineinfo.h"
#include "objdata.h"
#include "segments.h"
LI->Pos.Name = INVALID_STRING_ID;
LI->Pos.Line = 0;
LI->Pos.Col = 0;
- LI->Fragments = EmptyCollection;
LI->Spans = EmptyCollection;
/* Return the new struct */
void FreeLineInfo (LineInfo* LI)
-/* Free a LineInfo structure. This function will not handle a non empty
- * Fragments collection, it can only be used to free incomplete line infos.
- */
+/* Free a LineInfo structure. */
{
- unsigned I;
-
- /* Check, check, ... */
- PRECONDITION (CollCount (&LI->Fragments) == 0);
-
- /* Free all the code ranges */
- for (I = 0; I < CollCount (&LI->Spans); ++I) {
- FreeSpan (CollAtUnchecked (&LI->Spans, I));
- }
-
/* Free the collections */
DoneCollection (&LI->Spans);
LineInfo* LI = NewLineInfo ();
/* Read/fill the fields in the new LineInfo */
- LI->Type = ReadVar (F);
LI->Pos.Line = ReadVar (F);
LI->Pos.Col = ReadVar (F);
LI->File = CollAt (&O->Files, ReadVar (F));
LI->Pos.Name = LI->File->Name;
+ LI->Type = ReadVar (F);
+ ReadSpans (&LI->Spans, F, O);
/* Return the struct read */
return LI;
-void RelocLineInfo (Segment* S)
-/* Relocate the line info for a segment. */
-{
- unsigned long Offs = S->PC;
-
- /* Loop over all sections in this segment */
- Section* Sec = S->SecRoot;
- while (Sec) {
- Fragment* Frag;
-
- /* Adjust for fill bytes */
- Offs += Sec->Fill;
-
- /* Loop over all fragments in this section */
- Frag = Sec->FragRoot;
- while (Frag) {
-
- unsigned I;
-
- /* Add the range for this fragment to all line infos */
- for (I = 0; I < CollCount (&Frag->LineInfos); ++I) {
- LineInfo* LI = CollAtUnchecked (&Frag->LineInfos, I);
- AddSpan (&LI->Spans, S, Offs, Frag->Size);
- }
-
- /* Update the offset */
- Offs += Frag->Size;
-
- /* Next fragment */
- Frag = Frag->Next;
- }
-
- /* Next section */
- Sec = Sec->Next;
- }
-}
-
-
-
void PrintDbgLineInfo (FILE* F)
/* Output the line infos to a debug info file */
{
/* Get a pointer to the spans */
const Collection* Spans = &LI->Spans;
- /* Spans */
- for (K = 0; K < CollCount (Spans); ++K) {
+ /* Print the start of the line */
+ fprintf (F,
+ "line\tid=%u,file=%u,line=%lu",
+ Id++, LI->File->Id, GetSourceLine (LI));
- /* Get this code range */
- const Span* S = CollConstAt (Spans, K);
+ /* Print type if not LI_TYPE_ASM and count if not zero */
+ if (Type != LI_TYPE_ASM) {
+ fprintf (F, ",type=%u", Type);
+ }
+ if (Count != 0) {
+ fprintf (F, ",count=%u", Count);
+ }
- /* Print it */
- fprintf (F,
- "line\tid=%u,file=%u,line=%lu,seg=%u,range=0x%lX-0x%lX",
- Id++, LI->File->Id, GetSourceLine (LI), S->Seg->Id,
- S->Offs, S->Offs + S->Size - 1);
+ /* Add spans if the line info has it */
+ if (CollCount (Spans) > 0) {
- /* Print type if not LI_TYPE_ASM and count if not zero */
- if (Type != LI_TYPE_ASM) {
- fprintf (F, ",type=%u", Type);
- }
- if (Count != 0) {
- fprintf (F, ",count=%u", Count);
- }
-
- /* Terminate line */
- fputc ('\n', F);
+ /* Output the first span */
+ fprintf (F, ",span=%u", SpanId (O, CollConstAt (Spans, 0)));
+ /* Output the other spans */
+ for (K = 1; K < CollCount (Spans); ++K) {
+ fprintf (F, "+%u", SpanId (O, CollConstAt (Spans, K)));
+ }
}
+
+ /* Terminate line */
+ fputc ('\n', F);
}
}
}
struct FileInfo* File; /* File struct for this line if any */
unsigned Type; /* Type of line info */
FilePos Pos; /* Position in file */
- Collection Fragments; /* Fragments for this line */
Collection Spans; /* Spans for this line */
};
/* Read a line info from a file and return it */
void FreeLineInfo (LineInfo* LI);
-/* Free a LineInfo structure. This function will not handle a non empty
- * Fragments collection, it can only be used to free incomplete line infos.
- */
+/* Free a LineInfo structure. */
void ReadLineInfoList (FILE* F, struct ObjData* O, Collection* LineInfos);
/* Read a list of line infos stored as a list of indices in the object file,
* make real line infos from them and place them into the passed collection.
*/
-void RelocLineInfo (struct Segment* S);
-/* Relocate the line info for a segment. */
-
#if defined(HAVE_INLINE)
INLINE const FilePos* GetSourcePos (const LineInfo* LI)
/* Return the source file position from the given line info */
/* Get the segment from the list node */
S = Seg [I];
- /* Relocate line info for this segment */
- RelocLineInfo (S->Seg);
-
/* Keep the user happy */
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
O->Flags = 0;
O->SymBaseId = 0;
O->ScopeBaseId = 0;
+ O->SpanBaseId = 0;
O->Files = EmptyCollection;
O->Sections = EmptyCollection;
O->Exports = EmptyCollection;
O->Strings = 0;
O->Assertions = EmptyCollection;
O->Scopes = EmptyCollection;
+ O->Spans = EmptyCollection;
/* Return the new entry */
return O;
xfree (O->Strings);
DoneCollection (&O->Assertions);
DoneCollection (&O->Scopes);
+ for (I = 0; I < CollCount (&O->Spans); ++I) {
+ FreeSpan (CollAtUnchecked (&O->Spans, I));
+ }
+ DoneCollection (&O->Spans);
+
xfree (O);
}
unsigned Flags;
unsigned SymBaseId; /* Debug info base id for symbols */
- unsigned ScopeBaseId; /* Debug info base if for scopes */
+ unsigned ScopeBaseId; /* Debug info base id for scopes */
+ unsigned SpanBaseId; /* Debug info base id for spans */
Collection Files; /* List of input files */
Collection Sections; /* List of all sections */
unsigned* Strings; /* List of global string indices */
Collection Assertions; /* List of module assertions */
Collection Scopes; /* List of scopes */
+ Collection Spans; /* List of spans */
};
}
/* Print the list of spans for this scope */
if (CollCount (&S->Spans) > 0) {
- const Span* SP = CollConstAt (&S->Spans, 0);
- fprintf (F, ",span=%u", SP->Id);
+ fprintf (F, ",span=%u", SpanId (O, CollConstAt (&S->Spans, 0)));
for (K = 1; K < CollCount (&S->Spans); ++K) {
- SP = CollConstAt (&S->Spans, K);
- fprintf (F, "+%u", SP->Id);
+ fprintf (F, "+%u", SpanId (O, CollConstAt (&S->Spans, K)));
}
}
/* Read the line infos into the list of the fragment */
ReadLineInfoList (F, O, &Frag->LineInfos);
- /* Resolve the back pointers */
- FragResolveLineInfos (Frag);
-
/* Remember the module we had this fragment from */
Frag->Obj = O;
}
-/* List of all spans */
-static Collection SpanList = STATIC_COLLECTION_INITIALIZER;
+/* Definition of a span */
+struct Span {
+ unsigned Id; /* Id of the span */
+ unsigned Sec; /* Section id of this span */
+ unsigned long Offs; /* Offset of span within segment */
+ unsigned long Size; /* Size of span */
+};
-Span* NewSpan (struct Segment* Seg, unsigned long Offs, unsigned long Size)
+static Span* NewSpan (unsigned Id, unsigned SecId, 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 (&SpanList);
- S->Seg = Seg;
+ S->Id = Id;
+ S->Sec = SecId;
S->Offs = Offs;
S->Size = Size;
- /* Remember this span in the global list */
- CollAppend (&SpanList, S);
-
/* Return the result */
return S;
}
Span* ReadSpan (FILE* F, ObjData* O)
/* Read a Span from a file and return it */
{
- /* Read the section id and translate it to a section pointer */
- Section* Sec = GetObjSection (O, ReadVar (F));
+ /* Create a new Span */
+ unsigned SecId = ReadVar (F);
+ unsigned long Offs = ReadVar (F);
+ unsigned Size = ReadVar (F);
+ Span* S = NewSpan (CollCount (&O->Spans), SecId, Offs, Size);
- /* Read the offset and relocate it */
- unsigned long Offs = ReadVar (F) + Sec->Offs;
+ /* Insert it into the collection of all spans of this object file */
+ CollAppend (&O->Spans, S);
- /* Create and return a new Span */
- return NewSpan (Sec->Seg, Offs, ReadVar (F));
+ /* And return it */
+ return S;
}
-void AddSpan (Collection* Spans, struct Segment* Seg, unsigned long Offs,
- unsigned long Size)
-/* Either add a new span to the ones already in the given collection, or - if
- * possible - merge it with adjacent ones that already exist.
- */
+unsigned SpanId (const struct ObjData* O, const Span* S)
+/* Return the global id of a span */
{
- unsigned I;
-
- /* We don't have many spans in a collection, so we do a linear search here.
- * The collection is kept sorted which eases our work here.
- */
- for (I = 0; I < CollCount (Spans); ++I) {
-
- /* Get the next span */
- Span* S = CollAtUnchecked (Spans, I);
-
- /* Must be same segment, otherwise we cannot merge */
- if (S->Seg != Seg) {
- continue;
- }
-
- /* Check if we can merge it */
- if (Offs < S->Offs) {
+ return O->SpanBaseId + S->Id;
+}
- /* Got the insert position */
- if (Offs + Size == S->Offs) {
- /* Merge the two */
- S->Offs = Offs;
- S->Size += Size;
- } else {
- /* Insert a new entry */
- CollInsert (Spans, NewSpan (Seg, Offs, Size), I);
- }
- /* Done */
- return;
- } else if (S->Offs + S->Size == Offs) {
+unsigned SpanCount (void)
+/* Return the total number of spans */
+{
+ /* Walk over all object files */
+ unsigned I;
+ unsigned Count = 0;
+ for (I = 0; I < CollCount (&ObjDataList); ++I) {
- /* This is the regular case. Merge the two. */
- S->Size += Size;
+ /* Get this object file */
+ const ObjData* O = CollAtUnchecked (&ObjDataList, I);
- /* Done */
- return;
- }
+ /* Count spans */
+ Count += CollCount (&O->Spans);
}
- /* We must append an entry */
- CollAppend (Spans, NewSpan (Seg, Offs, Size));
+ return Count;
}
-unsigned SpanCount (void)
-/* Return the total number of spans */
+void PrintDbgSpans (FILE* F)
+/* Output the spans to a debug info file */
{
- return CollCount (&SpanList);
-}
+ unsigned I, J;
+ /* Walk over all object files */
+ for (I = 0; I < CollCount (&ObjDataList); ++I) {
+ /* Get this object file */
+ ObjData* O = CollAtUnchecked (&ObjDataList, I);
-void PrintDbgSpans (FILE* F)
-/* Output the spans to a debug info file */
-{
- /* Walk over all spans */
- unsigned I;
- for (I = 0; I < CollCount (&SpanList); ++I) {
+ /* Walk over all spans in this object file */
+ for (J = 0; J < CollCount (&O->Spans); ++J) {
+
+ /* Get this span */
+ Span* S = CollAtUnchecked (&O->Spans, J);
- /* Get this span */
- const Span* S = CollAtUnchecked (&SpanList, I);
+ /* Get the section for this span */
+ const Section* Sec = GetObjSection (O, S->Sec);
- /* Output the data */
- fprintf (F, "span\tid=%u,seg=%u,start=%lu,size=%lu\n",
- S->Id, S->Seg->Id, S->Offs, S->Size);
+ /* Output the data */
+ fprintf (F, "span\tid=%u,seg=%u,start=%lu,size=%lu\n",
+ O->SpanBaseId + S->Id,
+ Sec->Seg->Id,
+ Sec->Offs + S->Offs,
+ S->Size);
+ }
}
}
+/* Span is an opaque type */
typedef struct Span Span;
-struct Span {
- unsigned Id; /* Id of the span */
- struct Segment* Seg; /* Segment of this span */
- unsigned long Offs; /* Offset of span within segment */
- unsigned long Size; /* Size of span */
-};
-Span* NewSpan (struct Segment* Seg, unsigned long Offs, 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 */
void FreeSpan (Span* S);
/* Free a span structure */
-void AddSpan (Collection* Spans, struct Segment* Seg, unsigned long Offs,
- unsigned long Size);
-/* Either add a new span to the ones already in the given collection, or - if
- * possible - merge it with adjacent ones that already exist.
- */
+unsigned SpanId (const struct ObjData* O, const Span* S);
+/* Return the global id of a span */
unsigned SpanCount (void);
/* Return the total number of spans */