aboutsummaryrefslogtreecommitdiffhomepage
path: root/obj/elf.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
committerlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
commit302e24671942051d70707586cf8c605a5815edac (patch)
tree51e25fb6cd7e828c82ce5f17ffc775117121acee /obj/elf.c
parentc6c0f2ef35175075e91169113cfe856f29b3eb9a (diff)
create distinct interned string type
Interned strings are used pervasively, so it's a good idea to add a layer of type safety to differentiate them from general cstrs and avoid potential bugs from comparing non-interned and interned strings. Not that that's happened so far that I can remember, but it could. I'm 90% sure it's legal to alias `struct {char c;}` pointers with `char` pointers. This specific typedef gives type safety but with a simple one-way `internstr -> const char *` typecast (with `&istr->c`). Converting the other way around is more intentional: a straight up cast `(internstr)cstr` which sticks out as unchecked and probably wrong, or calling the intern(cstr) function, which is the right way.
Diffstat (limited to 'obj/elf.c')
-rw-r--r--obj/elf.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/obj/elf.c b/obj/elf.c
index 521a159..ea326b6 100644
--- a/obj/elf.c
+++ b/obj/elf.c
@@ -29,7 +29,7 @@ struct reloc {
vlong addend;
union {
uint symidx;
- const char *symname;
+ internstr symname;
};
};
static vec_of(struct reloc) relocs;
@@ -78,7 +78,7 @@ str2idx(const char *s)
}
static struct sym *
-findsym(const char *s)
+findsym(internstr s)
{
ushort *idx = pmap_get(&symht, s);
return idx ? &symtab.p[*idx] : NULL;
@@ -102,7 +102,7 @@ static const char sect2ndx[] = {
};
enum section
-elfhassym(const char *nam, uint *value)
+elfhassym(internstr nam, uint *value)
{
struct sym *sym = findsym(nam);
if (sym) {
@@ -113,12 +113,12 @@ elfhassym(const char *nam, uint *value)
}
void
-elfaddsym(const char *nam, int info, enum section sect, uvlong value, uvlong size)
+elfaddsym(internstr nam, int info, enum section sect, uvlong value, uvlong size)
{
struct sym *sym = findsym(nam), sym0;
if (!sym) {
sym = &sym0;
- sym->name = str2idx(nam);
+ sym->name = str2idx(&nam->c);
}
sym->bind = info >> 4;
sym->type = info & 0xF;
@@ -145,7 +145,7 @@ static const ushort relktab[][NRELOCKIND] = {
};
void
-elfreloc(const char *sym, enum relockind kind, enum section section, uint off, vlong addend)
+elfreloc(internstr sym, enum relockind kind, enum section section, uint off, vlong addend)
{
switch (section) {
default: assert(0);
@@ -401,7 +401,7 @@ elffini(struct wbuf *out)
rel->symidx = idx < ndefsym ? defsym2idx[idx] : idx;
} else {
assert(symtab.n < 1<<16);
- vpush(&symtab, ((struct sym) { str2idx(rel->symname), .bind = STB_GLOBAL, .type = STT_NOTYPE, .shndx = SHN_UND }));
+ vpush(&symtab, ((struct sym) { str2idx(&rel->symname->c), .bind = STB_GLOBAL, .type = STT_NOTYPE, .shndx = SHN_UND }));
pmap_set(&symht, rel->symname, symtab.n-1);
rel->symidx = symtab.n-1;
}