Manage the segments in a collection.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5125 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2011-08-05 13:59:26 +00:00
parent 9f02a29dfa
commit 6172979c1c
2 changed files with 41 additions and 59 deletions

View File

@@ -38,6 +38,7 @@
/* common */ /* common */
#include "check.h" #include "check.h"
#include "coll.h"
#include "exprdefs.h" #include "exprdefs.h"
#include "fragdefs.h" #include "fragdefs.h"
#include "hashstr.h" #include "hashstr.h"
@@ -67,10 +68,10 @@
/* Hash table */ /* Hash table */
#define HASHTAB_MASK 0x3FU #define HASHTAB_MASK 0x3FU
#define HASHTAB_SIZE (HASHTAB_MASK + 1) #define HASHTAB_SIZE (HASHTAB_MASK + 1)
static Segment* HashTab [HASHTAB_SIZE]; static Segment* HashTab[HASHTAB_SIZE];
static unsigned SegCount = 0; /* Segment count */ /* List of all segments */
static Segment* SegRoot = 0; /* List of all segments */ static Collection SegmentList = STATIC_COLLECTION_INITIALIZER;
@@ -107,14 +108,8 @@ static Segment* NewSegment (unsigned Name, unsigned char AddrSize)
S->Dumped = 0; S->Dumped = 0;
/* Insert the segment into the segment list and assign the segment id */ /* Insert the segment into the segment list and assign the segment id */
if (SegRoot == 0) { S->Id = CollCount (&SegmentList);
S->Id = 0; CollAppend (&SegmentList, S);
} else {
S->Id = SegRoot->Id + 1;
}
S->List = SegRoot;
SegRoot = S;
++SegCount;
/* Insert the segment into the segment hash list */ /* Insert the segment into the segment hash list */
Hash = (S->Name & HASHTAB_MASK); Hash = (S->Name & HASHTAB_MASK);
@@ -352,29 +347,30 @@ void SegDump (void)
unsigned I; unsigned I;
unsigned long Count; unsigned long Count;
unsigned char* Data; unsigned char* Data;
Segment* Seg = SegRoot; for (I = 0; I < CollCount (&SegmentList); ++I) {
while (Seg) { const Segment* Seg = CollConstAt (&SegmentList, I);
Section* S = Seg->SecRoot; Section* S = Seg->SecRoot;
printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size); printf ("Segment: %s (%lu)\n", GetString (Seg->Name), Seg->Size);
while (S) { while (S) {
unsigned J;
Fragment* F = S->FragRoot; Fragment* F = S->FragRoot;
printf (" Section:\n"); printf (" Section:\n");
while (F) { while (F) {
switch (F->Type) { switch (F->Type) {
case FRAG_LITERAL: case FRAG_LITERAL:
printf (" Literal (%u bytes):", F->Size); printf (" Literal (%u bytes):", F->Size);
Count = F->Size; Count = F->Size;
Data = F->LitBuf; Data = F->LitBuf;
I = 100; J = 100;
while (Count--) { while (Count--) {
if (I > 75) { if (J > 75) {
printf ("\n "); printf ("\n ");
I = 3; J = 3;
} }
printf (" %02X", *Data++); printf (" %02X", *Data++);
I += 3; J += 3;
} }
printf ("\n"); printf ("\n");
break; break;
@@ -402,7 +398,6 @@ void SegDump (void)
} }
S = S->Next; S = S->Next;
} }
Seg = Seg->List;
} }
} }
@@ -574,44 +569,28 @@ static int CmpSegStart (const void* K1, const void* K2)
void PrintSegmentMap (FILE* F) void PrintSegmentMap (FILE* F)
/* Print a segment map to the given file */ /* Print a segment map to the given file */
{ {
unsigned I;
Segment* S;
Segment** SegPool;
/* Allocate memory for the segment pool */ /* Allocate memory for the segment pool */
SegPool = xmalloc (SegCount * sizeof (Segment*)); Segment** SegPool = xmalloc (CollCount (&SegmentList) * sizeof (Segment*));
/* Collect pointers to the segments */ /* Copy the segment pointers */
I = 0; unsigned I;
S = SegRoot; for (I = 0; I < CollCount (&SegmentList); ++I) {
while (S) { SegPool[I] = CollAtUnchecked (&SegmentList, I);
/* Check the count for safety */
CHECK (I < SegCount);
/* Remember the pointer */
SegPool [I] = S;
/* Follow the linked list */
S = S->List;
/* Next array index */
++I;
} }
CHECK (I == SegCount);
/* Sort the array by increasing start addresses */ /* Sort the array by increasing start addresses */
qsort (SegPool, SegCount, sizeof (Segment*), CmpSegStart); qsort (SegPool, CollCount (&SegmentList), sizeof (Segment*), CmpSegStart);
/* Print a header */ /* Print a header */
fprintf (F, "Name Start End Size\n" fprintf (F, "Name Start End Size\n"
"--------------------------------------------\n"); "--------------------------------------------\n");
/* Print the segments */ /* Print the segments */
for (I = 0; I < SegCount; ++I) { for (I = 0; I < CollCount (&SegmentList); ++I) {
/* Get a pointer to the segment */ /* Get a pointer to the segment */
S = SegPool [I]; Segment* S = SegPool[I];
/* Print empty segments only if explicitly requested */ /* Print empty segments only if explicitly requested */
if (VerboseMap || S->Size > 0) { if (VerboseMap || S->Size > 0) {
@@ -634,10 +613,13 @@ void PrintSegmentMap (FILE* F)
void PrintDbgSegments (FILE* F) void PrintDbgSegments (FILE* F)
/* Output the segments to the debug file */ /* Output the segments to the debug file */
{ {
/* Walk over all segments */ /* Walk over all segments */
Segment* S = SegRoot; unsigned I;
while (S) { for (I = 0; I < CollCount (&SegmentList); ++I) {
/* Get the next segment */
const Segment* S = CollAtUnchecked (&SegmentList, I);
/* Print the segment data */ /* Print the segment data */
fprintf (F, fprintf (F,
@@ -650,10 +632,7 @@ void PrintDbgSegments (FILE* F)
S->OutputName, S->OutputOffs); S->OutputName, S->OutputOffs);
} }
fputc ('\n', F); fputc ('\n', F);
}
/* Follow the linked list */
S = S->List;
}
} }
@@ -663,13 +642,17 @@ void CheckSegments (void)
* not written to the output file. Output an error if this is the case. * not written to the output file. Output an error if this is the case.
*/ */
{ {
Segment* S = SegRoot; unsigned I;
while (S) { for (I = 0; I < CollCount (&SegmentList); ++I) {
/* Get the next segment */
const Segment* S = CollAtUnchecked (&SegmentList, I);
/* Check it */
if (S->Size > 0 && S->Dumped == 0) { if (S->Size > 0 && S->Dumped == 0) {
Error ("Missing memory area assignment for segment `%s'", Error ("Missing memory area assignment for segment `%s'",
GetString (S->Name)); GetString (S->Name));
} }
S = S->List;
} }
} }

View File

@@ -57,7 +57,6 @@ struct Segment {
unsigned Name; /* Name index of the segment */ unsigned Name; /* Name index of the segment */
unsigned Id; /* Segment id for debug info */ unsigned Id; /* Segment id for debug info */
Segment* Next; /* Hash list */ Segment* Next; /* Hash list */
Segment* List; /* List of all segments */
struct Section* SecRoot; /* Section list */ struct Section* SecRoot; /* Section list */
struct Section* SecLast; /* Pointer to last section */ struct Section* SecLast; /* Pointer to last section */
unsigned long PC; /* PC were this segment is located */ unsigned long PC; /* PC were this segment is located */