Hnetbsd,
Hopenbsd,
Hplan9,
+ Hsolaris,
Hwindows,
};
char openbsddynld[] = "XXX";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "XXX";
+char solarisdynld[] = "XXX";
static int
needlib(char *name)
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
+char solarisdynld[] = "/lib/amd64/ld.so.1";
char zeroes[32];
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
debug['8'] = 1; /* 64-bit addresses */
break;
case Hwindows:
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
symo = rnd(HEADR+segtext.len, INITRND)+rnd(segrodata.len, INITRND)+segdata.filelen;
symo = rnd(symo, INITRND);
break;
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
asmbelf(symo);
break;
case Hwindows:
case Hlinux:
case Hnetbsd:
case Hopenbsd:
+ case Hsolaris:
break;
}
ctxt->linkmode = linkmode;
case Hnetbsd: /* netbsd */
case Hopenbsd: /* openbsd */
case Hdragonfly: /* dragonfly */
+ case Hsolaris: /* solaris */
elfinit();
HEADR = ELFRESERVE;
if(INITTEXT == -1)
char openbsddynld[] = "/usr/libexec/ld.so";
char netbsddynld[] = "/usr/libexec/ld.elf_so";
char dragonflydynld[] = "/usr/libexec/ld-elf.so.2";
+char solarisdynld[] = "/lib/ld.so.1";
static int
needlib(char *name)
Write NetBSD ELF binaries (default when $GOOS is netbsd)
-H openbsd (only in 6l/8l)
Write OpenBSD ELF binaries (default when $GOOS is openbsd)
+ -H solaris (only in 6l)
+ Write Solaris ELF binaries (default when $GOOS is solaris)
-H windows (only in 6l/8l)
Write Windows PE32+ Console binaries (default when $GOOS is windows)
-H windowsgui (only in 6l/8l)
elfwritedynent(s, DT_VERNEEDNUM, nfile);
elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
}
+
+ if(thechar == '6') {
+ sy = linklookup(ctxt, ".rela.plt", 0);
+ if(sy->size > 0) {
+ elfwritedynent(s, DT_PLTREL, DT_RELA);
+ elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
+ elfwritedynentsym(s, DT_JMPREL, sy);
+ }
+ } else {
+ sy = linklookup(ctxt, ".rel.plt", 0);
+ if(sy->size > 0) {
+ elfwritedynent(s, DT_PLTREL, DT_REL);
+ elfwritedynentsymsize(s, DT_PLTRELSZ, sy);
+ elfwritedynentsym(s, DT_JMPREL, sy);
+ }
+ }
+
elfwritedynent(s, DT_NULL, 0);
}
elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0));
- if(thechar == '6') {
- elfwritedynent(s, DT_PLTREL, DT_RELA);
- elfwritedynentsymsize(s, DT_PLTRELSZ, linklookup(ctxt, ".rela.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, linklookup(ctxt, ".rela.plt", 0));
- } else {
- elfwritedynent(s, DT_PLTREL, DT_REL);
- elfwritedynentsymsize(s, DT_PLTRELSZ, linklookup(ctxt, ".rel.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, linklookup(ctxt, ".rel.plt", 0));
- }
-
+ // Solaris dynamic linker can't handle an empty .rela.plt if
+ // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
+ // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
+ // size of .rel(a).plt section.
elfwritedynent(s, DT_DEBUG, 0);
// Do not write DT_NULL. elfdynhash will finish it.
case Hdragonfly:
interpreter = dragonflydynld;
break;
+ case Hsolaris:
+ interpreter = solarisdynld;
+ break;
}
}
resoff -= elfinterp(sh, startva, resoff, interpreter);
extern char netbsddynld[];
extern char openbsddynld[];
extern char dragonflydynld[];
+extern char solarisdynld[];
int elfreloc1(Reloc*, vlong sectoff);
void putelfsectionsyms(void);
//
// Exception: on OS X, programs such as Shark only work with dynamic
// binaries, so leave it enabled on OS X (Mach-O) binaries.
- if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin)
+ // Also leave it enabled on Solaris which doesn't support
+ // statically linked binaries.
+ if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris)
debug['d'] = 1;
importcycles();
}
if(ctxt->headtype == Hlinux || ctxt->headtype == Hfreebsd
|| ctxt->headtype == Hopenbsd || ctxt->headtype == Hnetbsd
- || ctxt->headtype == Hplan9 || ctxt->headtype == Hdragonfly) {
+ || ctxt->headtype == Hplan9 || ctxt->headtype == Hdragonfly
+ || ctxt->headtype == Hsolaris) {
// ELF uses FS instead of GS.
if(p->from.type == D_INDIR+D_GS)
p->from.type = D_INDIR+D_FS;
p->as = AMOVQ;
if(ctxt->headtype == Hlinux || ctxt->headtype == Hfreebsd
|| ctxt->headtype == Hopenbsd || ctxt->headtype == Hnetbsd
- || ctxt->headtype == Hplan9 || ctxt->headtype == Hdragonfly)
+ || ctxt->headtype == Hplan9 || ctxt->headtype == Hdragonfly
+ || ctxt->headtype == Hsolaris)
// ELF uses FS
p->from.type = D_INDIR+D_FS;
else
"netbsd", Hnetbsd,
"openbsd", Hopenbsd,
"plan9", Hplan9,
+ "solaris", Hsolaris,
"windows", Hwindows,
"windowsgui", Hwindows,
0, 0
case Hnetbsd:
case Hopenbsd:
case Hdragonfly:
+ case Hsolaris:
/*
* ELF uses TLS offset negative from FS.
* Translate 0(FS) and 8(FS) into -16(FS) and -8(FS).