mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 02:32:06 +00:00
@@ -6,6 +6,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -33,6 +34,12 @@ struct SortedSection {
|
|||||||
struct SortedSection *next;
|
struct SortedSection *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SortedSymbol {
|
||||||
|
struct Symbol const *sym;
|
||||||
|
uint32_t idx;
|
||||||
|
uint16_t addr;
|
||||||
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
uint32_t nbBanks;
|
uint32_t nbBanks;
|
||||||
struct SortedSections {
|
struct SortedSections {
|
||||||
@@ -268,69 +275,86 @@ static struct SortedSection const **nextSection(struct SortedSection const **s1,
|
|||||||
return (*s1)->section->org < (*s2)->section->org ? s1 : s2;
|
return (*s1)->section->org < (*s2)->section->org ? s1 : s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comparator function for `qsort` to sort symbols
|
||||||
|
* Symbols are ordered by address, or else by original index for a stable sort
|
||||||
|
*/
|
||||||
|
static int compareSymbols(void const *a, void const *b)
|
||||||
|
{
|
||||||
|
struct SortedSymbol const *sym1 = (struct SortedSymbol const *)a;
|
||||||
|
struct SortedSymbol const *sym2 = (struct SortedSymbol const *)b;
|
||||||
|
|
||||||
|
if (sym1->addr != sym2->addr)
|
||||||
|
return sym1->addr < sym2->addr ? -1 : 1;
|
||||||
|
|
||||||
|
return sym1->idx < sym2->idx ? -1 : sym1->idx > sym2->idx ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a bank's contents to the sym file
|
* Write a bank's contents to the sym file
|
||||||
* @param bankSections The bank's sections
|
* @param bankSections The bank's sections
|
||||||
*/
|
*/
|
||||||
static void writeSymBank(struct SortedSections const *bankSections)
|
static void writeSymBank(struct SortedSections const *bankSections,
|
||||||
|
enum SectionType type, uint32_t bank)
|
||||||
{
|
{
|
||||||
if (!symFile)
|
if (!symFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct {
|
uint32_t nbSymbols = 0;
|
||||||
struct SortedSection const *sections;
|
|
||||||
#define sect sections->section /* Fake member as a shortcut */
|
|
||||||
uint32_t i;
|
|
||||||
struct Symbol const *sym;
|
|
||||||
uint16_t addr;
|
|
||||||
} sectList = { .sections = bankSections->sections, .i = 0 },
|
|
||||||
zlSectList = { .sections = bankSections->zeroLenSections, .i = 0 },
|
|
||||||
*minSectList;
|
|
||||||
|
|
||||||
for (;;) {
|
for (struct SortedSection const *ptr = bankSections->sections; ptr; ptr = ptr->next) {
|
||||||
while (sectList.sections
|
for (struct Section const *sect = ptr->section; sect; sect = sect->nextu)
|
||||||
&& sectList.i == sectList.sect->nbSymbols) {
|
nbSymbols += sect->nbSymbols;
|
||||||
sectList.sections = sectList.sections->next;
|
|
||||||
sectList.i = 0;
|
|
||||||
}
|
}
|
||||||
while (zlSectList.sections
|
for (struct SortedSection const *ptr = bankSections->zeroLenSections; ptr; ptr = ptr->next) {
|
||||||
&& zlSectList.i == zlSectList.sect->nbSymbols) {
|
for (struct Section const *sect = ptr->section; sect; sect = sect->nextu)
|
||||||
zlSectList.sections = zlSectList.sections->next;
|
nbSymbols += sect->nbSymbols;
|
||||||
zlSectList.i = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sectList.sections && !zlSectList.sections) {
|
if (!nbSymbols)
|
||||||
break;
|
return;
|
||||||
} else if (sectList.sections && zlSectList.sections) {
|
|
||||||
sectList.sym = sectList.sect->symbols[sectList.i];
|
|
||||||
zlSectList.sym = zlSectList.sect->symbols[zlSectList.i];
|
|
||||||
sectList.addr =
|
|
||||||
sectList.sym->offset + sectList.sect->org;
|
|
||||||
zlSectList.addr =
|
|
||||||
zlSectList.sym->offset + zlSectList.sect->org;
|
|
||||||
|
|
||||||
minSectList = sectList.addr < zlSectList.addr
|
struct SortedSymbol *symList = malloc(sizeof(*symList) * nbSymbols);
|
||||||
? §List
|
|
||||||
: &zlSectList;
|
|
||||||
} else if (sectList.sections) {
|
|
||||||
sectList.sym = sectList.sect->symbols[sectList.i];
|
|
||||||
sectList.addr =
|
|
||||||
sectList.sym->offset + sectList.sect->org;
|
|
||||||
|
|
||||||
minSectList = §List;
|
if (!symList)
|
||||||
} else {
|
err(1, "Failed to allocate symbol list");
|
||||||
zlSectList.sym = zlSectList.sect->symbols[zlSectList.i];
|
|
||||||
zlSectList.addr =
|
|
||||||
zlSectList.sym->offset + zlSectList.sect->org;
|
|
||||||
|
|
||||||
minSectList = &zlSectList;
|
uint32_t idx = 0;
|
||||||
|
|
||||||
|
for (struct SortedSection const *ptr = bankSections->sections; ptr; ptr = ptr->next) {
|
||||||
|
for (struct Section const *sect = ptr->section; sect; sect = sect->nextu) {
|
||||||
|
for (uint32_t i = 0; i < sect->nbSymbols; i++) {
|
||||||
|
symList[idx].idx = idx;
|
||||||
|
symList[idx].sym = sect->symbols[i];
|
||||||
|
symList[idx].addr = symList[idx].sym->offset + sect->org;
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (struct SortedSection const *ptr = bankSections->zeroLenSections; ptr; ptr = ptr->next) {
|
||||||
|
for (struct Section const *sect = ptr->section; sect; sect = sect->nextu) {
|
||||||
|
for (uint32_t i = 0; i < sect->nbSymbols; i++) {
|
||||||
|
symList[idx].idx = idx;
|
||||||
|
symList[idx].sym = sect->symbols[i];
|
||||||
|
symList[idx].addr = symList[idx].sym->offset + sect->org;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(idx == nbSymbols);
|
||||||
|
|
||||||
|
qsort(symList, nbSymbols, sizeof(*symList), compareSymbols);
|
||||||
|
|
||||||
|
uint32_t symBank = bank + bankranges[type][0];
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < nbSymbols; i++) {
|
||||||
|
struct SortedSymbol *sym = &symList[i];
|
||||||
|
|
||||||
fprintf(symFile, "%02" PRIx32 ":%04" PRIx16 " %s\n",
|
fprintf(symFile, "%02" PRIx32 ":%04" PRIx16 " %s\n",
|
||||||
minSectList->sect->bank, minSectList->addr,
|
symBank, sym->addr, sym->sym->name);
|
||||||
minSectList->sym->name);
|
|
||||||
minSectList->i++;
|
|
||||||
}
|
}
|
||||||
#undef sect
|
|
||||||
|
free(symList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,7 +467,7 @@ static void writeSymAndMap(void)
|
|||||||
for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) {
|
for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) {
|
||||||
struct SortedSections const *sect = §ions[type].banks[bank];
|
struct SortedSections const *sect = §ions[type].banks[bank];
|
||||||
|
|
||||||
writeSymBank(sect);
|
writeSymBank(sect, type, bank);
|
||||||
usedMap[type] += writeMapBank(sect, type, bank);
|
usedMap[type] += writeMapBank(sect, type, bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user