]> Cypherpunks repositories - gostls13.git/commitdiff
include, linlink, cmd/6l, cmd/ld: part 1 of solaris/amd64 linker changes.
authorShenghou Ma <minux.ma@gmail.com>
Sun, 9 Feb 2014 21:45:38 +0000 (16:45 -0500)
committerShenghou Ma <minux.ma@gmail.com>
Sun, 9 Feb 2014 21:45:38 +0000 (16:45 -0500)
rsc suggested that we split the whole linker changes into three parts.
This is the first one, mostly dealing with adding Hsolaris.

LGTM=iant
R=golang-codereviews, iant, dave
CC=golang-codereviews
https://golang.org/cl/54210050

include/link.h
src/cmd/5l/asm.c
src/cmd/6l/asm.c
src/cmd/6l/obj.c
src/cmd/8l/asm.c
src/cmd/ld/doc.go
src/cmd/ld/elf.c
src/cmd/ld/elf.h
src/cmd/ld/lib.c
src/liblink/obj6.c
src/liblink/sym.c

index 32d158428de29d3f11d223f3e883e5af79b64c73..e040e203f89b3832359d52a4d02150d7e19692dc 100644 (file)
@@ -451,6 +451,7 @@ enum {
        Hnetbsd,
        Hopenbsd,
        Hplan9,
+       Hsolaris,
        Hwindows,
 };
 
index 85600cabf6f72bca04c31579cc091f390d9c2749..096d321cb98ea34d81e7bc475914333bf188dd05 100644 (file)
@@ -41,6 +41,7 @@ char freebsddynld[] = "/usr/libexec/ld-elf.so.1";
 char openbsddynld[] = "XXX";
 char netbsddynld[] = "/libexec/ld.elf_so";
 char dragonflydynld[] = "XXX";
+char solarisdynld[] = "XXX";
 
 static int
 needlib(char *name)
index 084e2cc6a7c3233053079017a864e4ca8b961824..813bdc8485fc84ebb622f2a0658621b9124f3a32 100644 (file)
@@ -44,6 +44,7 @@ char freebsddynld[] = "/libexec/ld-elf.so.1";
 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];
 
@@ -645,6 +646,7 @@ asmb(void)
        case Hnetbsd:
        case Hopenbsd:
        case Hdragonfly:
+       case Hsolaris:
                debug['8'] = 1; /* 64-bit addresses */
                break;
        case Hwindows:
@@ -674,6 +676,7 @@ asmb(void)
                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;
@@ -754,6 +757,7 @@ asmb(void)
        case Hnetbsd:
        case Hopenbsd:
        case Hdragonfly:
+       case Hsolaris:
                asmbelf(symo);
                break;
        case Hwindows:
index a2f1465748cfed025ab47fa289d5b8c8c8028f31..92c0c747a04b63cbe86c687ef9b5d6911bf37f5e 100644 (file)
@@ -65,6 +65,7 @@ archinit(void)
        case Hlinux:
        case Hnetbsd:
        case Hopenbsd:
+       case Hsolaris:
                break;
        }
        ctxt->linkmode = linkmode;
@@ -106,6 +107,7 @@ archinit(void)
        case Hnetbsd:           /* netbsd */
        case Hopenbsd:          /* openbsd */
        case Hdragonfly:        /* dragonfly */
+       case Hsolaris:          /* solaris */
                elfinit();
                HEADR = ELFRESERVE;
                if(INITTEXT == -1)
index 46e8e47ecdc0fcd977c91d115e7ffea7f589ec2d..03f9e95c9b0c115d3549bbc9c43726e492775ed4 100644 (file)
@@ -42,6 +42,7 @@ char freebsddynld[] = "/usr/libexec/ld-elf.so.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)
index 064a7dfb5f7b16ccba610282a865c51daad85fc8..8135bd549c3ec21a5080e6a59e0a9bd533434204 100644 (file)
@@ -43,6 +43,8 @@ Options new in this version:
                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)
index 3b8bfb005706ac9c768dd999c6bf43d2571de537..dd992e42044726167b80fede08a93fdc9b0254e7 100644 (file)
@@ -677,6 +677,23 @@ elfdynhash(void)
                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);
 }
 
@@ -1058,16 +1075,10 @@ doelf(void)
                
                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.
@@ -1192,6 +1203,9 @@ asmbelf(vlong symo)
                        case Hdragonfly:
                                interpreter = dragonflydynld;
                                break;
+                       case Hsolaris:
+                               interpreter = solarisdynld;
+                               break;
                        }
                }
                resoff -= elfinterp(sh, startva, resoff, interpreter);
index 76085c7c6ec7baabdac213c486abc99fc17151d8..e84d996f259671e0826ef671a719f1e023b1b72d 100644 (file)
@@ -1010,6 +1010,7 @@ extern char freebsddynld[];
 extern char netbsddynld[];
 extern char openbsddynld[];
 extern char dragonflydynld[];
+extern char solarisdynld[];
 int    elfreloc1(Reloc*, vlong sectoff);
 void   putelfsectionsyms(void);
 
index e092b005bcc510630a4cdb39011f4966413bdcf2..eb02ae5e8c87575937db874c58377ae237be7cc6 100644 (file)
@@ -259,7 +259,9 @@ loadlib(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();
index 6bb65a28698bcbf89db1e62179c8abac17ba0053..e8967f3ec71ba96c483644aea7f73b711dc322d5 100644 (file)
@@ -137,7 +137,8 @@ progedit(Link *ctxt, Prog *p)
        }
        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;
@@ -577,7 +578,8 @@ load_g_cx(Link *ctxt, Prog *p)
        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
index e2527da3a7c9051aab16ccee422a174b04eff27b..7ff64350df818db9a6c5c51d81baffce763df744 100644 (file)
@@ -52,6 +52,7 @@ static struct {
        "netbsd",       Hnetbsd,
        "openbsd",      Hopenbsd,
        "plan9",        Hplan9,
+       "solaris",      Hsolaris,
        "windows",      Hwindows,
        "windowsgui",   Hwindows,
        0, 0
@@ -129,6 +130,7 @@ linknew(LinkArch *arch)
        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).