]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, runtime: add external linking support for linux/mips64x
authorCherry Zhang <lunaria21@gmail.com>
Thu, 28 Apr 2016 02:18:09 +0000 (22:18 -0400)
committerMinux Ma <minux@golang.org>
Sun, 1 May 2016 02:38:37 +0000 (02:38 +0000)
Fixes #12560

Change-Id: Ic2004fc7b09f2dbbf83c41f8c6307757c0e1676d
Reviewed-on: https://go-review.googlesource.com/19803
Reviewed-by: Minux Ma <minux@golang.org>
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/mips64/obj.go
src/runtime/asm_mips64x.s
src/runtime/rt0_linux_mips64x.s

index 15b8d7af93e16a28a087fcb89aeb3e7d87bb08c8..fce099da4581b15cb28750effca955921ee084a4 100644 (file)
@@ -489,6 +489,55 @@ const (
        R_386_IRELATIVE     = 42
        R_386_GOT32X        = 43
 
+       R_MIPS_NONE            = 0
+       R_MIPS_16              = 1
+       R_MIPS_32              = 2
+       R_MIPS_REL32           = 3
+       R_MIPS_26              = 4
+       R_MIPS_HI16            = 5
+       R_MIPS_LO16            = 6
+       R_MIPS_GPREL16         = 7
+       R_MIPS_LITERAL         = 8
+       R_MIPS_GOT16           = 9
+       R_MIPS_PC16            = 10
+       R_MIPS_CALL16          = 11
+       R_MIPS_GPREL32         = 12
+       R_MIPS_SHIFT5          = 16
+       R_MIPS_SHIFT6          = 17
+       R_MIPS_64              = 18
+       R_MIPS_GOT_DISP        = 19
+       R_MIPS_GOT_PAGE        = 20
+       R_MIPS_GOT_OFST        = 21
+       R_MIPS_GOT_HI16        = 22
+       R_MIPS_GOT_LO16        = 23
+       R_MIPS_SUB             = 24
+       R_MIPS_INSERT_A        = 25
+       R_MIPS_INSERT_B        = 26
+       R_MIPS_DELETE          = 27
+       R_MIPS_HIGHER          = 28
+       R_MIPS_HIGHEST         = 29
+       R_MIPS_CALL_HI16       = 30
+       R_MIPS_CALL_LO16       = 31
+       R_MIPS_SCN_DISP        = 32
+       R_MIPS_REL16           = 33
+       R_MIPS_ADD_IMMEDIATE   = 34
+       R_MIPS_PJUMP           = 35
+       R_MIPS_RELGOT          = 36
+       R_MIPS_JALR            = 37
+       R_MIPS_TLS_DTPMOD32    = 38
+       R_MIPS_TLS_DTPREL32    = 39
+       R_MIPS_TLS_DTPMOD64    = 40
+       R_MIPS_TLS_DTPREL64    = 41
+       R_MIPS_TLS_GD          = 42
+       R_MIPS_TLS_LDM         = 43
+       R_MIPS_TLS_DTPREL_HI16 = 44
+       R_MIPS_TLS_DTPREL_LO16 = 45
+       R_MIPS_TLS_GOTTPREL    = 46
+       R_MIPS_TLS_TPREL32     = 47
+       R_MIPS_TLS_TPREL64     = 48
+       R_MIPS_TLS_TPREL_HI16  = 49
+       R_MIPS_TLS_TPREL_LO16  = 50
+
        R_PPC_NONE            = 0
        R_PPC_ADDR32          = 1
        R_PPC_ADDR24          = 2
index f6c7a0152bb675b3b07e9257fdcd5c4205688ba7..a193704eb0de9361cd7dd1bc3b5997fbb437553f 100644 (file)
@@ -1298,6 +1298,8 @@ func hostlinkArchArgs() []string {
                return []string{"-marm"}
        case sys.ARM64:
                // nothing needed
+       case '0':
+               return []string{"-mabi=64"}
        }
        return nil
 }
index 379a550a16d93a89565db359fcc5b7f6e76e7ecc..742ea8a7274978215dd6dc15360d3bd54973c23e 100644 (file)
@@ -45,7 +45,49 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
 }
 
 func elfreloc1(r *ld.Reloc, sectoff int64) int {
-       return -1
+       // mips64 ELF relocation (endian neutral)
+       //              offset  uint64
+       //              sym             uint32
+       //              ssym    uint8
+       //              type3   uint8
+       //              type2   uint8
+       //              type    uint8
+       //              addend  int64
+
+       ld.Thearch.Vput(uint64(sectoff))
+
+       elfsym := r.Xsym.ElfsymForReloc()
+       ld.Thearch.Lput(uint32(elfsym))
+       ld.Cput(0)
+       ld.Cput(0)
+       ld.Cput(0)
+       switch r.Type {
+       default:
+               return -1
+
+       case obj.R_ADDR:
+               switch r.Siz {
+               case 4:
+                       ld.Cput(ld.R_MIPS_32)
+               case 8:
+                       ld.Cput(ld.R_MIPS_64)
+               default:
+                       return -1
+               }
+
+       case obj.R_ADDRMIPS:
+               ld.Cput(ld.R_MIPS_LO16)
+
+       case obj.R_ADDRMIPSU:
+               ld.Cput(ld.R_MIPS_HI16)
+
+       case obj.R_CALLMIPS,
+               obj.R_JMPMIPS:
+               ld.Cput(ld.R_MIPS_26)
+       }
+       ld.Thearch.Vput(uint64(r.Xadd))
+
+       return 0
 }
 
 func elfsetupplt() {
@@ -58,7 +100,36 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
 
 func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
        if ld.Linkmode == ld.LinkExternal {
-               return -1
+               switch r.Type {
+               default:
+                       return -1
+
+               case obj.R_ADDRMIPS,
+                       obj.R_ADDRMIPSU:
+                       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_CALLMIPS,
+                       obj.R_JMPMIPS:
+                       r.Done = 0
+                       r.Xsym = r.Sym
+                       r.Xadd = r.Add
+                       return 0
+               }
        }
 
        switch r.Type {
index 87bb3a079bb02162ece292e2b79c04203a97e0cd..dabd326d2171283597db56ae073d5d7fee4e3e0f 100644 (file)
@@ -107,6 +107,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 {
index f55627ce61703cdfa259eb5026c4f4cff14a436c..85b71d2d907c3027a9d90c5cffa52dfc7e01ec4e 100644 (file)
 #define        REGCTXT R22
 
 TEXT runtime·rt0_go(SB),NOSPLIT,$0
-       // R29 = stack; R1 = argc; R2 = argv
+       // R29 = stack; R4 = argc; R5 = argv
 
        // initialize essential registers
        JAL     runtime·reginit(SB)
 
        ADDV    $-24, R29
-       MOVW    R1, 8(R29) // argc
-       MOVV    R2, 16(R29) // argv
+       MOVW    R4, 8(R29) // argc
+       MOVV    R5, 16(R29) // argv
 
        // create istack out of the given (operating system) stack.
        // _cgo_init may update stackguard.
index 6b596677be540ced55ee2c9e1f3941810a7751ba..beb4ef26acdc5f74562d5af363a680b41e845d06 100644 (file)
@@ -19,18 +19,21 @@ TEXT _main<>(SB),NOSPLIT,$-8
        // sequence of string pointers followed by a NULL, and auxv.
        // There is no TLS base pointer.
 #ifdef GOARCH_mips64
-       MOVW 4(R29), R1 // argc, big-endian ABI places int32 at offset 4
+       MOVW    4(R29), R4 // argc, big-endian ABI places int32 at offset 4
 #else
-       MOVW 0(R29), R1 // argc
+       MOVW    0(R29), R4 // argc
 #endif
-       ADDV $8, R29, R2 // argv
-       JMP main(SB)
+       ADDV    $8, R29, R5 // argv
+       JMP     main(SB)
 
 TEXT main(SB),NOSPLIT,$-8
+       // in external linking, glibc jumps to main with argc in R4
+       // and argv in R5
+
        // initalize REGSB = PC&0xffffffff00000000
        BGEZAL  R0, 1(PC)
        SRLV    $32, R31, RSB
        SLLV    $32, RSB
 
-       MOVV    $runtime·rt0_go(SB), R4
-       JMP     (R4)
+       MOVV    $runtime·rt0_go(SB), R1
+       JMP     (R1)