]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: enable external linking on ppc64
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Thu, 3 Sep 2015 20:30:15 +0000 (08:30 +1200)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Tue, 10 Nov 2015 01:47:41 +0000 (01:47 +0000)
Change-Id: Iffe8ccb55b2c555b2cb8c168cebfbfd5892212df
Reviewed-on: https://go-review.googlesource.com/14236
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/ppc64/obj.go

index 8c2f9aad78c834dca630c47da74a1182c9c33ed3..b274e4524b9c1cacf70aa33e3f84d0600079eef8 100644 (file)
@@ -564,18 +564,23 @@ const (
        R_PPC_EMB_BIT_FLD     = 115
        R_PPC_EMB_RELSDA      = 116
 
-       R_PPC64_REL24       = R_PPC_REL24
-       R_PPC64_JMP_SLOT    = R_PPC_JMP_SLOT
-       R_PPC64_ADDR64      = 38
-       R_PPC64_TOC16       = 47
-       R_PPC64_TOC16_LO    = 48
-       R_PPC64_TOC16_HI    = 49
-       R_PPC64_TOC16_HA    = 50
-       R_PPC64_TOC16_DS    = 63
-       R_PPC64_TOC16_LO_DS = 64
-       R_PPC64_REL16_LO    = 250
-       R_PPC64_REL16_HI    = 251
-       R_PPC64_REL16_HA    = 252
+       R_PPC64_ADDR32       = R_PPC_ADDR32
+       R_PPC64_ADDR16_LO    = R_PPC_ADDR16_LO
+       R_PPC64_ADDR16_HA    = R_PPC_ADDR16_HA
+       R_PPC64_REL24        = R_PPC_REL24
+       R_PPC64_JMP_SLOT     = R_PPC_JMP_SLOT
+       R_PPC64_TPREL16      = R_PPC_TPREL16
+       R_PPC64_ADDR64       = 38
+       R_PPC64_TOC16        = 47
+       R_PPC64_TOC16_LO     = 48
+       R_PPC64_TOC16_HI     = 49
+       R_PPC64_TOC16_HA     = 50
+       R_PPC64_ADDR16_LO_DS = 57
+       R_PPC64_TOC16_DS     = 63
+       R_PPC64_TOC16_LO_DS  = 64
+       R_PPC64_REL16_LO     = 250
+       R_PPC64_REL16_HI     = 251
+       R_PPC64_REL16_HA     = 252
 
        R_SPARC_NONE     = 0
        R_SPARC_8        = 1
index e6dbec23ebf57895632c366dc43c1451beafad36..cdcfb3d076b173ff77c38196d864d20575354354 100644 (file)
@@ -293,8 +293,48 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
 }
 
 func elfreloc1(r *ld.Reloc, sectoff int64) int {
-       // TODO(minux)
-       return -1
+       ld.Thearch.Vput(uint64(sectoff))
+
+       elfsym := r.Xsym.ElfsymForReloc()
+       switch r.Type {
+       default:
+               return -1
+
+       case obj.R_ADDR:
+               switch r.Siz {
+               case 4:
+                       ld.Thearch.Vput(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32)
+               case 8:
+                       ld.Thearch.Vput(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32)
+               default:
+                       return -1
+               }
+
+       case obj.R_POWER_TLS_LE:
+               ld.Thearch.Vput(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32)
+
+       case obj.R_ADDRPOWER:
+               ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
+               ld.Thearch.Vput(uint64(r.Xadd))
+               ld.Thearch.Vput(uint64(sectoff + 4))
+               ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32)
+
+       case obj.R_ADDRPOWER_DS:
+               ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
+               ld.Thearch.Vput(uint64(r.Xadd))
+               ld.Thearch.Vput(uint64(sectoff + 4))
+               ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32)
+
+       case obj.R_CALLPOWER:
+               if r.Siz != 4 {
+                       return -1
+               }
+               ld.Thearch.Vput(ld.R_PPC64_REL24 | uint64(elfsym)<<32)
+
+       }
+       ld.Thearch.Vput(uint64(r.Xadd))
+
+       return 0
 }
 
 func elfsetupplt() {
@@ -381,10 +421,42 @@ func archrelocaddr(r *ld.Reloc, s *ld.LSym, val *int64) int {
 
 func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
        if ld.Linkmode == ld.LinkExternal {
-               // TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
-               // R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
-               // R_CALLPOWER corresponds to R_PPC_REL24.
-               return -1
+               switch r.Type {
+               default:
+                       return -1
+
+               case obj.R_POWER_TLS_LE:
+                       r.Done = 0
+                       // check Outer is nil, Type is TLSBSS?
+                       r.Xadd = r.Add
+                       r.Xsym = r.Sym
+                       return 0
+
+               case obj.R_ADDRPOWER,
+                       obj.R_ADDRPOWER_DS:
+                       r.Done = 0
+
+                       // set up addend for eventual relocation via outer symbol.
+                       rs := r.Sym
+                       r.Xadd = r.Add
+                       for rs.Outer != nil {
+                               r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
+                               rs = rs.Outer
+                       }
+
+                       if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
+                               ld.Diag("missing section for %s", rs.Name)
+                       }
+                       r.Xsym = rs
+
+                       return 0
+
+               case obj.R_CALLPOWER:
+                       r.Done = 0
+                       r.Xsym = r.Sym
+                       r.Xadd = r.Add
+                       return 0
+               }
        }
 
        switch r.Type {
index e2c98fc59e074db5833804157ff801d053c8fb31..0fb401161c96c05b4d933561fb6bbaca9f9463dc 100644 (file)
@@ -111,6 +111,9 @@ func archinit() {
                if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" {
                        log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE)))
                }
+
+       case obj.Hlinux:
+               break
        }
 
        switch ld.HEADTYPE {