diff options
Diffstat (limited to 'src/cmd/8l/asm.c')
| -rw-r--r-- | src/cmd/8l/asm.c | 62 |
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; |
