aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal
diff options
context:
space:
mode:
authorGuoqi Chen <chenguoqi@loongson.cn>2023-10-10 20:16:36 +0800
committerDavid Chase <drchase@google.com>2023-11-21 17:49:21 +0000
commit346e06c46dd1791e924ce4fffc879747bdabedf5 (patch)
tree8088a40fc6284fc2e43cc75d2e3ee6376f603539 /src/cmd/internal
parentf43581131e96f0a4a7745250218ace6c4ea2e557 (diff)
downloadgo-346e06c46dd1791e924ce4fffc879747bdabedf5.tar.xz
cmd/internal/obj,cmd/link: access global data via GOT in -dynlink mode on loong64
Updates #58784 Change-Id: Ic98d10a512fea0c3ca321ab52693d9f6775126a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/480875 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Meidan Li <limeidan@loongson.cn> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: WANG Xuerui <git@xen0n.name> Reviewed-by: WANG Xuerui <git@xen0n.name>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r--src/cmd/internal/obj/loong64/a.out.go1
-rw-r--r--src/cmd/internal/obj/loong64/asm.go21
-rw-r--r--src/cmd/internal/obj/loong64/cnames.go1
-rw-r--r--src/cmd/internal/obj/loong64/obj.go117
-rw-r--r--src/cmd/internal/objabi/reloctype.go5
-rw-r--r--src/cmd/internal/objabi/reloctype_string.go22
6 files changed, 157 insertions, 10 deletions
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go
index a4bb7b40a3..d944fcfcb8 100644
--- a/src/cmd/internal/obj/loong64/a.out.go
+++ b/src/cmd/internal/obj/loong64/a.out.go
@@ -227,6 +227,7 @@ const (
C_ADDR
C_TLS_LE
C_TLS_IE
+ C_GOTADDR
C_TEXTSIZE
C_NCLASS // must be the last
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go
index 19250c94ee..64c9226079 100644
--- a/src/cmd/internal/obj/loong64/asm.go
+++ b/src/cmd/internal/obj/loong64/asm.go
@@ -349,6 +349,8 @@ var optab = []Optab{
{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 40, 4, 0, 0},
{AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0},
+ {AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0},
+
{ATEQ, C_SCON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
{ATEQ, C_SCON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
@@ -676,6 +678,9 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
return C_SOREG
}
return C_LOREG
+
+ case obj.NAME_GOTREF:
+ return C_GOTADDR
}
return C_GOK
@@ -1776,6 +1781,22 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
case 64: // movv c_reg, c_fcc0 ==> movgr2cf cd, rj
a := OP_TEN(8, 1334)
o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
+
+ case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
+ o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
+ rel := obj.Addrel(c.cursym)
+ rel.Off = int32(c.pc)
+ rel.Siz = 4
+ rel.Sym = p.From.Sym
+ rel.Type = objabi.R_LOONG64_GOT_HI
+ rel.Add = 0x0
+ o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
+ rel2 := obj.Addrel(c.cursym)
+ rel2.Off = int32(c.pc + 4)
+ rel2.Siz = 4
+ rel2.Sym = p.From.Sym
+ rel2.Type = objabi.R_LOONG64_GOT_LO
+ rel2.Add = 0x0
}
out[0] = o1
diff --git a/src/cmd/internal/obj/loong64/cnames.go b/src/cmd/internal/obj/loong64/cnames.go
index 8b8af6ba31..94b1b54c93 100644
--- a/src/cmd/internal/obj/loong64/cnames.go
+++ b/src/cmd/internal/obj/loong64/cnames.go
@@ -39,6 +39,7 @@ var cnames0 = []string{
"ADDR",
"TLS_LE",
"TLS_IE",
+ "GOTADDR",
"TEXTSIZE",
"NCLASS",
}
diff --git a/src/cmd/internal/obj/loong64/obj.go b/src/cmd/internal/obj/loong64/obj.go
index d15d0dfd4c..fe98f8c11b 100644
--- a/src/cmd/internal/obj/loong64/obj.go
+++ b/src/cmd/internal/obj/loong64/obj.go
@@ -6,6 +6,7 @@ package loong64
import (
"cmd/internal/obj"
+ "cmd/internal/objabi"
"cmd/internal/sys"
"internal/abi"
"log"
@@ -84,6 +85,122 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.As = AADDVU
}
}
+
+ if ctxt.Flag_dynlink {
+ rewriteToUseGot(ctxt, p, newprog)
+ }
+}
+
+func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
+ // ADUFFxxx $offset
+ // becomes
+ // MOVV runtime.duffxxx@GOT, REGTMP
+ // ADD $offset, REGTMP
+ // JAL REGTMP
+ if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
+ var sym *obj.LSym
+ if p.As == obj.ADUFFZERO {
+ sym = ctxt.Lookup("runtime.duffzero")
+ } else {
+ sym = ctxt.Lookup("runtime.duffcopy")
+ }
+ offset := p.To.Offset
+ p.As = AMOVV
+ p.From.Type = obj.TYPE_MEM
+ p.From.Sym = sym
+ p.From.Name = obj.NAME_GOTREF
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = REGTMP
+ p.To.Name = obj.NAME_NONE
+ p.To.Offset = 0
+ p.To.Sym = nil
+ p1 := obj.Appendp(p, newprog)
+ p1.As = AADDV
+ p1.From.Type = obj.TYPE_CONST
+ p1.From.Offset = offset
+ p1.To.Type = obj.TYPE_REG
+ p1.To.Reg = REGTMP
+ p2 := obj.Appendp(p1, newprog)
+ p2.As = AJAL
+ p2.To.Type = obj.TYPE_MEM
+ p2.To.Reg = REGTMP
+ }
+
+ // We only care about global data: NAME_EXTERN means a global
+ // symbol in the Go sense, and p.Sym.Local is true for a few
+ // internally defined symbols.
+ if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ // MOVV $sym, Rx becomes MOVV sym@GOT, Rx
+ // MOVV $sym+<off>, Rx becomes MOVV sym@GOT, Rx; ADD <off>, Rx
+ if p.As != AMOVV {
+ ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -shared", p)
+ }
+ if p.To.Type != obj.TYPE_REG {
+ ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -shared", p)
+ }
+ p.From.Type = obj.TYPE_MEM
+ p.From.Name = obj.NAME_GOTREF
+ if p.From.Offset != 0 {
+ q := obj.Appendp(p, newprog)
+ q.As = AADDV
+ q.From.Type = obj.TYPE_CONST
+ q.From.Offset = p.From.Offset
+ q.To = p.To
+ p.From.Offset = 0
+ }
+ }
+ if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
+ ctxt.Diag("don't know how to handle %v with -shared", p)
+ }
+
+ var source *obj.Addr
+ // MOVx sym, Ry becomes MOVV sym@GOT, REGTMP; MOVx (REGTMP), Ry
+ // MOVx Ry, sym becomes MOVV sym@GOT, REGTMP; MOVx Ry, (REGTMP)
+ // An addition may be inserted between the two MOVs if there is an offset.
+ if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
+ if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
+ ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -shared", p)
+ }
+ source = &p.From
+ } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
+ source = &p.To
+ } else {
+ return
+ }
+ if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
+ return
+ }
+ if source.Sym.Type == objabi.STLSBSS {
+ return
+ }
+ if source.Type != obj.TYPE_MEM {
+ ctxt.Diag("don't know how to handle %v with -shared", p)
+ }
+ p1 := obj.Appendp(p, newprog)
+ p2 := obj.Appendp(p1, newprog)
+ p1.As = AMOVV
+ p1.From.Type = obj.TYPE_MEM
+ p1.From.Sym = source.Sym
+ p1.From.Name = obj.NAME_GOTREF
+ p1.To.Type = obj.TYPE_REG
+ p1.To.Reg = REGTMP
+
+ p2.As = p.As
+ p2.From = p.From
+ p2.To = p.To
+ if p.From.Name == obj.NAME_EXTERN {
+ p2.From.Reg = REGTMP
+ p2.From.Name = obj.NAME_NONE
+ p2.From.Sym = nil
+ } else if p.To.Name == obj.NAME_EXTERN {
+ p2.To.Reg = REGTMP
+ p2.To.Name = obj.NAME_NONE
+ p2.To.Sym = nil
+ } else {
+ return
+ }
+
+ obj.Nopout(p)
}
func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index e3e042a511..54429840b0 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -345,6 +345,11 @@ const (
R_LOONG64_TLS_IE_PCREL_HI
R_LOONG64_TLS_IE_LO
+ // R_LOONG64_GOT_HI and R_LOONG64_GOT_LO resolves a GOT-relative instruction sequence,
+ // usually an pcalau12i followed by another ld or addi instruction.
+ R_LOONG64_GOT_HI
+ R_LOONG64_GOT_LO
+
// R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction,
// by encoding the address into the instruction.
R_JMPLOONG64
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index e8793dedc1..c8923c0f4a 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -89,19 +89,21 @@ func _() {
_ = x[R_CALLLOONG64-79]
_ = x[R_LOONG64_TLS_IE_PCREL_HI-80]
_ = x[R_LOONG64_TLS_IE_LO-81]
- _ = x[R_JMPLOONG64-82]
- _ = x[R_ADDRMIPSU-83]
- _ = x[R_ADDRMIPSTLS-84]
- _ = x[R_ADDRCUOFF-85]
- _ = x[R_WASMIMPORT-86]
- _ = x[R_XCOFFREF-87]
- _ = x[R_PEIMAGEOFF-88]
- _ = x[R_INITORDER-89]
+ _ = x[R_LOONG64_GOT_HI-82]
+ _ = x[R_LOONG64_GOT_LO-83]
+ _ = x[R_JMPLOONG64-84]
+ _ = x[R_ADDRMIPSU-85]
+ _ = x[R_ADDRMIPSTLS-86]
+ _ = x[R_ADDRCUOFF-87]
+ _ = x[R_WASMIMPORT-88]
+ _ = x[R_XCOFFREF-89]
+ _ = x[R_PEIMAGEOFF-90]
+ _ = x[R_INITORDER-91]
}
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USENAMEDMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_JALR_RISCV_JAL_TRAMPR_RISCV_CALLR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IER_RISCV_TLS_LER_RISCV_GOT_HI20R_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_LOONG64_TLS_IE_PCREL_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDER"
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 993, 1007, 1023, 1040, 1053, 1078, 1097, 1109, 1120, 1133, 1144, 1156, 1166, 1178, 1189}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 226, 237, 243, 254, 264, 273, 286, 300, 314, 328, 344, 355, 368, 387, 407, 427, 447, 460, 474, 488, 502, 517, 531, 545, 556, 578, 600, 614, 629, 652, 669, 687, 708, 723, 742, 753, 770, 782, 801, 820, 834, 848, 864, 882, 902, 922, 936, 954, 970, 980, 993, 1007, 1023, 1040, 1053, 1078, 1097, 1113, 1129, 1141, 1152, 1165, 1176, 1188, 1198, 1210, 1221}
func (i RelocType) String() string {
i -= 1