/* common */
-#include "attrib.h"
+#include "gentype.h"
#include "xmalloc.h"
/* ld65 */
#include "objdata.h"
#include "segments.h"
#include "span.h"
+#include "tpool.h"
/* Definition of a span */
struct Span {
- unsigned Id; /* Id of the 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 */
+ unsigned Type; /* Generic type of the data */
};
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-static Span* NewSpan (unsigned Id, unsigned Sec, unsigned long Offs, unsigned long Size)
+static Span* NewSpan (unsigned Id)
/* Create and return a new span */
{
/* Allocate memory */
- Span* S = xmalloc (sizeof (*S));
+ Span* S = xmalloc (sizeof (Span));
- /* Initialize the fields */
+ /* Initialize the fields as necessary */
S->Id = Id;
- S->Sec = Sec;
- S->Offs = Offs;
- S->Size = Size;
/* Return the result */
return S;
-Span* ReadSpan (FILE* F, ObjData* O attribute ((unused)), unsigned Id)
+Span* ReadSpan (FILE* F, ObjData* O, 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 (Id, SecId, Offs, Size);
+ unsigned Type;
+
+ /* Create a new Span and initialize it */
+ Span* S = NewSpan (Id);
+ S->Sec = ReadVar (F);
+ S->Offs = ReadVar (F);
+ S->Size = ReadVar (F);
+
+ /* Read the type. An id of zero means an empty string (no need to check) */
+ Type = ReadVar (F);
+ if (Type == 0) {
+ S->Type = INVALID_TYPE_ID;
+ } else {
+ S->Type = GetTypeId (GetObjString (O, Type));
+ }
+
+ /* Return the new span */
+ return S;
}
-void ReadSpanList (Collection* Spans, FILE* F, ObjData* O)
-/* Read a list of span ids from a file and return the spans for the ids */
+unsigned* ReadSpanList (FILE* F)
+/* Read a list of span ids from a file. The list is returned as an array of
+** unsigneds, the first being the number of spans (never zero) followed by
+** the span ids. If the number of spans is zero, NULL is returned.
+*/
{
+ unsigned* Spans;
+
/* First is number of Spans */
unsigned Count = ReadVar (F);
+ if (Count == 0) {
+ return 0;
+ }
- /* Preallocate enough entries in the collection */
- CollGrow (Spans, Count);
+ /* Allocate memory for the list and set the count */
+ Spans = xmalloc ((Count + 1) * sizeof (*Spans));
+ *Spans = Count;
/* Read the spans and add them */
- while (Count--) {
- CollAppend (Spans, CollAt (&O->Spans, ReadVar (F)));
+ while (Count) {
+ Spans[Count] = ReadVar (F);
+ --Count;
}
+
+ /* Return the list */
+ return Spans;
}
-void FreeSpan (Span* S)
-/* Free a span structure */
+unsigned* DupSpanList (const unsigned* S)
+/* Duplicate a span list */
{
- /* Just free the structure */
- xfree (S);
+ unsigned Size;
+
+ /* The list may be empty */
+ if (S == 0) {
+ return 0;
+ }
+
+ /* Allocate memory, copy and return the new list */
+ Size = (*S + 1) * sizeof (*S);
+ return memcpy (xmalloc (Size), S, Size);
}
-unsigned SpanId (const struct ObjData* O, const Span* S)
-/* Return the global id of a span */
+void FreeSpan (Span* S)
+/* Free a span structure */
{
- return O->SpanBaseId + S->Id;
+ /* Just free the structure */
+ xfree (S);
}
+void PrintDbgSpanList (FILE* F, const ObjData* O, const unsigned* List)
+/* Output a string ",span=x[+y...]" for the given list. If the list is empty
+** or NULL, output nothing. This is a helper function for other modules to
+** print a list of spans read by ReadSpanList to the debug info file.
+*/
+{
+ if (List && *List) {
+ unsigned I;
+ const char* Format = ",span=%u";
+ for (I = 0; I < *List; ++I) {
+ fprintf (F, Format, O->SpanBaseId + List[I+1]);
+ Format = "+%u";
+ }
+ }
+}
+
+
+
void PrintDbgSpans (FILE* F)
/* Output the spans to a debug info file */
{
unsigned I, J;
+ StrBuf SpanType = STATIC_STRBUF_INITIALIZER;
+
/* Walk over all object files */
for (I = 0; I < CollCount (&ObjDataList); ++I) {
for (J = 0; J < CollCount (&O->Spans); ++J) {
/* Get this span */
- Span* S = CollAtUnchecked (&O->Spans, J);
+ const Span* S = CollAtUnchecked (&O->Spans, J);
/* 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",
+ fprintf (F, "span\tid=%u,seg=%u,start=%lu,size=%lu",
O->SpanBaseId + S->Id,
Sec->Seg->Id,
Sec->Offs + S->Offs,
S->Size);
- }
- }
-}
+ /* If we have a type, add it */
+ if (S->Type != INVALID_TYPE_ID) {
+ fprintf (F, ",type=%u", S->Type);
+ }
+ /* Terminate the output line */
+ fputc ('\n', F);
+ }
+ }
+ /* Free the string buffer */
+ SB_Done (&SpanType);
+}