aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/internal/obj/fips140.go4
-rw-r--r--src/cmd/internal/objabi/reloctype.go26
-rw-r--r--src/cmd/internal/objabi/reloctype_string.go64
-rw-r--r--src/cmd/internal/objabi/symkind_string.go5
-rw-r--r--src/cmd/link/internal/loadelf/ldelf.go4
-rw-r--r--src/cmd/link/internal/loong64/asm.go197
6 files changed, 224 insertions, 76 deletions
diff --git a/src/cmd/internal/obj/fips140.go b/src/cmd/internal/obj/fips140.go
index b888396b1f..0e4f2a47a3 100644
--- a/src/cmd/internal/obj/fips140.go
+++ b/src/cmd/internal/obj/fips140.go
@@ -356,6 +356,8 @@ func (s *LSym) checkFIPSReloc(ctxt *Link, rel Reloc) {
objabi.R_GOTPCREL,
objabi.R_LOONG64_ADDR_LO, // used with PC-relative load
objabi.R_LOONG64_ADDR_HI, // used with PC-relative load
+ objabi.R_LOONG64_ADDR64_LO, // used with PC-relative load
+ objabi.R_LOONG64_ADDR64_HI, // used with PC-relative load
objabi.R_LOONG64_ADDR_PCREL20_S2, // used with PC-relative load
objabi.R_LOONG64_CALL36,
objabi.R_LOONG64_TLS_LE_HI,
@@ -364,6 +366,8 @@ func (s *LSym) checkFIPSReloc(ctxt *Link, rel Reloc) {
objabi.R_LOONG64_TLS_IE_LO,
objabi.R_LOONG64_GOT_HI,
objabi.R_LOONG64_GOT_LO,
+ objabi.R_LOONG64_GOT64_HI,
+ objabi.R_LOONG64_GOT64_LO,
objabi.R_JMP16LOONG64,
objabi.R_JMP21LOONG64,
objabi.R_PCREL,
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index 8e95b5dae2..b6764ff8ef 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -327,13 +327,20 @@ const (
// Loong64.
- // R_LOONG64_ADDR_HI resolves to the sign-adjusted "upper" 20 bits (bit 5-24) of an
- // external address, by encoding it into the instruction.
+ // R_LOONG64_ADDR_HI resolves [31...12]bits of 32/64-bit PC-relative offset of an
+ // external address, by encoding it into addi.w/addi.d instruction
// R_LOONG64_ADDR_LO resolves to the low 12 bits of an external address, by encoding
- // it into the instruction.
+ // it into pcalau12i instruction.
R_LOONG64_ADDR_HI
R_LOONG64_ADDR_LO
+ // R_LOONG64_ADDR64_HI resolves [63...52]bits of 64-bit PC-relative offset of an
+ // external address, by encoding it into lu52i.d instruction
+ // R_LOONG64_ADDR64_LO resolves [51...32]bits of 64-bit PC-relative offset of an
+ // external address, by encoding it into lu32i.d instruction
+ R_LOONG64_ADDR64_HI
+ R_LOONG64_ADDR64_LO
+
// R_LOONG64_ADDR_PCREL20_S2 resolves to the 22-bit, 4-byte aligned offset of an
// external address, by encoding it into a PCADDI instruction.
R_LOONG64_ADDR_PCREL20_S2
@@ -358,11 +365,20 @@ const (
R_LOONG64_TLS_IE_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 resolves [31...12]bits of 32/64-bit PC-relative offset of
+ // GOT entry, by encoding it into pcalau12i instruction
+ // R_LOONG64_GOT_LO resolves [11...0]bits of 32/64-bit PC-relative offset of
+ // GOT entry, by encoding it into ld.w/ld.d instruction
R_LOONG64_GOT_HI
R_LOONG64_GOT_LO
+ // R_LOONG64_GOT64_HI resolves [63...52]bits of 64-bit PC-relative offset of
+ // GOT entry, by encoding it into lu52i.d instruction
+ // R_LOONG64_GOT64_LO resolves [51...32]bits of 64-bit PC-relative offset of
+ // GOT entry, by encoding it into lu32i.d instruction
+ R_LOONG64_GOT64_HI
+ R_LOONG64_GOT64_LO
+
// 64-bit in-place addition.
R_LOONG64_ADD64
// 64-bit in-place subtraction.
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index 4152afd92f..c7a5e6c07a 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -86,40 +86,44 @@ func _() {
_ = x[R_PCRELDBL-76]
_ = x[R_LOONG64_ADDR_HI-77]
_ = x[R_LOONG64_ADDR_LO-78]
- _ = x[R_LOONG64_ADDR_PCREL20_S2-79]
- _ = x[R_LOONG64_TLS_LE_HI-80]
- _ = x[R_LOONG64_TLS_LE_LO-81]
- _ = x[R_CALLLOONG64-82]
- _ = x[R_LOONG64_CALL36-83]
- _ = x[R_LOONG64_TLS_IE_HI-84]
- _ = x[R_LOONG64_TLS_IE_LO-85]
- _ = x[R_LOONG64_GOT_HI-86]
- _ = x[R_LOONG64_GOT_LO-87]
- _ = x[R_LOONG64_ADD64-88]
- _ = x[R_LOONG64_SUB64-89]
- _ = x[R_JMP16LOONG64-90]
- _ = x[R_JMP21LOONG64-91]
- _ = x[R_ADDRMIPSU-92]
- _ = x[R_ADDRMIPSTLS-93]
- _ = x[R_ADDRCUOFF-94]
- _ = x[R_WASMIMPORT-95]
- _ = x[R_XCOFFREF-96]
- _ = x[R_PEIMAGEOFF-97]
- _ = x[R_INITORDER-98]
- _ = x[R_DWTXTADDR_U1-99]
- _ = x[R_DWTXTADDR_U2-100]
- _ = x[R_DWTXTADDR_U3-101]
- _ = x[R_DWTXTADDR_U4-102]
+ _ = x[R_LOONG64_ADDR64_HI-79]
+ _ = x[R_LOONG64_ADDR64_LO-80]
+ _ = x[R_LOONG64_ADDR_PCREL20_S2-81]
+ _ = x[R_LOONG64_TLS_LE_HI-82]
+ _ = x[R_LOONG64_TLS_LE_LO-83]
+ _ = x[R_CALLLOONG64-84]
+ _ = x[R_LOONG64_CALL36-85]
+ _ = x[R_LOONG64_TLS_IE_HI-86]
+ _ = x[R_LOONG64_TLS_IE_LO-87]
+ _ = x[R_LOONG64_GOT_HI-88]
+ _ = x[R_LOONG64_GOT_LO-89]
+ _ = x[R_LOONG64_GOT64_HI-90]
+ _ = x[R_LOONG64_GOT64_LO-91]
+ _ = x[R_LOONG64_ADD64-92]
+ _ = x[R_LOONG64_SUB64-93]
+ _ = x[R_JMP16LOONG64-94]
+ _ = x[R_JMP21LOONG64-95]
+ _ = x[R_ADDRMIPSU-96]
+ _ = x[R_ADDRMIPSTLS-97]
+ _ = x[R_ADDRCUOFF-98]
+ _ = x[R_WASMIMPORT-99]
+ _ = x[R_XCOFFREF-100]
+ _ = x[R_PEIMAGEOFF-101]
+ _ = x[R_INITORDER-102]
+ _ = x[R_DWTXTADDR_U1-103]
+ _ = x[R_DWTXTADDR_U2-104]
+ _ = x[R_DWTXTADDR_U3-105]
+ _ = x[R_DWTXTADDR_U4-106]
}
-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_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_GOT_PCREL_ITYPER_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_ADD32R_RISCV_SUB32R_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_LOONG64_ADDR_HIR_LOONG64_ADDR_LOR_LOONG64_ADDR_PCREL20_S2R_LOONG64_TLS_LE_HIR_LOONG64_TLS_LE_LOR_CALLLOONG64R_LOONG64_CALL36R_LOONG64_TLS_IE_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_LOONG64_ADD64R_LOONG64_SUB64R_JMP16LOONG64R_JMP21LOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDERR_DWTXTADDR_U1R_DWTXTADDR_U2R_DWTXTADDR_U3R_DWTXTADDR_U4"
+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_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_GOT_PCREL_ITYPER_RISCV_PCREL_HI20R_RISCV_PCREL_LO12_IR_RISCV_PCREL_LO12_SR_RISCV_BRANCHR_RISCV_ADD32R_RISCV_SUB32R_RISCV_RVC_BRANCHR_RISCV_RVC_JUMPR_PCRELDBLR_LOONG64_ADDR_HIR_LOONG64_ADDR_LOR_LOONG64_ADDR64_HIR_LOONG64_ADDR64_LOR_LOONG64_ADDR_PCREL20_S2R_LOONG64_TLS_LE_HIR_LOONG64_TLS_LE_LOR_CALLLOONG64R_LOONG64_CALL36R_LOONG64_TLS_IE_HIR_LOONG64_TLS_IE_LOR_LOONG64_GOT_HIR_LOONG64_GOT_LOR_LOONG64_GOT64_HIR_LOONG64_GOT64_LOR_LOONG64_ADD64R_LOONG64_SUB64R_JMP16LOONG64R_JMP21LOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFFR_INITORDERR_DWTXTADDR_U1R_DWTXTADDR_U2R_DWTXTADDR_U3R_DWTXTADDR_U4"
-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, 330, 341, 354, 373, 393, 413, 433, 446, 460, 474, 488, 503, 517, 531, 542, 564, 586, 600, 615, 638, 655, 673, 694, 709, 728, 739, 756, 768, 787, 806, 820, 834, 850, 873, 891, 911, 931, 945, 958, 971, 989, 1005, 1015, 1032, 1049, 1074, 1093, 1112, 1125, 1141, 1160, 1179, 1195, 1211, 1226, 1241, 1255, 1269, 1280, 1293, 1304, 1316, 1326, 1338, 1349, 1363, 1377, 1391, 1405}
+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, 330, 341, 354, 373, 393, 413, 433, 446, 460, 474, 488, 503, 517, 531, 542, 564, 586, 600, 615, 638, 655, 673, 694, 709, 728, 739, 756, 768, 787, 806, 820, 834, 850, 873, 891, 911, 931, 945, 958, 971, 989, 1005, 1015, 1032, 1049, 1068, 1087, 1112, 1131, 1150, 1163, 1179, 1198, 1217, 1233, 1249, 1267, 1285, 1300, 1315, 1329, 1343, 1354, 1367, 1378, 1390, 1400, 1412, 1423, 1437, 1451, 1465, 1479}
func (i RelocType) String() string {
- i -= 1
- if i < 0 || i >= RelocType(len(_RelocType_index)-1) {
- return "RelocType(" + strconv.FormatInt(int64(i+1), 10) + ")"
+ idx := int(i) - 1
+ if i < 1 || idx >= len(_RelocType_index)-1 {
+ return "RelocType(" + strconv.FormatInt(int64(i), 10) + ")"
}
- return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]]
+ return _RelocType_name[_RelocType_index[idx]:_RelocType_index[idx+1]]
}
diff --git a/src/cmd/internal/objabi/symkind_string.go b/src/cmd/internal/objabi/symkind_string.go
index fbf6a826a4..a22f9a6a1c 100644
--- a/src/cmd/internal/objabi/symkind_string.go
+++ b/src/cmd/internal/objabi/symkind_string.go
@@ -41,8 +41,9 @@ const _SymKind_name = "SxxxSTEXTSTEXTFIPSSRODATASRODATAFIPSSNOPTRDATASNOPTRDATAF
var _SymKind_index = [...]uint16{0, 4, 9, 18, 25, 36, 46, 60, 65, 74, 78, 87, 94, 106, 117, 126, 138, 148, 157, 168, 177, 188, 198, 221, 238, 254, 268}
func (i SymKind) String() string {
- if i >= SymKind(len(_SymKind_index)-1) {
+ idx := int(i) - 0
+ if i < 0 || idx >= len(_SymKind_index)-1 {
return "SymKind(" + strconv.FormatInt(int64(i), 10) + ")"
}
- return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]]
+ return _SymKind_name[_SymKind_index[idx]:_SymKind_index[idx+1]]
}
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index c5c4645656..50bce8613b 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -1071,8 +1071,12 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
LOONG64 | uint32(elf.R_LARCH_B26)<<16,
LOONG64 | uint32(elf.R_LARCH_PCALA_HI20)<<16,
LOONG64 | uint32(elf.R_LARCH_PCALA_LO12)<<16,
+ LOONG64 | uint32(elf.R_LARCH_PCALA64_HI12)<<16,
+ LOONG64 | uint32(elf.R_LARCH_PCALA64_LO20)<<16,
LOONG64 | uint32(elf.R_LARCH_GOT_PC_HI20)<<16,
LOONG64 | uint32(elf.R_LARCH_GOT_PC_LO12)<<16,
+ LOONG64 | uint32(elf.R_LARCH_GOT64_PC_LO20)<<16,
+ LOONG64 | uint32(elf.R_LARCH_GOT64_PC_HI12)<<16,
LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16,
LOONG64 | uint32(elf.R_LARCH_PCREL20_S2)<<16:
return 4, 4, nil
diff --git a/src/cmd/link/internal/loong64/asm.go b/src/cmd/link/internal/loong64/asm.go
index 9881e37493..0ebdc61936 100644
--- a/src/cmd/link/internal/loong64/asm.go
+++ b/src/cmd/link/internal/loong64/asm.go
@@ -105,24 +105,37 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_HI20),
- objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_LO12):
+ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_LO12),
+ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT64_PC_HI12),
+ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT64_PC_LO20):
if targType != sym.SDYNIMPORT {
// TODO: turn LDR of GOT entry into ADR of symbol itself
}
ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64))
su := ldr.MakeSymbolUpdater(s)
- if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_GOT_PC_HI20) {
- su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI)
- } else {
- su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO)
+
+ var relocType objabi.RelocType
+ switch r.Type() - objabi.ElfRelocOffset {
+ case objabi.RelocType(elf.R_LARCH_GOT_PC_HI20):
+ relocType = objabi.R_LOONG64_ADDR_HI
+ case objabi.RelocType(elf.R_LARCH_GOT_PC_LO12):
+ relocType = objabi.R_LOONG64_ADDR_LO
+ case objabi.RelocType(elf.R_LARCH_GOT64_PC_HI12):
+ relocType = objabi.R_LOONG64_ADDR64_HI
+ case objabi.RelocType(elf.R_LARCH_GOT64_PC_LO20):
+ relocType = objabi.R_LOONG64_ADDR64_LO
}
+
+ su.SetRelocType(rIdx, relocType)
su.SetRelocSym(rIdx, syms.GOT)
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_HI20),
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_LO12),
+ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA64_HI12),
+ objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA64_LO20),
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCREL20_S2):
if targType == sym.SDYNIMPORT {
ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
@@ -137,9 +150,14 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
relocType = objabi.R_LOONG64_ADDR_HI
case objabi.RelocType(elf.R_LARCH_PCALA_LO12):
relocType = objabi.R_LOONG64_ADDR_LO
+ case objabi.RelocType(elf.R_LARCH_PCALA64_HI12):
+ relocType = objabi.R_LOONG64_ADDR64_HI
+ case objabi.RelocType(elf.R_LARCH_PCALA64_LO20):
+ relocType = objabi.R_LOONG64_ADDR64_LO
case objabi.RelocType(elf.R_LARCH_PCREL20_S2):
relocType = objabi.R_LOONG64_ADDR_PCREL20_S2
}
+
su := ldr.MakeSymbolUpdater(s)
su.SetRelocType(rIdx, relocType)
return true
@@ -289,14 +307,25 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
}
case objabi.R_LOONG64_GOT_HI,
- objabi.R_LOONG64_GOT_LO:
+ objabi.R_LOONG64_GOT_LO,
+ objabi.R_LOONG64_GOT64_HI,
+ objabi.R_LOONG64_GOT64_LO:
ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64))
su := ldr.MakeSymbolUpdater(s)
- if r.Type() == objabi.R_LOONG64_GOT_HI {
- su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI)
- } else {
- su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO)
+
+ var relocType objabi.RelocType
+ switch r.Type() {
+ case objabi.R_LOONG64_GOT_HI:
+ relocType = objabi.R_LOONG64_ADDR_HI
+ case objabi.R_LOONG64_GOT_LO:
+ relocType = objabi.R_LOONG64_ADDR_LO
+ case objabi.R_LOONG64_GOT64_HI:
+ relocType = objabi.R_LOONG64_ADDR64_HI
+ case objabi.R_LOONG64_GOT64_LO:
+ relocType = objabi.R_LOONG64_ADDR64_LO
}
+
+ su.SetRelocType(rIdx, relocType)
su.SetRelocSym(rIdx, syms.GOT)
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
return true
@@ -454,6 +483,16 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
out.Write64(uint64(elf.R_LARCH_PCALA_HI20) | uint64(elfsym)<<32)
out.Write64(uint64(r.Xadd))
+ case objabi.R_LOONG64_ADDR64_LO:
+ out.Write64(uint64(sectoff))
+ out.Write64(uint64(elf.R_LARCH_PCALA64_LO20) | uint64(elfsym)<<32)
+ out.Write64(uint64(r.Xadd))
+
+ case objabi.R_LOONG64_ADDR64_HI:
+ out.Write64(uint64(sectoff))
+ out.Write64(uint64(elf.R_LARCH_PCALA64_HI12) | uint64(elfsym)<<32)
+ out.Write64(uint64(r.Xadd))
+
case objabi.R_LOONG64_ADDR_PCREL20_S2:
out.Write64(uint64(sectoff))
out.Write64(uint64(elf.R_LARCH_PCREL20_S2) | uint64(elfsym)<<32)
@@ -468,6 +507,16 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
out.Write64(uint64(sectoff))
out.Write64(uint64(elf.R_LARCH_GOT_PC_LO12) | uint64(elfsym)<<32)
out.Write64(uint64(0x0))
+
+ case objabi.R_LOONG64_GOT64_HI:
+ out.Write64(uint64(sectoff))
+ out.Write64(uint64(elf.R_LARCH_GOT64_PC_HI12) | uint64(elfsym)<<32)
+ out.Write64(uint64(0x0))
+
+ case objabi.R_LOONG64_GOT64_LO:
+ out.Write64(uint64(sectoff))
+ out.Write64(uint64(elf.R_LARCH_GOT64_PC_LO20) | uint64(elfsym)<<32)
+ out.Write64(uint64(0x0))
}
return true
@@ -485,6 +534,8 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
return val, 0, false
case objabi.R_LOONG64_ADDR_HI,
objabi.R_LOONG64_ADDR_LO,
+ objabi.R_LOONG64_ADDR64_HI,
+ objabi.R_LOONG64_ADDR64_LO,
objabi.R_LOONG64_ADDR_PCREL20_S2:
// set up addend for eventual relocation via outer symbol.
rs, _ := ld.FoldSubSymbolOffset(ldr, rs)
@@ -493,6 +544,7 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
}
return val, 1, true
+
case objabi.R_LOONG64_TLS_LE_HI,
objabi.R_LOONG64_TLS_LE_LO,
objabi.R_CALLLOONG64,
@@ -500,7 +552,9 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
objabi.R_LOONG64_TLS_IE_HI,
objabi.R_LOONG64_TLS_IE_LO,
objabi.R_LOONG64_GOT_HI,
- objabi.R_LOONG64_GOT_LO:
+ objabi.R_LOONG64_GOT_LO,
+ objabi.R_LOONG64_GOT64_HI,
+ objabi.R_LOONG64_GOT64_LO:
return val, 1, true
}
}
@@ -511,20 +565,43 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
switch r.Type() {
case objabi.R_CONST:
return r.Add(), noExtReloc, isOk
+
case objabi.R_GOTOFF:
return ldr.SymValue(r.Sym()) + r.Add() - ldr.SymValue(syms.GOT), noExtReloc, isOk
+
case objabi.R_LOONG64_ADDR_HI,
- objabi.R_LOONG64_ADDR_LO:
+ objabi.R_LOONG64_ADDR_LO,
+ objabi.R_LOONG64_ADDR64_HI,
+ objabi.R_LOONG64_ADDR64_LO:
pc := ldr.SymValue(s) + int64(r.Off())
- t := calculatePCAlignedReloc(r.Type(), ldr.SymAddr(rs)+r.Add(), pc)
- if r.Type() == objabi.R_LOONG64_ADDR_LO {
- return val&0xffc003ff | (t << 10), noExtReloc, isOk
+ var t int64
+
+ switch r.Type() {
+ case objabi.R_LOONG64_ADDR_LO:
+ // pcalau12i
+ t = pc32RelocBits(r.Type(), ldr.SymAddr(rs)+r.Add(), pc)
+ o = val&0xffc003ff | (t << 10)
+ case objabi.R_LOONG64_ADDR_HI:
+ // addi.w/addi.d
+ t = pc32RelocBits(r.Type(), ldr.SymAddr(rs)+r.Add(), pc)
+ o = val&0xfe00001f | (t << 5)
+ case objabi.R_LOONG64_ADDR64_LO:
+ // lu32i.d
+ t = pc64RelocBits(r.Type(), ldr.SymAddr(rs)+r.Add(), pc-8)
+ o = val&0xfe00001f | (t << 5)
+ case objabi.R_LOONG64_ADDR64_HI:
+ // lu52i.d
+ t = pc64RelocBits(r.Type(), ldr.SymAddr(rs)+r.Add(), pc-12)
+ o = val&0xffc003ff | (t << 10)
}
- return val&0xfe00001f | (t << 5), noExtReloc, isOk
+
+ return o, noExtReloc, isOk
+
case objabi.R_LOONG64_ADDR_PCREL20_S2:
pc := ldr.SymValue(s) + int64(r.Off())
t := (ldr.SymAddr(rs) + r.Add() - pc) >> 2
return val&0xfe00001f | ((t & 0xfffff) << 5), noExtReloc, isOk
+
case objabi.R_LOONG64_TLS_LE_HI,
objabi.R_LOONG64_TLS_LE_LO:
t := ldr.SymAddr(rs) + r.Add()
@@ -532,6 +609,7 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
return val&0xffc003ff | ((t & 0xfff) << 10), noExtReloc, isOk
}
return val&0xfe00001f | (((t) >> 12 << 5) & 0x1ffffe0), noExtReloc, isOk
+
case objabi.R_CALLLOONG64:
pc := ldr.SymValue(s) + int64(r.Off())
t := ldr.SymAddr(rs) + r.Add() - pc
@@ -589,8 +667,12 @@ func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sy
switch r.Type() {
case objabi.R_LOONG64_ADDR_HI,
objabi.R_LOONG64_ADDR_LO,
+ objabi.R_LOONG64_ADDR64_HI,
+ objabi.R_LOONG64_ADDR64_LO,
objabi.R_LOONG64_GOT_HI,
- objabi.R_LOONG64_GOT_LO:
+ objabi.R_LOONG64_GOT_LO,
+ objabi.R_LOONG64_GOT64_HI,
+ objabi.R_LOONG64_GOT64_LO:
return ld.ExtrelocViaOuterSym(ldr, r, s), true
case objabi.R_LOONG64_TLS_LE_HI,
@@ -605,34 +687,71 @@ func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sy
return loader.ExtReloc{}, false
}
-func isRequestingLowPageBits(t objabi.RelocType) bool {
- switch t {
- case objabi.R_LOONG64_ADDR_LO:
- return true
+// Comments from copying binutils/bfd/elfnn-loongarch.c
+//
+// For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
+//
+// offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
+// offset = 0x712347ffff000
+//
+// lo12: 0x1812348ffff812 & 0xfff = 0x812
+// hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
+// lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
+// hi12: 0x0
+//
+// pcalau12i $t1, hi20 (0x80000)
+//
+// $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
+// = 0x11000010000100 + 0xffffffff80000000
+// = 0x10ffff90000000
+//
+// addi.d $t0, $zero, lo12 (0x812)
+//
+// $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
+// lo20 need to sub 0x1)
+//
+// lu32i.d $t0, lo20 (0x71234)
+//
+// $t0 = {0x71234, 0xfffff812}
+// = 0x71234fffff812
+//
+// lu52i.d $t0, hi12 (0x0)
+//
+// $t0 = {0x0, 0x71234fffff812}
+// = 0x71234fffff812
+func pc32RelocBits(reloc objabi.RelocType, tgt int64, pc int64) int64 {
+ lo12 := tgt & 0xfff
+ if reloc == objabi.R_LOONG64_ADDR_LO {
+ return lo12
}
- return false
+
+ off := (tgt & ^0xfff) - (pc & ^0xfff)
+ if lo12 >= 0x800 {
+ off += 0x1000
+ }
+
+ // objabi.R_LOONG64_ADDR_HI
+ return (off >> 12) & 0xfffff
}
-// Calculates the value to put into the immediate slot, according to the
-// desired relocation type, target and PC.
-// The value to use varies based on the reloc type. Namely, the absolute low
-// bits of the target are to be used for the low part, while the page-aligned
-// offset is to be used for the higher part. A "page" here is not related to
-// the system's actual page size, but rather a fixed 12-bit range (designed to
-// cooperate with ADDI/LD/ST's 12-bit immediates).
-func calculatePCAlignedReloc(t objabi.RelocType, tgt int64, pc int64) int64 {
- if isRequestingLowPageBits(t) {
- // corresponding immediate field is 12 bits wide
- return tgt & 0xfff
+func pc64RelocBits(reloc objabi.RelocType, tgt int64, pc int64) int64 {
+ lo12 := tgt & 0xfff
+ off := (tgt & ^0xfff) - (pc & ^0xfff)
+
+ if lo12 >= 0x800 {
+ off += (0x1000 - 0x100000000)
}
- pageDelta := (tgt >> 12) - (pc >> 12)
- if tgt&0xfff >= 0x800 {
- // adjust for sign-extended addition of the low bits
- pageDelta += 1
+ if (off & 0x80000000) != 0 {
+ off += 0x100000000
}
- // corresponding immediate field is 20 bits wide
- return pageDelta & 0xfffff
+
+ if reloc == objabi.R_LOONG64_ADDR64_LO {
+ return (off >> 32) & 0xfffff
+ }
+
+ // objabi.R_LOONG64_ADDR64_HI
+ return (off >> 52) & 0xfff
}
// Convert the direct jump relocation r to refer to a trampoline if the target is too far.