aboutsummaryrefslogtreecommitdiffhomepage
path: root/obj
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
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')
-rw-r--r--obj/elf.c14
-rw-r--r--obj/obj.c14
-rw-r--r--obj/obj.h8
3 files changed, 18 insertions, 18 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;
}
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: */