ElfStrShstrtab,
ElfStrRelPlt,
ElfStrPlt,
+ ElfStrNoteNetbsdIdent,
NElfStr
};
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, ".rodata");
addstring(shstrtab, ".gosymtab");
addstring(shstrtab, ".gopclntab");
{
int32 t;
int a, dynsym;
- uint32 fo, symo, startva;
+ uint32 fo, symo, startva, resoff;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
if(elfverneed)
elftextsh += 2;
}
+ if(HEADTYPE == Hnetbsd)
+ elftextsh += 1;
}
/* output symbol table */
cseek(symo);
if(iself) {
if(debug['v'])
- Bprint(&bso, "%5.2f elfsym\n", cputime());
+ Bprint(&bso, "%5.2f elfsym\n", cputime());
asmelfsym();
cflush();
cwrite(elfstrdat, elfstrsize);
eh = getElfEhdr();
fo = HEADR;
startva = INITTEXT - fo; /* va of byte 0 of file */
+ resoff = ELFRESERVE;
/* This null SHdr must appear before all others */
newElfShdr(elfstr[ElfStrEmpty]);
sh->addralign = 1;
if(interpreter == nil)
interpreter = linuxdynld;
- elfinterp(sh, startva, interpreter);
+ resoff -= elfinterp(sh, startva, resoff, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
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;
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;
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- a += elfwriteinterp();
+ a += elfwriteinterp(elfstr[ElfStrInterp]);
+ if(HEADTYPE == Hnetbsd)
+ a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
{
int32 magic;
int a, dynsym;
- vlong vl, startva, symo, dwarfoff, machlink;
+ vlong vl, startva, symo, dwarfoff, machlink, resoff;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
if(elfverneed)
elftextsh += 2;
}
+ if(HEADTYPE == Hnetbsd)
+ elftextsh += 1;
break;
case Hwindows:
break;
eh = getElfEhdr();
startva = INITTEXT - HEADR;
+ resoff = ELFRESERVE;
/* This null SHdr must appear before all others */
newElfShdr(elfstr[ElfStrEmpty]);
break;
}
}
- elfinterp(sh, startva, interpreter);
+ resoff -= elfinterp(sh, startva, resoff, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
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;
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;
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- a += elfwriteinterp();
+ a += elfwriteinterp(elfstr[ElfStrInterp]);
+ if(HEADTYPE == Hnetbsd)
+ a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
ElfStrPlt,
ElfStrGnuVersion,
ElfStrGnuVersionR,
+ ElfStrNoteNetbsdIdent,
NElfStr
};
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");
{
int32 v, magic;
int a, dynsym;
- uint32 symo, startva, dwarfoff, machlink;
+ uint32 symo, startva, dwarfoff, machlink, resoff;
ElfEhdr *eh;
ElfPhdr *ph, *pph;
ElfShdr *sh;
if(elfverneed)
elftextsh += 2;
}
+ if(HEADTYPE == Hnetbsd)
+ elftextsh += 1;
}
symsize = 0;
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);
Elfput:
eh = getElfEhdr();
startva = INITTEXT - HEADR;
+ resoff = ELFRESERVE;
/* This null SHdr must appear before all others */
newElfShdr(elfstr[ElfStrEmpty]);
break;
}
}
- elfinterp(sh, startva, interpreter);
+ resoff -= elfinterp(sh, startva, resoff, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
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;
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;
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- a += elfwriteinterp();
+ a += elfwriteinterp(elfstr[ElfStrInterp]);
+ if(HEADTYPE == Hnetbsd)
+ a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
}
int
-elfwriteinterp(void)
+elfinterp(ElfShdr *sh, uint64 startva, uint64 resoff, char *p)
{
int n;
- if(interp == nil)
- return 0;
-
+ interp = p;
n = strlen(interp)+1;
- cseek(ELFRESERVE-n);
- cwrite(interp, n);
+ sh->addr = startva + resoff - n;
+ sh->off = resoff - n;
+ sh->size = n;
+
return n;
}
-void
-elfinterp(ElfShdr *sh, uint64 startva, char *p)
+int
+elfwriteinterp(vlong stridx)
+{
+ ElfShdr *sh = nil;
+ int i;
+
+ for(i = 0; i < hdr.shnum; i++)
+ if(shdr[i]->name == stridx)
+ sh = shdr[i];
+ if(sh == nil || interp == nil)
+ return 0;
+
+ cseek(sh->off);
+ cwrite(interp, sh->size);
+ return sh->size;
+}
+
+// Defined in NetBSD's sys/exec_elf.h
+#define ELF_NOTE_TYPE_NETBSD_TAG 1
+#define ELF_NOTE_NETBSD_NAMESZ 7
+#define ELF_NOTE_NETBSD_DESCSZ 4
+#define ELF_NOTE_NETBSD_NAME "NetBSD\0\0"
+#define ELF_NOTE_NETBSD_VERSION 599000000 /* NetBSD 5.99 */
+
+int
+elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
{
int n;
- interp = p;
- n = strlen(interp)+1;
- sh->addr = startva + ELFRESERVE - n;
- sh->off = ELFRESERVE - n;
+ n = sizeof(Elf_Note) + ELF_NOTE_NETBSD_NAMESZ + ELF_NOTE_NETBSD_DESCSZ + 1;
+ n += resoff % 4;
+ sh->addr = startva + resoff - n;
+ sh->off = resoff - n;
sh->size = n;
+
+ return n;
+}
+
+int
+elfwritenetbsdsig(vlong stridx) {
+ ElfShdr *sh = nil;
+ int i;
+
+ for(i = 0; i < hdr.shnum; i++)
+ if(shdr[i]->name == stridx)
+ sh = shdr[i];
+ if(sh == nil)
+ return 0;
+
+ // Write Elf_Note header followed by NetBSD string.
+ cseek(sh->off);
+ LPUT(ELF_NOTE_NETBSD_NAMESZ);
+ LPUT(ELF_NOTE_NETBSD_DESCSZ);
+ LPUT(ELF_NOTE_TYPE_NETBSD_TAG);
+ cwrite(ELF_NOTE_NETBSD_NAME, 8);
+ LPUT(ELF_NOTE_NETBSD_VERSION);
+
+ return sh->size;
}
extern int nelfsym;
extern int numelfshdr;
extern int iself;
extern int elfverneed;
-int elfwriteinterp(void);
-void elfinterp(ElfShdr*, uint64, char*);
+int elfinterp(ElfShdr*, uint64, uint64, char*);
+int elfwriteinterp(vlong);
+int elfnetbsdsig(ElfShdr*, uint64, uint64);
+int elfwritenetbsdsig(vlong);
void elfdynhash(void);
ElfPhdr* elfphload(Segment*);
ElfShdr* elfshbits(Section*);