mirror of
https://github.com/golang/go
synced 2024-11-12 00:20:22 -07:00
5l/6l/8l: add support for netbsd signature note section
R=m4dh4tt3r, jsing, rsc CC=golang-dev https://golang.org/cl/5493068
This commit is contained in:
parent
b7e9d22528
commit
5842f7e46a
@ -73,6 +73,7 @@ enum {
|
||||
ElfStrShstrtab,
|
||||
ElfStrRelPlt,
|
||||
ElfStrPlt,
|
||||
ElfStrNoteNetbsdIdent,
|
||||
NElfStr
|
||||
};
|
||||
|
||||
@ -164,6 +165,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, ".rodata");
|
||||
addstring(shstrtab, ".gosymtab");
|
||||
addstring(shstrtab, ".gopclntab");
|
||||
@ -294,7 +297,7 @@ asmb(void)
|
||||
{
|
||||
int32 t;
|
||||
int a, dynsym;
|
||||
uint32 fo, symo, startva;
|
||||
uint32 fo, symo, startva, resoff;
|
||||
ElfEhdr *eh;
|
||||
ElfPhdr *ph, *pph;
|
||||
ElfShdr *sh;
|
||||
@ -336,6 +339,8 @@ asmb(void)
|
||||
if(elfverneed)
|
||||
elftextsh += 2;
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd)
|
||||
elftextsh += 1;
|
||||
}
|
||||
|
||||
/* output symbol table */
|
||||
@ -371,7 +376,7 @@ asmb(void)
|
||||
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);
|
||||
@ -455,6 +460,7 @@ asmb(void)
|
||||
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]);
|
||||
@ -487,7 +493,7 @@ asmb(void)
|
||||
sh->addralign = 1;
|
||||
if(interpreter == nil)
|
||||
interpreter = linuxdynld;
|
||||
elfinterp(sh, startva, interpreter);
|
||||
resoff -= elfinterp(sh, startva, resoff, interpreter);
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_INTERP;
|
||||
@ -495,11 +501,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;
|
||||
@ -590,7 +609,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;
|
||||
@ -632,7 +651,9 @@ asmb(void)
|
||||
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;
|
||||
|
@ -707,7 +707,7 @@ asmb(void)
|
||||
{
|
||||
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;
|
||||
@ -778,6 +778,8 @@ asmb(void)
|
||||
if(elfverneed)
|
||||
elftextsh += 2;
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd)
|
||||
elftextsh += 1;
|
||||
break;
|
||||
case Hwindows:
|
||||
break;
|
||||
@ -879,6 +881,7 @@ asmb(void)
|
||||
|
||||
eh = getElfEhdr();
|
||||
startva = INITTEXT - HEADR;
|
||||
resoff = ELFRESERVE;
|
||||
|
||||
/* This null SHdr must appear before all others */
|
||||
newElfShdr(elfstr[ElfStrEmpty]);
|
||||
@ -925,7 +928,7 @@ asmb(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
elfinterp(sh, startva, interpreter);
|
||||
resoff -= elfinterp(sh, startva, resoff, interpreter);
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_INTERP;
|
||||
@ -933,11 +936,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;
|
||||
@ -1061,7 +1077,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;
|
||||
@ -1107,7 +1123,9 @@ asmb(void)
|
||||
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;
|
||||
|
@ -92,6 +92,7 @@ enum {
|
||||
ElfStrPlt,
|
||||
ElfStrGnuVersion,
|
||||
ElfStrGnuVersionR,
|
||||
ElfStrNoteNetbsdIdent,
|
||||
NElfStr
|
||||
};
|
||||
|
||||
@ -528,6 +529,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");
|
||||
@ -661,7 +664,7 @@ asmb(void)
|
||||
{
|
||||
int32 v, magic;
|
||||
int a, dynsym;
|
||||
uint32 symo, startva, dwarfoff, machlink;
|
||||
uint32 symo, startva, dwarfoff, machlink, resoff;
|
||||
ElfEhdr *eh;
|
||||
ElfPhdr *ph, *pph;
|
||||
ElfShdr *sh;
|
||||
@ -715,6 +718,8 @@ asmb(void)
|
||||
if(elfverneed)
|
||||
elftextsh += 2;
|
||||
}
|
||||
if(HEADTYPE == Hnetbsd)
|
||||
elftextsh += 1;
|
||||
}
|
||||
|
||||
symsize = 0;
|
||||
@ -761,7 +766,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);
|
||||
@ -932,6 +937,7 @@ asmb(void)
|
||||
Elfput:
|
||||
eh = getElfEhdr();
|
||||
startva = INITTEXT - HEADR;
|
||||
resoff = ELFRESERVE;
|
||||
|
||||
/* This null SHdr must appear before all others */
|
||||
newElfShdr(elfstr[ElfStrEmpty]);
|
||||
@ -978,7 +984,7 @@ asmb(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
elfinterp(sh, startva, interpreter);
|
||||
resoff -= elfinterp(sh, startva, resoff, interpreter);
|
||||
|
||||
ph = newElfPhdr();
|
||||
ph->type = PT_INTERP;
|
||||
@ -986,11 +992,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;
|
||||
@ -1114,7 +1133,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;
|
||||
@ -1167,7 +1186,9 @@ asmb(void)
|
||||
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;
|
||||
|
@ -318,29 +318,77 @@ elfwritedynentsymsize(Sym *s, int tag, Sym *t)
|
||||
}
|
||||
|
||||
int
|
||||
elfwriteinterp(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
if(interp == nil)
|
||||
return 0;
|
||||
|
||||
n = strlen(interp)+1;
|
||||
cseek(ELFRESERVE-n);
|
||||
cwrite(interp, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
elfinterp(ElfShdr *sh, uint64 startva, char *p)
|
||||
elfinterp(ElfShdr *sh, uint64 startva, uint64 resoff, char *p)
|
||||
{
|
||||
int n;
|
||||
|
||||
interp = p;
|
||||
n = strlen(interp)+1;
|
||||
sh->addr = startva + ELFRESERVE - n;
|
||||
sh->off = ELFRESERVE - n;
|
||||
sh->addr = startva + resoff - n;
|
||||
sh->off = resoff - n;
|
||||
sh->size = n;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
@ -968,8 +968,10 @@ extern int numelfphdr;
|
||||
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*);
|
||||
|
Loading…
Reference in New Issue
Block a user