aboutsummaryrefslogtreecommitdiffhomepage
path: root/obj
diff options
context:
space:
mode:
Diffstat (limited to 'obj')
-rw-r--r--obj/elf.c29
-rw-r--r--obj/obj.c42
-rw-r--r--obj/obj.h2
3 files changed, 40 insertions, 33 deletions
diff --git a/obj/elf.c b/obj/elf.c
index e20da99..521a159 100644
--- a/obj/elf.c
+++ b/obj/elf.c
@@ -91,16 +91,23 @@ enum {
BSS_SHNDX = 4,
};
+static const char sect2ndx[] = {
+ [Snone] = SHN_UND,
+ [Stext] = TEXT_SHNDX, [Srodata] = RODATA_SHNDX,
+ [Sdata] = DATA_SHNDX, [Sbss] = BSS_SHNDX,
+}, shndx2sect[] = {
+ [SHN_UND] = Snone,
+ [TEXT_SHNDX] = Stext, [RODATA_SHNDX] = Srodata,
+ [DATA_SHNDX] = Sdata, [BSS_SHNDX] = Sbss,
+};
+
enum section
-elfhassym(const char *nam)
+elfhassym(const char *nam, uint *value)
{
struct sym *sym = findsym(nam);
- if (sym) switch (sym->shndx) {
- case SHN_UND: return Snone;
- case TEXT_SHNDX: return Stext;
- case RODATA_SHNDX: return Srodata;
- case DATA_SHNDX: return Sdata;
- case BSS_SHNDX: return Sbss;
+ if (sym) {
+ if (value) *value = sym->value;
+ return shndx2sect[sym->shndx];
}
return Snone;
}
@@ -115,13 +122,7 @@ elfaddsym(const char *nam, int info, enum section sect, uvlong value, uvlong siz
}
sym->bind = info >> 4;
sym->type = info & 0xF;
- switch (sect) {
- case Snone: sym->shndx = SHN_UND; break;
- case Stext: sym->shndx = TEXT_SHNDX; break;
- case Srodata: sym->shndx = RODATA_SHNDX; break;
- case Sdata: sym->shndx = DATA_SHNDX; break;
- case Sbss: sym->shndx = BSS_SHNDX; break;
- }
+ sym->shndx = sect2ndx[sect];
sym->value = value;
sym->size = size;
if (sym == &sym0) {
diff --git a/obj/obj.c b/obj/obj.c
index fa62e9e..2d8b497 100644
--- a/obj/obj.c
+++ b/obj/obj.c
@@ -6,7 +6,7 @@
void elfinit(void);
-enum section elfhassym(const char *);
+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);
void elffini(struct wbuf *);
@@ -40,38 +40,44 @@ objdeffunc(const char *nam, bool globl, uint off, uint siz)
}
enum section
-objhassym(const char *name)
+objhassym(const char *name, uint *off)
{
- return elfhassym(name);
+ return elfhassym(name, off);
}
uint
objnewdat(const char *name, enum section sec, bool globl, uint siz, uint align)
{
+ struct objfile *o = &objout;
uint off;
-
assert(siz && align && ispo2(align));
-
switch (sec) {
default: assert(0);
+ case Stext:
+ assert(align <= targ_primsizes[TYPTR]);
+ assert(o->textend - siz > o->code);
+ while ((o->code - o->textbegin) & (align - 1)) ++o->code;
+ off = o->code - o->textbegin;
+ o->code += siz;
+ break;
case Srodata:
- if (align > objout.rodataalign) objout.rodataalign = align;
- while (objout.rodata.n & (align - 1)) vpush(&objout.rodata, 0);
- off = objout.rodata.n;
- vresize(&objout.rodata, objout.rodata.n + siz);
- memset(objout.rodata.p+off, 0, siz);
+ if (align > o->rodataalign) o->rodataalign = align;
+ while (o->rodata.n & (align - 1)) vpush(&o->rodata, 0);
+ off = o->rodata.n;
+ vresize(&o->rodata, o->rodata.n + siz);
+ memset(o->rodata.p+off, 0, siz);
break;
case Sdata:
- if (align > objout.dataalign) objout.dataalign = align;
- while (objout.data.n & (align - 1)) vpush(&objout.data, 0);
- off = objout.data.n;
- vresize(&objout.data, objout.data.n + siz);
- memset(objout.data.p+off, 0, siz);
+ if (align > o->dataalign) o->dataalign = align;
+ while (o->data.n & (align - 1)) vpush(&o->data, 0);
+ off = o->data.n;
+ vresize(&o->data, o->data.n + siz);
+ memset(o->data.p+off, 0, siz);
break;
case Sbss:
- if (align > objout.bssalign) objout.bssalign = align;
- off = alignup(objout.nbss, align);
- objout.nbss = off + siz;
+ if (align > o->bssalign) o->bssalign = align;
+ off = alignup(o->nbss, align);
+ o->nbss = off + siz;
break;
}
diff --git a/obj/obj.h b/obj/obj.h
index 8e9dea8..59769ff 100644
--- a/obj/obj.h
+++ b/obj/obj.h
@@ -23,7 +23,7 @@ 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);
+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 objfini(void);