aboutsummaryrefslogtreecommitdiffhomepage
path: root/obj
diff options
context:
space:
mode:
Diffstat (limited to 'obj')
-rw-r--r--obj/elf.c572
-rw-r--r--obj/elf.h206
-rw-r--r--obj/obj.c118
-rw-r--r--obj/obj.h36
4 files changed, 0 insertions, 932 deletions
diff --git a/obj/elf.c b/obj/elf.c
deleted file mode 100644
index 5044e56..0000000
--- a/obj/elf.c
+++ /dev/null
@@ -1,572 +0,0 @@
-#include "elf.h"
-#include "obj.h"
-#include "../ir/ir.h" /* mctarg */
-#include "../endian.h"
-#include <unistd.h>
-#include <stdlib.h> /* qsort */
-
-static union {
- ELF_HDRIDENT;
- struct elf32hdr h32;
- struct elf64hdr h64;
-} hdr;
-static vec_of(uchar) strs;
-struct sym {
- uint name;
- uchar bind : 4,
- type : 4;
- ushort shndx;
- uvlong value,
- size;
-};
-static vec_of(struct sym) symtab;
-static pmap_of(ushort) symht;
-static uint ntextrel, nrodatarel, ndatarel;
-struct reloc {
- uchar section;
- ushort kind;
- uint off;
- vlong addend;
- union {
- uint symidx;
- internstr symname;
- };
-};
-static vec_of(struct reloc) relocs;
-
-#define O objout
-
-void
-elfinit(void)
-{
- memcpy(hdr.i_mag, ELFMAG, 4);
- hdr.i_class = ELFCLASS32 + targ_64bit;
- hdr.i_data = ELFDATA2LSB + targ_bigendian;
- hdr.i_version = ELFVERSION;
- hdr.i_osabi = ELFOSABI_SYSV;
- hdr.i_abiversion = 0;
- hdr.h32.type = ET_REL;
- switch (target.arch) {
- default: assert(!"arch?");
- case ISx86_64: hdr.h32.machine = EM_X86_64; break;
- case ISaarch64: hdr.h32.machine = EM_ARM64; break;
- }
- hdr.h32.version = ELFVERSION;
- if (targ_64bit) {
- hdr.h64.ehsize = sizeof(struct elf64hdr);
- hdr.h64.shentsize = sizeof(struct elf64shdr);
- } else {
- hdr.h32.ehsize = sizeof(struct elf32hdr);
- hdr.h32.shentsize = sizeof(struct elf32shdr);
- }
- vinit(&strs, NULL, 4<<10);
- vpush(&symtab, ((struct sym){0}));
- vpush(&symtab, ((struct sym){ .type = STT_FILE, .shndx = SHN_ABS}));
-}
-
-uint
-str2idx(const char *s)
-{
- static pmap_of(uint) ht;
- uint *p, i;
-
- if (!ht.v) pmap_init(&ht, 1<<8);
- if ((p = pmap_get(&ht, s))) return *p;
- if (!strs.n) vpush(&strs, 0);
- i = strs.n;
- vpushn(&strs, s, strlen(s)+1);
- pmap_set(&ht, s, i);
- return i;
-}
-
-static struct sym *
-findsym(internstr s)
-{
- ushort *idx = pmap_get(&symht, s);
- return idx ? &symtab.p[*idx] : NULL;
-}
-
-enum {
- TEXT_SHNDX = 1,
- RODATA_SHNDX = 2,
- DATA_SHNDX = 3,
- 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(internstr nam, uint *value)
-{
- struct sym *sym = findsym(nam);
- if (sym) {
- if (value) *value = sym->value;
- return shndx2sect[sym->shndx];
- }
- return Snone;
-}
-
-void
-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->c);
- }
- sym->bind = info >> 4;
- sym->type = info & 0xF;
- sym->shndx = sect2ndx[sect];
- sym->value = value;
- sym->size = size;
- if (sym == &sym0) {
- assert(symtab.n < 1<<16);
- pmap_set(&symht, nam, symtab.n);
- vpush(&symtab, sym0);
- }
-}
-
-static const ushort relktab[][NRELOCKIND] = {
- [ISx86_64] = {
- [REL_ABS64] = 1, /* R_X86_64_64 */
- [REL_ABS32] = 10, /* R_X86_64_32 */
- [REL_ABS32S] = 11, /* R_X86_64_32S */
- [REL_PCREL32] = 2, /* R_X86_64_PC32 */
- [REL_PLT32] = 4, /* R_X86_64_PLT32 */
- [REL_GOTPCRELX] = 41, /* R_X86_64_GOTPCRELX */
- [REL_GOTPCRELX_REX] = 42, /* R_X86_64_REX_GOTPCRELX */
- },
- [ISaarch64] = {
- [REL_ABS64] = 257, /* R_AARCH64_ABS64 */
- [REL_ABS32] = 258, /* R_AARCH64_ABS32 */
- [REL_ABS32S] = 258, /* R_AARCH64_ABS32S */
- [REL_PCREL32] = 261, /* R_AARCH64_PREL2 */
- [REL_PLT32] = 314, /* R_AARCH64_PLT32 */
- [REL_CALL26] = 283, /* R_AARCH64_CALL26 */
- [REL_LD_PREL_LO19] = 273, /* R_AARCH64_LD_PREL_LO19 */
- [REL_ADR_PREL_LO21] = 274, /* R_AARCH64_ADR_PREL_LO21 */
- [REL_ADR_PREL_PG_HI21] = 276, /* R_AARCH64_ADR_PREL_PG_HI21_NC */
- [REL_ADD_ABS_LO12_NC] = 277, /* R_AARCH64_ADD_ABS_LO12_NC */
-
- }
-};
-
-void
-elfreloc(internstr sym, enum relockind kind, enum section section, uint off, vlong addend)
-{
- switch (section) {
- default: assert(0);
- case Stext: ++ntextrel; break;
- case Srodata: ++nrodatarel; break;
- case Sdata: ++ndatarel; break;
- }
- assert(kind < NRELOCKIND);
- vpush(&relocs, ((struct reloc) { section, relktab[target.arch][kind], off, addend, .symname = sym }));
-}
-
-static void
-elf64puthdr(struct wbuf *out, struct elf64hdr *hdr)
-{
- if (!hostntarg_sameendian()) {
- hdr->type = bswap16(hdr->type);
- hdr->machine = bswap16(hdr->machine);
- hdr->version = bswap32(hdr->version);
- hdr->entry = bswap64(hdr->entry);
- hdr->phoff = bswap64(hdr->phoff);
- hdr->shoff = bswap64(hdr->shoff);
- hdr->flags = bswap32(hdr->flags);
- hdr->ehsize = bswap16(hdr->ehsize);
- hdr->phentsize = bswap16(hdr->phentsize);
- hdr->phnum = bswap16(hdr->phnum);
- hdr->shentsize = bswap16(hdr->shentsize);
- hdr->shnum = bswap16(hdr->shnum);
- hdr->shstrndx = bswap16(hdr->shstrndx);
- }
- iowrite(out, hdr, sizeof *hdr);
-}
-
-static void
-elf32puthdr(struct wbuf *out, struct elf32hdr *hdr)
-{
- if (!hostntarg_sameendian()) {
- hdr->type = bswap16(hdr->type);
- hdr->machine = bswap16(hdr->machine);
- hdr->version = bswap32(hdr->version);
- hdr->entry = bswap32(hdr->entry);
- hdr->phoff = bswap32(hdr->phoff);
- hdr->shoff = bswap32(hdr->shoff);
- hdr->flags = bswap32(hdr->flags);
- hdr->ehsize = bswap16(hdr->ehsize);
- hdr->phentsize = bswap16(hdr->phentsize);
- hdr->phnum = bswap16(hdr->phnum);
- hdr->shentsize = bswap16(hdr->shentsize);
- hdr->shnum = bswap16(hdr->shnum);
- hdr->shstrndx = bswap16(hdr->shstrndx);
- }
- iowrite(out, hdr, sizeof *hdr);
-}
-
-static void
-elf64putshdr(struct wbuf *out, struct elf64shdr *shdr)
-{
- if (!hostntarg_sameendian()) {
- shdr->name = bswap32(shdr->name);
- shdr->type = bswap32(shdr->type);
- shdr->flags = bswap64(shdr->flags);
- shdr->addr = bswap64(shdr->addr);
- shdr->offset = bswap64(shdr->offset);
- shdr->size = bswap64(shdr->size);
- shdr->link = bswap32(shdr->link);
- shdr->info = bswap32(shdr->info);
- shdr->addralign = bswap64(shdr->addralign);
- shdr->entsize = bswap64(shdr->entsize);
- }
- iowrite(out, shdr, sizeof *shdr);
-}
-
-static void
-elf32putshdr(struct wbuf *out, struct elf32shdr *shdr)
-{
- if (!hostntarg_sameendian()) {
- shdr->name = bswap32(shdr->name);
- shdr->type = bswap32(shdr->type);
- shdr->flags = bswap32(shdr->flags);
- shdr->addr = bswap32(shdr->addr);
- shdr->offset = bswap32(shdr->offset);
- shdr->size = bswap32(shdr->size);
- shdr->link = bswap32(shdr->link);
- shdr->info = bswap32(shdr->info);
- shdr->addralign = bswap32(shdr->addralign);
- shdr->entsize = bswap32(shdr->entsize);
- }
- iowrite(out, shdr, sizeof *shdr);
-}
-
-static void
-elf64putsym(struct wbuf *out, struct elf64sym *sym)
-{
- if (!hostntarg_sameendian()) {
- sym->name = bswap32(sym->name);
- sym->shndx = bswap16(sym->shndx);
- sym->value = bswap64(sym->value);
- sym->size = bswap64(sym->size);
- }
- iowrite(out, sym, sizeof *sym);
-}
-
-static void
-elf32putsym(struct wbuf *out, struct elf32sym *sym)
-{
- if (!hostntarg_sameendian()) {
- sym->name = bswap32(sym->name);
- sym->value = bswap32(sym->value);
- sym->size = bswap32(sym->size);
- sym->shndx = bswap16(sym->shndx);
- }
- iowrite(out, sym, sizeof *sym);
-}
-
-static void
-putsym(struct wbuf *out, const struct sym *sym)
-{
- if (targ_64bit) {
- elf64putsym(out, &(struct elf64sym) {
- sym->name, .info = ELF_S_INFO(sym->bind, sym->type),
- .shndx = sym->shndx, .value = sym->value, .size = sym->size });
- } else {
- elf32putsym(out, &(struct elf32sym) {
- sym->name, .info = ELF_S_INFO(sym->bind, sym->type),
- .shndx = sym->shndx, .value = sym->value, .size = sym->size });
- }
-}
-
-static void
-elf64putrel(struct wbuf *out, struct elf64rel *rel)
-{
- if (!hostntarg_sameendian()) {
- rel->offset = bswap64(rel->offset);
- rel->info = bswap64(rel->info);
- }
- iowrite(out, rel, sizeof *rel);
-}
-
-static void
-elf32putrel(struct wbuf *out, struct elf32rel *rel)
-{
- if (!hostntarg_sameendian()) {
- rel->offset = bswap32(rel->offset);
- rel->info = bswap32(rel->info);
- }
- iowrite(out, rel, sizeof *rel);
-}
-
-static void
-elf64putrela(struct wbuf *out, struct elf64rela *rel)
-{
- if (!hostntarg_sameendian()) {
- rel->offset = bswap64(rel->offset);
- rel->info = bswap64(rel->info);
- rel->addend = bswap64(rel->addend);
- }
- iowrite(out, rel, sizeof *rel);
-}
-
-static void
-elf32putrela(struct wbuf *out, struct elf32rela *rel)
-{
- if (!hostntarg_sameendian()) {
- rel->offset = bswap32(rel->offset);
- rel->info = bswap32(rel->info);
- rel->addend = bswap32(rel->addend);
- }
- iowrite(out, rel, sizeof *rel);
-}
-
-static void
-putreloc(struct wbuf *out, const struct reloc *rel, bool userela)
-{
- if (userela) {
- if (targ_64bit) {
- elf64putrela(out, &(struct elf64rela) {
- rel->off, ELF64_R_INFO(rel->symidx, rel->kind), rel->addend });
- } else {
- elf32putrela(out, &(struct elf32rela) {
- rel->off, ELF32_R_INFO(rel->symidx, rel->kind), rel->addend });
- }
- } else {
- if (targ_64bit) {
- elf64putrel(out, &(struct elf64rel) {
- rel->off, ELF64_R_INFO(rel->symidx, rel->kind) });
- } else {
- elf32putrel(out, &(struct elf32rel) {
- rel->off, ELF32_R_INFO(rel->symidx, rel->kind) });
- }
- }
-}
-
-/* ensure .symtab entries are ordered like this:
- * (0. zero entry: NOTYPE LOCAL UND)
- * (1. file: FILE LOCAL ABS "...")
- * 2. locals
- * 3. defined globals
- * 4. undefined globals
- */
-static int
-symcmp(const void *aa, const void *bb)
-{
- const ushort *a = aa, *b = bb;
- const struct sym *l = &symtab.p[*a], *r = &symtab.p[*b];
- int tmp;
- if ((tmp = l->bind - r->bind)) return tmp; /* locals prio */
- if ((tmp = r->shndx - l->shndx)) return tmp; /* section prio (real sections > SHN_UND) */
- return l->name - r->name;
-}
-
-static void
-wordalign(struct wbuf *out, int align)
-{
- size_t off = out->len + lseek(out->fd, 0, SEEK_CUR);
- while (off++ & (align - 1)) ioputc(out, 0);
-}
-
-static const bool userelatab[] = { [ISx86_64] = 1, [ISaarch64] = 1 };
-
-void
-elffini(struct wbuf *out)
-{
- enum {
- shnam_text = 1, shnam_rodata = 7, shnam_data = 15, shnam_bss = 21, shnam_shstrtab = 26,
- shnam_strtab = 36, shnam_symtab = 44, shnam_reltext = 52, shnam_relrodata = 63, shnam_reldata = 76
- };
- int align = targ_64bit ? 8 : 4;
- bool userela = userelatab[target.arch];
- char shstrs[] = "\0.text\0.rodata\0.data\0.bss\0.shstrtab\0.strtab\0.symtab\0"
- ".rela.text\0.rela.rodata\0.rela.data";
- if (!userela) {
- /* .rela -> .rel */
- memcpy(shstrs + shnam_reltext + 4, ".text\0", 6);
- memcpy(shstrs + shnam_relrodata + 4, ".rodata\0", 8);
- memcpy(shstrs + shnam_reldata + 4, ".data\0", 6);
- }
-
- symtab.p[1].name = str2idx(objout.infile);
- /* create a mapping of original symbol index -> sorted symtab index */
- uint ndefsym = symtab.n;
- ushort ssbuf[2<<10],
- *sortedsyms = ndefsym*2 < countof(ssbuf) ? ssbuf : xmalloc(sizeof *sortedsyms * ndefsym*2),
- *defsym2idx = sortedsyms + ndefsym;
- for (int i = 0; i < ndefsym; ++i) sortedsyms[i] = i;
- qsort(sortedsyms+2, ndefsym-2, sizeof *sortedsyms, symcmp);
- for (int i = 0; i < ndefsym; ++i) defsym2idx[sortedsyms[i]] = i;
-
- /* fixup relocs */
- for (int i = 0; i < relocs.n; ++i) {
- struct reloc *rel = &relocs.p[i];
- struct sym *sym = findsym(rel->symname);
- if (sym) {
- uint idx = sym - symtab.p;
- rel->symidx = idx < ndefsym ? defsym2idx[idx] : idx;
- } else {
- assert(symtab.n < 1<<16);
- 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;
- }
- if (!userela) {
- uchar *p;
- switch (rel->section) {
- default: assert(0);
- case Sdata: p = O.data.p + rel->off; break;
- case Srodata: p = O.rodata.p + rel->off; break;
- case Stext: p = O.textbegin + rel->off; break;
- }
- if (targ_64bit)
- wr64targ(p, rel->addend);
- else
- wr32targ(p, rel->addend);
- }
- }
- size_t codesize = alignup(O.code - O.textbegin, align),
- rodataoff = (targ_64bit ? sizeof hdr.h64 : sizeof hdr.h32) + codesize,
- rodatasize = O.rodata.n,
- dataoff = rodataoff + rodatasize,
- datasize = O.data.n,
- bsssize = O.nbss,
- shstrsoff = dataoff + datasize,
- shstrssize = sizeof(shstrs),
- strsoff = shstrsoff + shstrssize,
- strssize = strs.n,
- symtaboff = alignup(strsoff + strssize, align),
- symtabsize = symtab.n * (targ_64bit ? 24 : 16),
- reltextoff = symtaboff + symtabsize,
- relxsiz = userela ? (targ_64bit ? 24 : 12) : (targ_64bit ? 16 : 8),
- reltextsize = ntextrel * relxsiz,
- relrodataoff = reltextoff + reltextsize,
- relrodatasize = nrodatarel * relxsiz,
- reldataoff = relrodataoff + relrodatasize,
- reldatasize = ndatarel * relxsiz;
- int nlocal = 0;
-
-#define CHECKOFF(s, x) \
- efmt(s " expect OFF: %u ; ACTUAL %u\n", (uint)(x),(uint)(lseek(out->fd, 0, SEEK_CUR) + out->len))
-
- if (targ_64bit) {
- hdr.h64.shoff = alignup(reldataoff + reldatasize, align);
- hdr.h64.shnum = 11;
- hdr.h64.shstrndx = 5;
- } else {
- hdr.h32.shoff = alignup(reldataoff + reldatasize, align);
- hdr.h32.shnum = 11;
- hdr.h32.shstrndx = 5;
- }
-
- /* elf header */
- if (targ_64bit)
- elf64puthdr(out, &hdr.h64);
- else
- elf32puthdr(out, &hdr.h32);
-
- /* .text progbits */
- iowrite(out, O.textbegin, codesize);
-
- /* .rodata progbits */
- iowrite(out, O.rodata.p, O.rodata.n);
-
- /* .data progbits */
- iowrite(out, O.data.p, O.data.n);
-
- /* section names */
- iowrite(out, shstrs, sizeof shstrs);
-
- /* strings */
- iowrite(out, strs.p, strs.n);
-
- /* symtab */
- wordalign(out, align);
- for (int i = 0; i < symtab.n; ++i) {
- struct sym *sym = &symtab.p[i < ndefsym ? sortedsyms[i] : i];
- if (sym->bind == STB_LOCAL) ++nlocal;
- putsym(out, sym);
- }
- if (sortedsyms != ssbuf) free(sortedsyms);
-
- /* rel.* */
- assert(relocs.n == ntextrel + nrodatarel + ndatarel);
- for (enum section s = Stext; s <= Sbss; ++s) {
- for (int i = 0; i < relocs.n; ++i) {
- struct reloc *rel = &relocs.p[i];
- if (rel->section != s) continue;
- putreloc(out, rel, userela);
- }
- }
-
- /** Section Headers **/
- wordalign(out, align);
-#define putshdr(...) if (targ_64bit) elf64putshdr(out, &(struct elf64shdr) { __VA_ARGS__ }); \
- else elf32putshdr(out, &(struct elf32shdr) { __VA_ARGS__ });
- /* §0 null section */
- putshdr(0);
- /* §1 .text */
- putshdr(.name = shnam_text, .type = SHT_PROGBITS,
- .flags = SHF_ALLOC | SHF_EXECINSTR,
- .offset = targ_64bit ? hdr.h64.ehsize : hdr.h32.ehsize, .size = codesize,
- .addralign = align);
- /* §2 .rodata */
- putshdr(.name = shnam_rodata, .type = SHT_PROGBITS,
- .flags = SHF_ALLOC,
- .offset = rodataoff, .size = rodatasize,
- .addralign = O.rodataalign,);
- /* §3 .data */
- putshdr(.name = shnam_data, .type = SHT_PROGBITS,
- .flags = SHF_ALLOC | SHF_WRITE,
- .offset = dataoff, .size = datasize,
- .addralign = O.dataalign,);
- /* §4 .bss */
- putshdr(.name = shnam_bss, .type = SHT_NOBITS,
- .size = bsssize,
- .flags = SHF_ALLOC | SHF_WRITE,
- .addralign = O.bssalign,);
- /* §5 .shstrtab */
- putshdr(.name = shnam_shstrtab, .type = SHT_STRTAB,
- .offset = shstrsoff, .size = shstrssize,
- .flags = SHF_STRINGS );
- /* §6 .strtab */
- putshdr(.name = shnam_strtab, .type = SHT_STRTAB,
- .offset = strsoff, .size = strssize,
- .flags = SHF_STRINGS );
- /* §7 .symtab */
- putshdr(.name = shnam_symtab, .type = SHT_SYMTAB,
- .offset = symtaboff, .size = symtabsize,
- .flags = SHF_STRINGS,
- .link = 6, /* .strtab */
- .info = nlocal,
- .entsize = targ_64bit ? 24 : 16 );
- /* §8 .rel.text */
- putshdr(.name = shnam_reltext, .type = SHT_RELA,
- .offset = reltextoff, .size = reltextsize,
- .link = 7, /* .symtab */
- .entsize = relxsiz,
- .info = TEXT_SHNDX );
- /* §9 .rel.rodata */
- putshdr(.name = shnam_relrodata, .type = SHT_RELA,
- .offset = relrodataoff, .size = relrodatasize,
- .link = 7, /* .symtab */
- .entsize = relxsiz,
- .info = RODATA_SHNDX );
- /* §10 .rel.data */
- putshdr(.name = shnam_reldata, .type = SHT_RELA,
- .offset = reldataoff, .size = reldatasize,
- .link = 7, /* .symtab */
- .entsize = relxsiz,
- .info = DATA_SHNDX );
-}
-
-/* vim:set ts=3 sw=3 expandtab: */
diff --git a/obj/elf.h b/obj/elf.h
deleted file mode 100644
index c96ae8b..0000000
--- a/obj/elf.h
+++ /dev/null
@@ -1,206 +0,0 @@
-#include "../common.h"
-
-#define ELFMAG "\177ELF"
-enum {
- ELFCLASS32 = 1,
- ELFCLASS64 = 2,
-
- ELFDATA2LSB = 1,
- ELFDATA2MSB = 2,
-
- ELFVERSION = 1,
-
- ELFOSABI_SYSV = 0,
- ELFOSABI_ARM = 97,
- ELFOSABI_STANDALONE = 255,
-
- ET_NONE = 0,
- ET_REL, ET_EXEC, ET_DYN, ET_CORE,
-
- EM_NONE = 0,
- EM_386 = 3,
- EM_486 = 6,
- EM_MIPS = 8,
- EM_MIPS_RS4_BE = 0xA,
- EM_ARM = 0x28,
- EM_X86_64 = 0x3E,
- EM_ARM64 = 0xB7,
-};
-
-#define ELF_HDRIDENT \
- union { \
- uchar ident[16]; \
- struct { \
- uchar i_mag[4], \
- i_class, \
- i_data, \
- i_version, \
- i_osabi, \
- i_abiversion, \
- i_pad[7]; \
- }; \
- }
-
-struct elf64hdr {
- ELF_HDRIDENT;
- ushort type,
- machine;
- uint version;
- uvlong entry,
- phoff,
- shoff;
- uint flags;
- ushort ehsize,
- phentsize,
- phnum,
- shentsize,
- shnum,
- shstrndx;
-};
-static_assert(sizeof(struct elf64hdr) == 64);
-
-struct elf32hdr {
- ELF_HDRIDENT;
- ushort type,
- machine;
- uint version;
- uint entry,
- phoff,
- shoff;
- uint flags;
- ushort ehsize,
- phentsize,
- phnum,
- shentsize,
- shnum,
- shstrndx;
-};
-static_assert(sizeof(struct elf32hdr) == 52);
-
-enum {
- SHT_NULL = 0x0,
- SHT_PROGBITS = 0x1,
- SHT_SYMTAB = 0x2,
- SHT_STRTAB = 0x3,
- SHT_RELA = 0x4,
- SHT_HASH = 0x5,
- SHT_DYNAMIC = 0x6,
- SHT_NOTE = 0x7,
- SHT_NOBITS = 0x8,
- SHT_REL = 0x9,
- SHT_SHLIB = 0xA,
- SHT_DYNSYM = 0xB,
- SHT_INIT_ARRAY = 0xE,
- SHT_FINI_ARRAY = 0xF,
- SHT_PREINIT_ARRAY = 0x10,
- SHT_GROUP = 0x12,
- SHT_SYMTAB_SHNDX = 0x13,
-};
-
-enum {
- SHF_WRITE = 0x1,
- SHF_ALLOC = 0x2,
- SHF_EXECINSTR = 0x4,
- SHF_MERGE = 0x10,
- SHF_STRINGS = 0x20,
- SHF_INFO_LINK = 0x40,
- SHF_LINK_ORDER = 0x80,
- SHF_OS_NONCONFORMING = 0x100,
- SHF_GROUP = 0x200,
- SHF_TLS = 0x400,
-};
-
-struct elf64shdr {
- uint name,
- type;
- uvlong flags,
- addr,
- offset,
- size;
- uint link,
- info;
- uvlong addralign,
- entsize;
-};
-static_assert(sizeof(struct elf64shdr) == 64);
-
-struct elf32shdr {
- uint name,
- type,
- flags,
- addr,
- offset,
- size,
- link,
- info,
- addralign,
- entsize;
-};
-static_assert(sizeof(struct elf32shdr) == 40);
-
-enum {
- STB_LOCAL,
- STB_GLOBAL,
- STB_WEAK
-};
-
-enum {
- STT_NOTYPE,
- STT_OBJECT,
- STT_FUNC,
- STT_SECTION,
- STT_FILE,
-};
-
-enum {
- SHN_UND = 0,
- SHN_ABS = 0xFFF1,
-};
-
-#define ELF_S_INFO(b,t) ((b) << 4 | (t))
-
-struct elf64sym {
- uint name;
- uchar info,
- other;
- ushort shndx;
- uvlong value,
- size;
-};
-static_assert(sizeof(struct elf64sym) == 24);
-
-struct elf32sym {
- uint name,
- value,
- size;
- uchar info,
- other;
- ushort shndx;
-};
-static_assert(sizeof(struct elf32sym) == 16);
-
-#define ELF64_R_INFO(s,t) ((uvlong) (s) << 32 | (uint)(t))
-struct elf64rel {
- uvlong offset, info;
-};
-static_assert(sizeof(struct elf64rel) == 16);
-
-#define ELF32_R_INFO(s,t) ((s) << 8 | (uchar)(t))
-struct elf32rel {
- uint offset, info;
-};
-static_assert(sizeof(struct elf32rel) == 8);
-
-struct elf64rela {
- uvlong offset, info;
- vlong addend;
-};
-static_assert(sizeof(struct elf64rela) == 24);
-
-struct elf32rela {
- uint offset, info;
- int addend;
-};
-static_assert(sizeof(struct elf32rela) == 12);
-
-/* vim:set ts=3 sw=3 expandtab: */
diff --git a/obj/obj.c b/obj/obj.c
deleted file mode 100644
index 12f0db7..0000000
--- a/obj/obj.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "obj.h"
-#include "../ir/ir.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-
-void elfinit(void);
-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;
-
-enum { NTEXT = 4<<20 /* 4MiB */ };
-
-void
-objini(const char *infile, const char *outfile)
-{
- assert(!objout.outfile);
- objout.infile = infile;
- objout.outfile = outfile;
- objout.code = objout.textbegin = mapzeros(NTEXT);
- objout.textend = objout.textbegin + NTEXT;
-
- switch (mctarg->objkind) {
- case OBJELF: elfinit(); break;
- }
-}
-
-void
-objdeffunc(internstr nam, bool globl, uint off, uint siz)
-{
- switch (mctarg->objkind) {
- case OBJELF:
- elfaddsym(nam, /*STT_LOCAL/GLOBAL*/globl << 4 | /*STT_FUNC*/2, Stext, off, siz);
- break;
- }
-}
-
-enum section
-objhassym(internstr name, uint *off)
-{
- return elfhassym(name, off);
-}
-
-uint
-objnewdat(internstr 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 > 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 > 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 > o->bssalign) o->bssalign = align;
- off = alignup(o->nbss, align);
- o->nbss = off + siz;
- break;
- }
-
- switch (mctarg->objkind) {
- case OBJELF:
- elfaddsym(name, /*STT_LOCAL/GLOBAL*/globl<<4 | /*STT_OBJECT*/1, sec, off, siz);
- break;
- }
- return off;
-}
-
-void
-objreloc(internstr sym, enum relockind reloc, enum section section, uint off, vlong addend)
-{
- switch (mctarg->objkind) {
- case OBJELF:
- elfreloc(sym, reloc, section, off, addend);
- break;
- }
-}
-
-void
-objfini(void)
-{
- static char buf[1<<12];
- struct wbuf out = FDBUF(buf, sizeof buf, open(objout.outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666));
- if (out.fd < 0) fatal(NULL, "could not open %'s for writing: %s", objout.outfile, strerror(errno));
-
- switch (mctarg->objkind) {
- case OBJELF: elffini(&out); break;
- }
-
- munmap(objout.textbegin, NTEXT);
- ioflush(&out);
- close(out.fd);
-}
-
-/* vim:set ts=3 sw=3 expandtab: */
diff --git a/obj/obj.h b/obj/obj.h
deleted file mode 100644
index 1982033..0000000
--- a/obj/obj.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "../common.h"
-
-extern struct objfile {
- const char *infile, *outfile;
- uchar *textbegin, *textend;
- uchar *code;
- uchar dataalign, rodataalign, bssalign;
- uint nbss;
- vec_of(uchar) data, rodata;
-} objout;
-
-enum relockind {
- REL_ABS64,
- REL_ABS32,
- REL_ABS32S,
- REL_PCREL32,
- REL_PLT32,
- REL_GOTPCRELX,
- REL_GOTPCRELX_REX,
- REL_CALL26,
- REL_ADR_PREL_LO21,
- REL_ADR_PREL_PG_HI21,
- REL_ADD_ABS_LO12_NC,
- REL_LD_PREL_LO19,
- NRELOCKIND,
-};
-enum section { Snone, Stext, Srodata, Sdata, Sbss };
-
-void objini(const char *infile, const char *outfile);
-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: */