Commit 420fe229 authored by Christopher Nielsen's avatar Christopher Nielsen Committed by Russ Cox

ld/6l/8l: First pass at changes to the linker to support NetBSD binaries.

This will not currently create valid NetBSD binaries because NetBSD requires
an ELF note section to run, otherwise the kernel will throw ENOEXEC. I was
unable to determine an elegant way to add the section, so I am submitting
what I have.

References:
http://www.netbsd.org/docs/kernel/elf-notes.html
http://mail-index.netbsd.org/netbsd-bugs/2001/08/03/0012.html

R=rsc
CC=golang-dev
https://golang.org/cl/5472049
parent 728c16cf
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2"; char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2";
char freebsddynld[] = "/libexec/ld-elf.so.1"; char freebsddynld[] = "/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so"; char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/libexec/ld.elf_so";
char zeroes[32]; char zeroes[32];
...@@ -95,6 +96,7 @@ enum { ...@@ -95,6 +96,7 @@ enum {
ElfStrPlt, ElfStrPlt,
ElfStrGnuVersion, ElfStrGnuVersion,
ElfStrGnuVersionR, ElfStrGnuVersionR,
ElfStrNoteNetbsdIdent,
NElfStr NElfStr
}; };
...@@ -558,7 +560,7 @@ doelf(void) ...@@ -558,7 +560,7 @@ doelf(void)
{ {
Sym *s, *shstrtab, *dynstr; Sym *s, *shstrtab, *dynstr;
if(HEADTYPE != Hlinux && HEADTYPE != Hfreebsd && HEADTYPE != Hopenbsd) if(HEADTYPE != Hlinux && HEADTYPE != Hfreebsd && HEADTYPE != Hopenbsd && HEADTYPE != Hnetbsd)
return; return;
/* predefine strings we need for section headers */ /* predefine strings we need for section headers */
...@@ -570,6 +572,8 @@ doelf(void) ...@@ -570,6 +572,8 @@ doelf(void)
elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrText] = addstring(shstrtab, ".text");
elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrData] = addstring(shstrtab, ".data");
elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss");
if(HEADTYPE == Hnetbsd)
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
addstring(shstrtab, ".elfdata"); addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata"); addstring(shstrtab, ".rodata");
addstring(shstrtab, ".gosymtab"); addstring(shstrtab, ".gosymtab");
...@@ -763,6 +767,7 @@ asmb(void) ...@@ -763,6 +767,7 @@ asmb(void)
break; break;
case Hlinux: case Hlinux:
case Hfreebsd: case Hfreebsd:
case Hnetbsd:
case Hopenbsd: case Hopenbsd:
debug['8'] = 1; /* 64-bit addresses */ debug['8'] = 1; /* 64-bit addresses */
/* index of elf text section; needed by asmelfsym, double-checked below */ /* index of elf text section; needed by asmelfsym, double-checked below */
...@@ -798,6 +803,7 @@ asmb(void) ...@@ -798,6 +803,7 @@ asmb(void)
break; break;
case Hlinux: case Hlinux:
case Hfreebsd: case Hfreebsd:
case Hnetbsd:
case Hopenbsd: case Hopenbsd:
symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen; symo = rnd(HEADR+segtext.len, INITRND)+segdata.filelen;
symo = rnd(symo, INITRND); symo = rnd(symo, INITRND);
...@@ -867,6 +873,7 @@ asmb(void) ...@@ -867,6 +873,7 @@ asmb(void)
break; break;
case Hlinux: case Hlinux:
case Hfreebsd: case Hfreebsd:
case Hnetbsd:
case Hopenbsd: case Hopenbsd:
/* elf amd-64 */ /* elf amd-64 */
...@@ -910,6 +917,9 @@ asmb(void) ...@@ -910,6 +917,9 @@ asmb(void)
case Hfreebsd: case Hfreebsd:
interpreter = freebsddynld; interpreter = freebsddynld;
break; break;
case Hnetbsd:
interpreter = netbsddynld;
break;
case Hopenbsd: case Hopenbsd:
interpreter = openbsddynld; interpreter = openbsddynld;
break; break;
...@@ -1076,6 +1086,8 @@ asmb(void) ...@@ -1076,6 +1086,8 @@ asmb(void)
eh->ident[EI_MAG3] = 'F'; eh->ident[EI_MAG3] = 'F';
if(HEADTYPE == Hfreebsd) if(HEADTYPE == Hfreebsd)
eh->ident[EI_OSABI] = ELFOSABI_FREEBSD; eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
else if(HEADTYPE == Hnetbsd)
eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
else if(HEADTYPE == Hopenbsd) else if(HEADTYPE == Hopenbsd)
eh->ident[EI_OSABI] = ELFOSABI_OPENBSD; eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
eh->ident[EI_CLASS] = ELFCLASS64; eh->ident[EI_CLASS] = ELFCLASS64;
......
...@@ -31,6 +31,8 @@ Options new in this version: ...@@ -31,6 +31,8 @@ Options new in this version:
Write Linux ELF binaries (default when $GOOS is linux) Write Linux ELF binaries (default when $GOOS is linux)
-Hfreebsd -Hfreebsd
Write FreeBSD ELF binaries (default when $GOOS is freebsd) Write FreeBSD ELF binaries (default when $GOOS is freebsd)
-Hnetbsd
Write NetBSD ELF binaries (default when $GOOS is netbsd)
-Hopenbsd -Hopenbsd
Write OpenBSD ELF binaries (default when $GOOS is openbsd) Write OpenBSD ELF binaries (default when $GOOS is openbsd)
-Hwindows -Hwindows
......
...@@ -44,16 +44,17 @@ char* thestring = "amd64"; ...@@ -44,16 +44,17 @@ char* thestring = "amd64";
char* paramspace = "FP"; char* paramspace = "FP";
Header headers[] = { Header headers[] = {
"plan9x32", Hplan9x32, "plan9x32", Hplan9x32,
"plan9", Hplan9x64, "plan9", Hplan9x64,
"elf", Helf, "elf", Helf,
"darwin", Hdarwin, "darwin", Hdarwin,
"linux", Hlinux, "linux", Hlinux,
"freebsd", Hfreebsd, "freebsd", Hfreebsd,
"openbsd", Hopenbsd, "netbsd", Hnetbsd,
"windows", Hwindows, "openbsd", Hopenbsd,
"windowsgui", Hwindows, "windows", Hwindows,
0, 0 "windowsgui", Hwindows,
0, 0
}; };
/* /*
...@@ -63,6 +64,7 @@ Header headers[] = { ...@@ -63,6 +64,7 @@ Header headers[] = {
* -Hdarwin -Tx -Rx is apple MH-exec * -Hdarwin -Tx -Rx is apple MH-exec
* -Hlinux -Tx -Rx is linux elf-exec * -Hlinux -Tx -Rx is linux elf-exec
* -Hfreebsd -Tx -Rx is FreeBSD elf-exec * -Hfreebsd -Tx -Rx is FreeBSD elf-exec
* -Hnetbsd -Tx -Rx is NetBSD elf-exec
* -Hopenbsd -Tx -Rx is OpenBSD elf-exec * -Hopenbsd -Tx -Rx is OpenBSD elf-exec
* -Hwindows -Tx -Rx is MS Windows PE32+ * -Hwindows -Tx -Rx is MS Windows PE32+
* *
...@@ -197,6 +199,7 @@ main(int argc, char *argv[]) ...@@ -197,6 +199,7 @@ main(int argc, char *argv[])
break; break;
case Hlinux: /* elf64 executable */ case Hlinux: /* elf64 executable */
case Hfreebsd: /* freebsd */ case Hfreebsd: /* freebsd */
case Hnetbsd: /* netbsd */
case Hopenbsd: /* openbsd */ case Hopenbsd: /* openbsd */
/* /*
* ELF uses TLS offset negative from FS. * ELF uses TLS offset negative from FS.
......
...@@ -295,7 +295,7 @@ patch(void) ...@@ -295,7 +295,7 @@ patch(void)
} }
} }
if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
|| HEADTYPE == Hopenbsd) { || HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd) {
// ELF uses FS instead of GS. // ELF uses FS instead of GS.
if(p->from.type == D_INDIR+D_GS) if(p->from.type == D_INDIR+D_GS)
p->from.type = D_INDIR+D_FS; p->from.type = D_INDIR+D_FS;
...@@ -421,7 +421,7 @@ dostkoff(void) ...@@ -421,7 +421,7 @@ dostkoff(void)
p = appendp(p); // load g into CX p = appendp(p); // load g into CX
p->as = AMOVQ; p->as = AMOVQ;
if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd if(HEADTYPE == Hlinux || HEADTYPE == Hfreebsd
|| HEADTYPE == Hopenbsd) // ELF uses FS || HEADTYPE == Hopenbsd || HEADTYPE == Hnetbsd) // ELF uses FS
p->from.type = D_INDIR+D_FS; p->from.type = D_INDIR+D_FS;
else else
p->from.type = D_INDIR+D_GS; p->from.type = D_INDIR+D_GS;
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
char linuxdynld[] = "/lib/ld-linux.so.2"; char linuxdynld[] = "/lib/ld-linux.so.2";
char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
char openbsddynld[] = "/usr/libexec/ld.so"; char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/usr/libexec/ld.elf_so";
int32 int32
entryvalue(void) entryvalue(void)
...@@ -969,6 +970,9 @@ asmb(void) ...@@ -969,6 +970,9 @@ asmb(void)
case Hfreebsd: case Hfreebsd:
interpreter = freebsddynld; interpreter = freebsddynld;
break; break;
case Hnetbsd:
interpreter = netbsddynld;
break;
case Hopenbsd: case Hopenbsd:
interpreter = openbsddynld; interpreter = openbsddynld;
break; break;
...@@ -1140,6 +1144,9 @@ asmb(void) ...@@ -1140,6 +1144,9 @@ asmb(void)
case Hfreebsd: case Hfreebsd:
eh->ident[EI_OSABI] = ELFOSABI_FREEBSD; eh->ident[EI_OSABI] = ELFOSABI_FREEBSD;
break; break;
case Hnetbsd:
eh->ident[EI_OSABI] = ELFOSABI_NETBSD;
break;
case Hopenbsd: case Hopenbsd:
eh->ident[EI_OSABI] = ELFOSABI_OPENBSD; eh->ident[EI_OSABI] = ELFOSABI_OPENBSD;
break; break;
......
...@@ -33,6 +33,8 @@ Options new in this version: ...@@ -33,6 +33,8 @@ Options new in this version:
Write Linux ELF binaries (default when $GOOS is linux) Write Linux ELF binaries (default when $GOOS is linux)
-Hfreebsd -Hfreebsd
Write FreeBSD ELF binaries (default when $GOOS is freebsd) Write FreeBSD ELF binaries (default when $GOOS is freebsd)
-Hnetbsd
Write NetBSD ELF binaries (default when $GOOS is netbsd)
-Hopenbsd -Hopenbsd
Write OpenBSD ELF binaries (default when $GOOS is openbsd) Write OpenBSD ELF binaries (default when $GOOS is openbsd)
-Hwindows -Hwindows
......
...@@ -47,18 +47,19 @@ char *noname = "<none>"; ...@@ -47,18 +47,19 @@ char *noname = "<none>";
char *thestring = "386"; char *thestring = "386";
Header headers[] = { Header headers[] = {
"garbunix", Hgarbunix, "garbunix", Hgarbunix,
"unixcoff", Hunixcoff, "unixcoff", Hunixcoff,
"plan9", Hplan9x32, "plan9", Hplan9x32,
"msdoscom", Hmsdoscom, "msdoscom", Hmsdoscom,
"msdosexe", Hmsdosexe, "msdosexe", Hmsdosexe,
"darwin", Hdarwin, "darwin", Hdarwin,
"linux", Hlinux, "linux", Hlinux,
"freebsd", Hfreebsd, "freebsd", Hfreebsd,
"openbsd", Hopenbsd, "netbsd", Hnetbsd,
"windows", Hwindows, "openbsd", Hopenbsd,
"windowsgui", Hwindows, "windows", Hwindows,
0, 0 "windowsgui", Hwindows,
0, 0
}; };
/* /*
...@@ -70,6 +71,7 @@ Header headers[] = { ...@@ -70,6 +71,7 @@ Header headers[] = {
* -Hdarwin -Tx -Rx is Apple Mach-O * -Hdarwin -Tx -Rx is Apple Mach-O
* -Hlinux -Tx -Rx is Linux ELF32 * -Hlinux -Tx -Rx is Linux ELF32
* -Hfreebsd -Tx -Rx is FreeBSD ELF32 * -Hfreebsd -Tx -Rx is FreeBSD ELF32
* -Hnetbsd -Tx -Rx is NetBSD ELF32
* -Hopenbsd -Tx -Rx is OpenBSD ELF32 * -Hopenbsd -Tx -Rx is OpenBSD ELF32
* -Hwindows -Tx -Rx is MS Windows PE32 * -Hwindows -Tx -Rx is MS Windows PE32
*/ */
...@@ -225,6 +227,7 @@ main(int argc, char *argv[]) ...@@ -225,6 +227,7 @@ main(int argc, char *argv[])
break; break;
case Hlinux: /* elf32 executable */ case Hlinux: /* elf32 executable */
case Hfreebsd: case Hfreebsd:
case Hnetbsd:
case Hopenbsd: case Hopenbsd:
/* /*
* ELF uses TLS offsets negative from %gs. * ELF uses TLS offsets negative from %gs.
......
...@@ -124,11 +124,11 @@ Uconv(Fmt *fp) ...@@ -124,11 +124,11 @@ Uconv(Fmt *fp)
if(s && *s) { if(s && *s) {
if(upper) if(upper)
str[0] = toupper(*s); str[0] = toupper((uchar)*s);
else else
str[0] = tolower(*s); str[0] = tolower((uchar)*s);
for(i = 1; i < STRINGSZ && s[i] != 0; i++) for(i = 1; i < STRINGSZ && s[i] != 0; i++)
str[i] = tolower(s[i]); str[i] = tolower((uchar)s[i]);
str[i] = 0; str[i] = 0;
} }
......
...@@ -115,7 +115,7 @@ addlib(char *src, char *obj) ...@@ -115,7 +115,7 @@ addlib(char *src, char *obj)
sprint(name, ""); sprint(name, "");
i = 1; i = 1;
} else } else
if(isalpha(histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') { if(isalpha((uchar)histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') {
strcpy(name, histfrog[0]->name+1); strcpy(name, histfrog[0]->name+1);
i = 1; i = 1;
} else } else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment