summaryrefslogtreecommitdiff
path: root/src/cmd/8l/asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8l/asm.c')
-rw-r--r--src/cmd/8l/asm.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index 6c7f96483..0fe4cf112 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -37,11 +37,10 @@
#include "../ld/macho.h"
#include "../ld/pe.h"
-#define Dbufslop 100
-
char linuxdynld[] = "/lib/ld-linux.so.2";
char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so";
+char netbsddynld[] = "/usr/libexec/ld.elf_so";
int32
entryvalue(void)
@@ -91,6 +90,7 @@ enum {
ElfStrPlt,
ElfStrGnuVersion,
ElfStrGnuVersionR,
+ ElfStrNoteNetbsdIdent,
NElfStr
};
@@ -527,6 +527,8 @@ doelf(void)
elfstr[ElfStrText] = addstring(shstrtab, ".text");
elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
+ if(HEADTYPE == Hnetbsd)
+ elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata");
addstring(shstrtab, ".gosymtab");
@@ -607,7 +609,7 @@ doelf(void)
/* define dynamic elf table */
s = lookup(".dynamic", 0);
s->reachable = 1;
- s->type = SELFROSECT;
+ s->type = SELFSECT; // writable
/*
* .dynamic table
@@ -627,6 +629,8 @@ doelf(void)
elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0));
elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0));
+ elfwritedynent(s, DT_DEBUG, 0);
+
// Do not write DT_NULL. elfdynhash will finish it.
}
}
@@ -658,7 +662,7 @@ asmb(void)
{
int32 v, magic;
int a, dynsym;
- uint32 symo, startva, machlink;
+ uint32 symo, startva, dwarfoff, machlink, resoff;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
@@ -689,8 +693,19 @@ asmb(void)
datblk(segdata.vaddr, segdata.filelen);
machlink = 0;
- if(HEADTYPE == Hdarwin)
+ if(HEADTYPE == Hdarwin) {
+ if(debug['v'])
+ Bprint(&bso, "%5.2f dwarf\n", cputime());
+
+ dwarfoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen, INITRND);
+ cseek(dwarfoff);
+
+ segdwarf.fileoff = cpos();
+ dwarfemitdebugsections();
+ segdwarf.filelen = cpos() - segdwarf.fileoff;
+
machlink = domacholink();
+ }
if(iself) {
/* index of elf text section; needed by asmelfsym, double-checked below */
@@ -701,6 +716,8 @@ asmb(void)
if(elfverneed)
elftextsh += 2;
}
+ if(HEADTYPE == Hnetbsd)
+ elftextsh += 1;
}
symsize = 0;
@@ -747,7 +764,7 @@ asmb(void)
default:
if(iself) {
if(debug['v'])
- Bprint(&bso, "%5.2f elfsym\n", cputime());
+ Bprint(&bso, "%5.2f elfsym\n", cputime());
asmelfsym();
cflush();
cwrite(elfstrdat, elfstrsize);
@@ -770,7 +787,6 @@ asmb(void)
cflush();
}
break;
- case Hdarwin:
case Hwindows:
if(debug['v'])
Bprint(&bso, "%5.2f dwarf\n", cputime());
@@ -919,6 +935,7 @@ asmb(void)
Elfput:
eh = getElfEhdr();
startva = INITTEXT - HEADR;
+ resoff = ELFRESERVE;
/* This null SHdr must appear before all others */
newElfShdr(elfstr[ElfStrEmpty]);
@@ -957,12 +974,15 @@ asmb(void)
case Hfreebsd:
interpreter = freebsddynld;
break;
+ case Hnetbsd:
+ interpreter = netbsddynld;
+ break;
case Hopenbsd:
interpreter = openbsddynld;
break;
}
}
- elfinterp(sh, startva, interpreter);
+ resoff -= elfinterp(sh, startva, resoff, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
@@ -970,11 +990,24 @@ asmb(void)
phsh(ph, sh);
}
+ if(HEADTYPE == Hnetbsd) {
+ sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
+ sh->type = SHT_NOTE;
+ sh->flags = SHF_ALLOC;
+ sh->addralign = 4;
+ resoff -= elfnetbsdsig(sh, startva, resoff);
+
+ ph = newElfPhdr();
+ ph->type = PT_NOTE;
+ ph->flags = PF_R;
+ phsh(ph, sh);
+ }
+
elfphload(&segtext);
elfphload(&segdata);
/* Dynamic linking sections */
- if (!debug['d']) { /* -d suppresses dynamic loader format */
+ if(!debug['d']) { /* -d suppresses dynamic loader format */
/* S headers for dynamic linking */
sh = newElfShdr(elfstr[ElfStrGot]);
sh->type = SHT_PROGBITS;
@@ -1098,7 +1131,7 @@ asmb(void)
for(sect=segdata.sect; sect!=nil; sect=sect->next)
elfshbits(sect);
- if (!debug['s']) {
+ if(!debug['s']) {
sh = newElfShdr(elfstr[ElfStrSymtab]);
sh->type = SHT_SYMTAB;
sh->off = symo;
@@ -1128,6 +1161,9 @@ asmb(void)
case Hfreebsd:
eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
break;
+ case Hnetbsd:
+ eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
+ break;
case Hopenbsd:
eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
break;
@@ -1148,8 +1184,10 @@ asmb(void)
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- cflush();
- if(a+elfwriteinterp() > ELFRESERVE)
+ a += elfwriteinterp(elfstr[ElfStrInterp]);
+ if(HEADTYPE == Hnetbsd)
+ a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
+ if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;