pkgsrc/lang/go14/patches/patch-src_cmd_ld_data.c
bsiegert 4f034c2357 Create lang/go14 as a copy of lang/go but which installs under
$PREFIX/go14.

Go 1.5 is going to be released soon, and it will depend on an existing
installation of Go 1.4 to compile. So let's provide one.
2015-07-31 14:46:25 +00:00

139 lines
3.3 KiB
C

$NetBSD: patch-src_cmd_ld_data.c,v 1.1 2015/07/31 14:46:25 bsiegert Exp $
Support cgo on illumos.
--- src/cmd/ld/data.c.orig 2014-12-11 01:18:12.000000000 +0000
+++ src/cmd/ld/data.c
@@ -965,6 +965,46 @@ dodata(void)
datap = listsort(datap, datcmp, offsetof(LSym, next));
/*
+ * The SunOS rtld expects the .rel/.rela and .rel.plt/.rela.plt
+ * sections to be contiguous. More properly, it expects that the
+ * region starting from the lower of DT_RELA and DT_PLTREL and
+ * continuing for DT_RELASZ bytes contains at least the set of non-PLT
+ * relocation entries. To ensure this, we put .rel[a].plt after .rel[a].
+ * This is actually required by the ELF gABI on all ELF platforms.
+ */
+ if (ctxt->headtype == Hsolaris) {
+ for (l = &datap; (s = *l) != nil; ) {
+ if (strcmp(s->name, ".rel.plt") == 0 ||
+ strcmp(s->name, ".rela.plt") == 0) {
+ *l = s->next;
+ s->next = nil;
+ last = s;
+ break;
+ }
+ l = &s->next;
+ }
+
+ if (s != nil) {
+ for (s = datap; s != nil; s = s->next) {
+ if (strcmp(s->name, ".rel") == 0 ||
+ strcmp(s->name, ".rela") == 0) {
+ last->next = s->next;
+ s->next = last;
+ break;
+ }
+ }
+ /*
+ * .rel[a].plt without .rel[a]. Should never occur
+ * but just in case, put it back where we found it.
+ */
+ if (s == nil) {
+ last->next = (*l)->next;
+ (*l)->next = last;
+ }
+ }
+ }
+
+ /*
* allocate sections. list is sorted by type,
* so we can just walk it for each piece we want to emit.
* segdata is processed before segtext, because we need
@@ -1239,6 +1279,85 @@ dodata(void)
sect->extnum = n++;
}
+/*
+ * Fix up the section numbers in .dynsym if present. We could not write these
+ * shndx entries until we know all present sections and have sorted them.
+ *
+ * Each dynsym entry is actually an ElfXX_Sym, and we're going to replace the
+ * st_shndx field. For 32-bit targets, that's at offset 0xe; for 64-bit, it's
+ * at offset 0x6. Anything we don't expect, we ignore and leave unchanged.
+ */
+void
+dodynsym(void)
+{
+ LSym *ds;
+ LSym *ss;
+ LSym *s;
+ vlong off;
+ size_t entsz;
+ uint16 ent;
+ char *sectname = nil;
+
+ if (!iself)
+ return;
+
+ ds = linklookup(ctxt, ".dynsym", 0);
+
+ if (ds == nil)
+ return;
+
+ if (thechar == '6')
+ entsz = ELF64SYMSIZE;
+ else
+ entsz = ELF32SYMSIZE;
+
+ for(s = ctxt->allsym; s != nil; s = s->allsym) {
+ if (s->dynid <= 0 || s->type == SDYNIMPORT)
+ continue;
+
+ if (s->sect != nil) {
+ ent = s->sect->extnum;
+ } else {
+ switch (s->type) {
+ case STEXT:
+ default:
+ sectname = ".text";
+ break;
+ case SRODATA:
+ sectname = ".rodata";
+ break;
+ case SDATA:
+ sectname = ".data";
+ break;
+ case SBSS:
+ sectname = ".bss";
+ break;
+ }
+
+ ss = linklookup(ctxt, sectname, 0);
+ if (ss == nil || ss->sect == nil) {
+ diag("dodynsym: symbol %s in nonexistent %s",
+ s->extname != nil ? s->extname : "<none>",
+ sectname);
+ continue;
+ }
+
+ ent = ss->sect->extnum;
+ }
+
+ if (ent == 0) {
+ diag("dodynsym: symbol %s in section 0; ignored");
+ continue;
+ }
+
+ off = s->dynid * entsz +
+ ((thechar == '6') ? offsetof(Elf64_Sym, shndx) :
+ offsetof(Elf32_Sym, shndx));
+
+ (void) setuint16(ctxt, ds, off, ent);
+ }
+}
+
// assign addresses to text
void
textaddress(void)