/*****************************************************************************/ /* */ /* span.c */ /* */ /* A span of data within a segment */ /* */ /* */ /* */ /* (C) 2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ /* warranty. In no event will the authors be held liable for any damages */ /* arising from the use of this software. */ /* */ /* Permission is granted to anyone to use this software for any purpose, */ /* including commercial applications, and to alter it and redistribute it */ /* freely, subject to the following restrictions: */ /* */ /* 1. The origin of this software must not be misrepresented; you must not */ /* claim that you wrote the original software. If you use this software */ /* in a product, an acknowledgment in the product documentation would be */ /* appreciated but is not required. */ /* 2. Altered source versions must be plainly marked as such, and must not */ /* be misrepresented as being the original software. */ /* 3. This notice may not be removed or altered from any source */ /* distribution. */ /* */ /*****************************************************************************/ /* common */ #include "gentype.h" #include "xmalloc.h" /* ld65 */ #include "fileio.h" #include "objdata.h" #include "segments.h" #include "span.h" #include "tpool.h" /*****************************************************************************/ /* Data */ /*****************************************************************************/ /* 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 */ unsigned Type; /* Generic type of the data */ }; /*****************************************************************************/ /* Code */ /*****************************************************************************/ static Span* NewSpan (unsigned Id) /* Create and return a new span */ { /* Allocate memory */ Span* S = xmalloc (sizeof (Span)); /* Initialize the fields as necessary */ S->Id = Id; /* Return the result */ return S; } Span* ReadSpan (FILE* F, ObjData* O, unsigned Id) /* Read a Span from a file and return it */ { 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; } 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; } /* 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) { Spans[Count] = ReadVar (F); --Count; } /* Return the list */ return Spans; } unsigned* DupSpanList (const unsigned* S) /* Duplicate a span list */ { 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); } void FreeSpan (Span* S) /* Free a span structure */ { /* Just free the structure */ xfree (S); } 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) { /* Get this object file */ const ObjData* O = CollAtUnchecked (&ObjDataList, I); /* Count spans */ Count += CollCount (&O->Spans); } return Count; } 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) { /* Get this object file */ ObjData* O = CollAtUnchecked (&ObjDataList, I); /* Walk over all spans in this object file */ for (J = 0; J < CollCount (&O->Spans); ++J) { /* Get this span */ 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", 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); }