mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use std::map for rgblink symbols and sections
This commit is contained in:
@@ -57,12 +57,9 @@ struct Section {
|
|||||||
/*
|
/*
|
||||||
* Execute a callback for each section currently registered.
|
* Execute a callback for each section currently registered.
|
||||||
* This is to avoid exposing the data structure in which sections are stored.
|
* This is to avoid exposing the data structure in which sections are stored.
|
||||||
* @param callback The function to call for each structure;
|
* @param callback The function to call for each structure.
|
||||||
* the first argument will be a pointer to the structure,
|
|
||||||
* the second argument will be the pointer `arg`.
|
|
||||||
* @param arg A pointer which will be passed to all calls to `callback`.
|
|
||||||
*/
|
*/
|
||||||
void sect_ForEach(void (*callback)(struct Section *, void *), void *arg);
|
void sect_ForEach(void (*callback)(struct Section *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Registers a section to be processed.
|
* Registers a section to be processed.
|
||||||
|
|||||||
@@ -344,9 +344,8 @@ static struct UnassignedSection *sections;
|
|||||||
* Categorize a section depending on how constrained it is
|
* Categorize a section depending on how constrained it is
|
||||||
* This is so the most-constrained sections are placed first
|
* This is so the most-constrained sections are placed first
|
||||||
* @param section The section to categorize
|
* @param section The section to categorize
|
||||||
* @param arg Callback arg, unused
|
|
||||||
*/
|
*/
|
||||||
static void categorizeSection(struct Section *section, void *)
|
static void categorizeSection(struct Section *section)
|
||||||
{
|
{
|
||||||
uint8_t constraints = 0;
|
uint8_t constraints = 0;
|
||||||
|
|
||||||
@@ -385,7 +384,7 @@ void assign_AssignSections(void)
|
|||||||
initFreeSpace();
|
initFreeSpace();
|
||||||
|
|
||||||
nbSectionsToAssign = 0;
|
nbSectionsToAssign = 0;
|
||||||
sect_ForEach(categorizeSection, NULL);
|
sect_ForEach(categorizeSection);
|
||||||
|
|
||||||
// Place sections, starting with the most constrained
|
// Place sections, starting with the most constrained
|
||||||
|
|
||||||
|
|||||||
@@ -661,7 +661,7 @@ static void freeNode(struct FileStackNode *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void freeSection(struct Section *section, void *)
|
static void freeSection(struct Section *section)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
struct Section *next = section->nextu;
|
struct Section *next = section->nextu;
|
||||||
@@ -698,7 +698,7 @@ void obj_Cleanup(void)
|
|||||||
|
|
||||||
sym_CleanupSymbols();
|
sym_CleanupSymbols();
|
||||||
|
|
||||||
sect_ForEach(freeSection, NULL);
|
sect_ForEach(freeSection);
|
||||||
sect_CleanupSections();
|
sect_CleanupSections();
|
||||||
|
|
||||||
for (struct SymbolList &list : symbolLists) {
|
for (struct SymbolList &list : symbolLists) {
|
||||||
|
|||||||
@@ -556,9 +556,8 @@ static void applyFilePatches(struct Section *section, struct Section *dataSectio
|
|||||||
/*
|
/*
|
||||||
* Applies all of a section's patches, iterating over "components" of unionized sections
|
* Applies all of a section's patches, iterating over "components" of unionized sections
|
||||||
* @param section The section to patch
|
* @param section The section to patch
|
||||||
* @param arg Ignored callback arg
|
|
||||||
*/
|
*/
|
||||||
static void applyPatches(struct Section *section, void *)
|
static void applyPatches(struct Section *section)
|
||||||
{
|
{
|
||||||
if (!sect_HasData(section->type))
|
if (!sect_HasData(section->type))
|
||||||
return;
|
return;
|
||||||
@@ -570,7 +569,7 @@ static void applyPatches(struct Section *section, void *)
|
|||||||
void patch_ApplyPatches(void)
|
void patch_ApplyPatches(void)
|
||||||
{
|
{
|
||||||
initRPNStack();
|
initRPNStack();
|
||||||
sect_ForEach(applyPatches, NULL);
|
sect_ForEach(applyPatches);
|
||||||
freeRPNStack();
|
freeRPNStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,35 +2,23 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <map>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "link/main.hpp"
|
#include "link/main.hpp"
|
||||||
#include "link/section.hpp"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "hashmap.hpp"
|
|
||||||
#include "linkdefs.hpp"
|
#include "linkdefs.hpp"
|
||||||
|
|
||||||
HashMap sections;
|
std::map<std::string, struct Section *> sections;
|
||||||
|
|
||||||
struct ForEachSectionArg {
|
void sect_ForEach(void (*callback)(struct Section *))
|
||||||
void (*callback)(struct Section *section, void *arg);
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void forEach(void *section, void *arg)
|
|
||||||
{
|
{
|
||||||
struct ForEachSectionArg *callbackArg = (struct ForEachSectionArg *)arg;
|
for (auto &it : sections)
|
||||||
|
callback(it.second);
|
||||||
callbackArg->callback((struct Section *)section, callbackArg->arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sect_ForEach(void (*callback)(struct Section *, void *), void *arg)
|
|
||||||
{
|
|
||||||
struct ForEachSectionArg callbackArg = { .callback = callback, .arg = arg};
|
|
||||||
|
|
||||||
hash_ForEach(sections, forEach, &callbackArg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkSectUnionCompat(struct Section *target, struct Section *other)
|
static void checkSectUnionCompat(struct Section *target, struct Section *other)
|
||||||
@@ -190,9 +178,7 @@ static void mergeSections(struct Section *target, struct Section *other, enum Se
|
|||||||
void sect_AddSection(struct Section *section)
|
void sect_AddSection(struct Section *section)
|
||||||
{
|
{
|
||||||
// Check if the section already exists
|
// Check if the section already exists
|
||||||
struct Section *other = (struct Section *)hash_GetElement(sections, section->name);
|
if (struct Section *other = sect_GetSection(section->name); other) {
|
||||||
|
|
||||||
if (other) {
|
|
||||||
if (section->modifier != other->modifier)
|
if (section->modifier != other->modifier)
|
||||||
errx("Section \"%s\" defined as %s and %s", section->name,
|
errx("Section \"%s\" defined as %s and %s", section->name,
|
||||||
sectionModNames[section->modifier], sectionModNames[other->modifier]);
|
sectionModNames[section->modifier], sectionModNames[other->modifier]);
|
||||||
@@ -205,21 +191,22 @@ void sect_AddSection(struct Section *section)
|
|||||||
section->name, sectionTypeInfo[section->type].name.c_str());
|
section->name, sectionTypeInfo[section->type].name.c_str());
|
||||||
} else {
|
} else {
|
||||||
// If not, add it
|
// If not, add it
|
||||||
hash_AddElement(sections, section->name, section);
|
sections[section->name] = section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Section *sect_GetSection(char const *name)
|
struct Section *sect_GetSection(char const *name)
|
||||||
{
|
{
|
||||||
return (struct Section *)hash_GetElement(sections, name);
|
auto search = sections.find(name);
|
||||||
|
return search != sections.end() ? search->second : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_CleanupSections(void)
|
void sect_CleanupSections(void)
|
||||||
{
|
{
|
||||||
hash_EmptyMap(sections);
|
sections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doSanityChecks(struct Section *section, void *)
|
static void doSanityChecks(struct Section *section)
|
||||||
{
|
{
|
||||||
// Sanity check the section's type
|
// Sanity check the section's type
|
||||||
if (section->type < 0 || section->type >= SECTTYPE_INVALID) {
|
if (section->type < 0 || section->type >= SECTTYPE_INVALID) {
|
||||||
@@ -301,5 +288,5 @@ static void doSanityChecks(struct Section *section, void *)
|
|||||||
|
|
||||||
void sect_DoSanityChecks(void)
|
void sect_DoSanityChecks(void)
|
||||||
{
|
{
|
||||||
sect_ForEach(doSanityChecks, NULL);
|
sect_ForEach(doSanityChecks);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
/* SPDX-License-Identifier: MIT */
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <map>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "link/object.hpp"
|
#include "link/object.hpp"
|
||||||
#include "link/symbol.hpp"
|
#include "link/symbol.hpp"
|
||||||
#include "link/main.hpp"
|
#include "link/main.hpp"
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "hashmap.hpp"
|
|
||||||
|
|
||||||
HashMap symbols;
|
std::map<std::string, struct Symbol *> symbols;
|
||||||
|
|
||||||
void sym_AddSymbol(struct Symbol *symbol)
|
void sym_AddSymbol(struct Symbol *symbol)
|
||||||
{
|
{
|
||||||
// Check if the symbol already exists
|
// Check if the symbol already exists
|
||||||
struct Symbol *other = (struct Symbol *)hash_GetElement(symbols, symbol->name);
|
if (struct Symbol *other = sym_GetSymbol(symbol->name); other) {
|
||||||
|
|
||||||
if (other) {
|
|
||||||
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName);
|
fprintf(stderr, "error: \"%s\" both in %s from ", symbol->name, symbol->objFileName);
|
||||||
dumpFileStack(symbol->src);
|
dumpFileStack(symbol->src);
|
||||||
fprintf(stderr, "(%" PRIu32 ") and in %s from ",
|
fprintf(stderr, "(%" PRIu32 ") and in %s from ",
|
||||||
@@ -28,15 +27,16 @@ void sym_AddSymbol(struct Symbol *symbol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If not, add it
|
// If not, add it
|
||||||
hash_AddElement(symbols, symbol->name, symbol);
|
symbols[symbol->name] = symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Symbol *sym_GetSymbol(char const *name)
|
struct Symbol *sym_GetSymbol(char const *name)
|
||||||
{
|
{
|
||||||
return (struct Symbol *)hash_GetElement(symbols, name);
|
auto search = symbols.find(name);
|
||||||
|
return search != symbols.end() ? search->second : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sym_CleanupSymbols(void)
|
void sym_CleanupSymbols(void)
|
||||||
{
|
{
|
||||||
hash_EmptyMap(symbols);
|
symbols.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,4 @@ SECTION "v0", VRAM
|
|||||||
DS $2000
|
DS $2000
|
||||||
|
|
||||||
SECTION "v1", VRAM
|
SECTION "v1", VRAM
|
||||||
DS $2000
|
DS $1fff
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user