From 302e24671942051d70707586cf8c605a5815edac Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 15 Dec 2025 22:39:52 +0100 Subject: 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. --- obj/elf.c | 14 +++++++------- obj/obj.c | 14 +++++++------- obj/obj.h | 8 ++++---- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'obj') 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; } diff --git a/obj/obj.c b/obj/obj.c index 2d8b497..12f0db7 100644 --- a/obj/obj.c +++ b/obj/obj.c @@ -6,9 +6,9 @@ void elfinit(void); -enum section elfhassym(const char *, uint *value); -void elfaddsym(const char *, int info, enum section, uvlong value, uvlong size); -void elfreloc(const char *sym, enum relockind, enum section, uint off, vlong addend); +enum section elfhassym(internstr , uint *value); +void elfaddsym(internstr , int info, enum section, uvlong value, uvlong size); +void elfreloc(internstr sym, enum relockind, enum section, uint off, vlong addend); void elffini(struct wbuf *); struct objfile objout; @@ -30,7 +30,7 @@ objini(const char *infile, const char *outfile) } void -objdeffunc(const char *nam, bool globl, uint off, uint siz) +objdeffunc(internstr nam, bool globl, uint off, uint siz) { switch (mctarg->objkind) { case OBJELF: @@ -40,13 +40,13 @@ objdeffunc(const char *nam, bool globl, uint off, uint siz) } enum section -objhassym(const char *name, uint *off) +objhassym(internstr name, uint *off) { return elfhassym(name, off); } uint -objnewdat(const char *name, enum section sec, bool globl, uint siz, uint align) +objnewdat(internstr name, enum section sec, bool globl, uint siz, uint align) { struct objfile *o = &objout; uint off; @@ -90,7 +90,7 @@ objnewdat(const char *name, enum section sec, bool globl, uint siz, uint align) } void -objreloc(const char *sym, enum relockind reloc, enum section section, uint off, vlong addend) +objreloc(internstr sym, enum relockind reloc, enum section section, uint off, vlong addend) { switch (mctarg->objkind) { case OBJELF: diff --git a/obj/obj.h b/obj/obj.h index 59769ff..77da99a 100644 --- a/obj/obj.h +++ b/obj/obj.h @@ -22,10 +22,10 @@ enum relockind { enum section { Snone, Stext, Srodata, Sdata, Sbss }; void objini(const char *infile, const char *outfile); -void objdeffunc(const char *nam, bool globl, uint off, uint siz); -enum section objhassym(const char *name, uint *off); -uint objnewdat(const char *name, enum section, bool globl, uint siz, uint align); -void objreloc(const char *sym, enum relockind, enum section, uint off, vlong addend); +void objdeffunc(internstr nam, bool globl, uint off, uint siz); +enum section objhassym(internstr name, uint *off); +uint objnewdat(internstr name, enum section, bool globl, uint siz, uint align); +void objreloc(internstr sym, enum relockind, enum section, uint off, vlong addend); void objfini(void); /* vim:set ts=3 sw=3 expandtab: */ -- cgit v1.2.3