Skip to content

Commit 6c54ab5

Browse files
authored
[lld][LoongArch] Relax R_LARCH_{PCALA,GOT_PC}_{HI20,LO12} (#123566)
Support relaxation optimization for two types of code sequences. ``` From: pcalau12i $a0, %pc_hi20(sym) R_LARCH_PCALA_HI20, R_LARCH_RELAX addi.w/d $a0, $a0, %pc_lo12(sym) R_LARCH_PCALA_LO12, R_LARCH_RELAX To: pcaddi $a0, %pc_lo12(sym) R_LARCH_PCREL20_S2 From: pcalau12i $a0, %got_pc_hi20(sym_got) R_LARCH_GOT_PC_HI20, R_LARCH_RELAX ld.w/d $a0, $a0, %got_pc_lo12(sym_got) R_LARCH_GOT_PC_LO12, R_LARCH_RELAX To: pcaddi $a0, %got_pc_hi20(sym_got) R_LARCH_PCREL20_S2 ``` Others: - `loongarch-relax-pc-hi20-lo12-got-symbols.s` is inspired by `aarch64-adrp-ldr-got-symbols.s`. Co-authored-by: Xin Wang [[email protected]](mailto:[email protected])
1 parent 68a82a2 commit 6c54ab5

5 files changed

+389
-64
lines changed

lld/ELF/Arch/LoongArch.cpp

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ enum Op {
5353
ADDI_W = 0x02800000,
5454
ADDI_D = 0x02c00000,
5555
ANDI = 0x03400000,
56+
PCADDI = 0x18000000,
5657
PCADDU12I = 0x1c000000,
5758
LD_W = 0x28800000,
5859
LD_D = 0x28c00000,
@@ -131,6 +132,10 @@ static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
131132
return begin == 63 ? v >> end : (v & ((1ULL << (begin + 1)) - 1)) >> end;
132133
}
133134

135+
static uint32_t getD5(uint64_t v) { return extractBits(v, 4, 0); }
136+
137+
static uint32_t getJ5(uint64_t v) { return extractBits(v, 9, 5); }
138+
134139
static uint32_t setD5k16(uint32_t insn, uint32_t imm) {
135140
uint32_t immLo = extractBits(imm, 15, 0);
136141
uint32_t immHi = extractBits(imm, 20, 16);
@@ -743,6 +748,88 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
743748
}
744749
}
745750

751+
static bool relaxable(ArrayRef<Relocation> relocs, size_t i) {
752+
return i + 1 < relocs.size() && relocs[i + 1].type == R_LARCH_RELAX;
753+
}
754+
755+
static bool isPairRelaxable(ArrayRef<Relocation> relocs, size_t i) {
756+
return relaxable(relocs, i) && relaxable(relocs, i + 2) &&
757+
relocs[i].offset + 4 == relocs[i + 2].offset;
758+
}
759+
760+
// Relax code sequence.
761+
// From:
762+
// pcalau12i $a0, %pc_hi20(sym)
763+
// addi.w/d $a0, $a0, %pc_lo12(sym)
764+
// To:
765+
// pcaddi $a0, %pc_lo12(sym)
766+
//
767+
// From:
768+
// pcalau12i $a0, %got_pc_hi20(sym_got)
769+
// ld.w/d $a0, $a0, %got_pc_lo12(sym_got)
770+
// To:
771+
// pcaddi $a0, %got_pc_hi20(sym_got)
772+
static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
773+
uint64_t loc, Relocation &rHi20, Relocation &rLo12,
774+
uint32_t &remove) {
775+
// check if the relocations are relaxable sequences.
776+
if (!((rHi20.type == R_LARCH_PCALA_HI20 &&
777+
rLo12.type == R_LARCH_PCALA_LO12) ||
778+
(rHi20.type == R_LARCH_GOT_PC_HI20 &&
779+
rLo12.type == R_LARCH_GOT_PC_LO12)))
780+
return;
781+
782+
// GOT references to absolute symbols can't be relaxed to use pcaddi in
783+
// position-independent code, because these instructions produce a relative
784+
// address.
785+
// Meanwhile skip undefined, preemptible and STT_GNU_IFUNC symbols, because
786+
// these symbols may be resolve in runtime.
787+
if (rHi20.type == R_LARCH_GOT_PC_HI20 &&
788+
(!rHi20.sym->isDefined() || rHi20.sym->isPreemptible ||
789+
rHi20.sym->isGnuIFunc() ||
790+
(ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section)))
791+
return;
792+
793+
uint64_t dest = 0;
794+
if (rHi20.expr == RE_LOONGARCH_PLT_PAGE_PC)
795+
dest = rHi20.sym->getPltVA(ctx);
796+
else if (rHi20.expr == RE_LOONGARCH_PAGE_PC ||
797+
rHi20.expr == RE_LOONGARCH_GOT_PAGE_PC)
798+
dest = rHi20.sym->getVA(ctx);
799+
else {
800+
Err(ctx) << getErrorLoc(ctx, (const uint8_t *)loc) << "unknown expr ("
801+
<< rHi20.expr << ") against symbol " << rHi20.sym
802+
<< "in relaxPCHi20Lo12";
803+
return;
804+
}
805+
dest += rHi20.addend;
806+
807+
const int64_t displace = dest - loc;
808+
// Check if the displace aligns 4 bytes or exceeds the range of pcaddi.
809+
if ((displace & 0x3) != 0 || !isInt<22>(displace))
810+
return;
811+
812+
// Note: If we can ensure that the .o files generated by LLVM only contain
813+
// relaxable instruction sequences with R_LARCH_RELAX, then we do not need to
814+
// decode instructions. The relaxable instruction sequences imply the
815+
// following constraints:
816+
// * For relocation pairs related to got_pc, the opcodes of instructions
817+
// must be pcalau12i + ld.w/d. In other cases, the opcodes must be pcalau12i +
818+
// addi.w/d.
819+
// * The destination register of pcalau12i is guaranteed to be used only by
820+
// the immediately following instruction.
821+
const uint32_t currInsn = read32le(sec.content().data() + rHi20.offset);
822+
const uint32_t nextInsn = read32le(sec.content().data() + rLo12.offset);
823+
// Check if use the same register.
824+
if (getD5(currInsn) != getJ5(nextInsn) || getJ5(nextInsn) != getD5(nextInsn))
825+
return;
826+
827+
sec.relaxAux->relocTypes[i] = R_LARCH_RELAX;
828+
sec.relaxAux->relocTypes[i + 2] = R_LARCH_PCREL20_S2;
829+
sec.relaxAux->writes.push_back(insn(PCADDI, getD5(nextInsn), 0, 0));
830+
remove = 4;
831+
}
832+
746833
static bool relax(Ctx &ctx, InputSection &sec) {
747834
const uint64_t secAddr = sec.getVA();
748835
const MutableArrayRef<Relocation> relocs = sec.relocs();
@@ -781,6 +868,12 @@ static bool relax(Ctx &ctx, InputSection &sec) {
781868
}
782869
break;
783870
}
871+
case R_LARCH_PCALA_HI20:
872+
case R_LARCH_GOT_PC_HI20:
873+
// The overflow check for i+2 will be carried out in isPairRelaxable.
874+
if (isPairRelaxable(relocs, i))
875+
relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove);
876+
break;
784877
}
785878

786879
// For all anchors whose offsets are <= r.offset, they are preceded by
@@ -851,6 +944,7 @@ void LoongArch::finalizeRelax(int passes) const {
851944
MutableArrayRef<Relocation> rels = sec->relocs();
852945
ArrayRef<uint8_t> old = sec->content();
853946
size_t newSize = old.size() - aux.relocDeltas[rels.size() - 1];
947+
size_t writesIdx = 0;
854948
uint8_t *p = ctx.bAlloc.Allocate<uint8_t>(newSize);
855949
uint64_t offset = 0;
856950
int64_t delta = 0;
@@ -867,11 +961,29 @@ void LoongArch::finalizeRelax(int passes) const {
867961
continue;
868962

869963
// Copy from last location to the current relocated location.
870-
const Relocation &r = rels[i];
964+
Relocation &r = rels[i];
871965
uint64_t size = r.offset - offset;
872966
memcpy(p, old.data() + offset, size);
873967
p += size;
874-
offset = r.offset + remove;
968+
969+
int64_t skip = 0;
970+
if (RelType newType = aux.relocTypes[i]) {
971+
switch (newType) {
972+
case R_LARCH_RELAX:
973+
break;
974+
case R_LARCH_PCREL20_S2:
975+
skip = 4;
976+
write32le(p, aux.writes[writesIdx++]);
977+
// RelExpr is needed for relocating.
978+
r.expr = r.sym->hasFlag(NEEDS_PLT) ? R_PLT_PC : R_PC;
979+
break;
980+
default:
981+
llvm_unreachable("unsupported type");
982+
}
983+
}
984+
985+
p += skip;
986+
offset = r.offset + skip + remove;
875987
}
876988
memcpy(p, old.data() + offset, old.size() - offset);
877989

lld/test/ELF/loongarch-relax-align.s

Lines changed: 78 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,93 @@
44
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o
55
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.32.o -o %t.32
66
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o -o %t.64
7-
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.32.o --no-relax -o %t.32n
8-
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.64.o --no-relax -o %t.64n
9-
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck %s
10-
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck %s
11-
# RUN: llvm-objdump -td --no-show-raw-insn %t.32n | FileCheck %s
12-
# RUN: llvm-objdump -td --no-show-raw-insn %t.64n | FileCheck %s
7+
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 --no-relax %t.32.o -o %t.32n
8+
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 --no-relax %t.64.o -o %t.64n
9+
# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX,NOOLD %s
10+
# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX,NOOLD %s
11+
# RUN: llvm-objdump -td --no-show-raw-insn %t.32n | FileCheck --check-prefixes=NORELAX,NOOLD %s
12+
# RUN: llvm-objdump -td --no-show-raw-insn %t.64n | FileCheck --check-prefixes=NORELAX,NOOLD %s
1313

1414
## Test the R_LARCH_ALIGN without symbol index.
1515
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.o64.o --defsym=old=1
1616
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o -o %t.o64
17-
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 %t.o64.o --no-relax -o %t.o64n
18-
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64 | FileCheck %s
19-
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64n | FileCheck %s
17+
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.text2=0x20000 -e 0 --no-relax %t.o64.o -o %t.o64n
18+
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64 | FileCheck --check-prefixes=RELAX,OLD %s
19+
# RUN: llvm-objdump -td --no-show-raw-insn %t.o64n | FileCheck --check-prefixes=NORELAX,OLD %s
2020

2121
## -r keeps section contents unchanged.
2222
# RUN: ld.lld -r %t.64.o -o %t.64.r
2323
# RUN: llvm-objdump -dr --no-show-raw-insn %t.64.r | FileCheck %s --check-prefix=CHECKR
2424

25-
# CHECK-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start
26-
# CHECK-DAG: {{0*}}10038 l .text {{0*}}0c .L1
27-
# CHECK-DAG: {{0*}}10040 l .text {{0*}}04 .L2
28-
# CHECK-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start
29-
30-
# CHECK: <.Ltext_start>:
31-
# CHECK-NEXT: break 1
32-
# CHECK-NEXT: break 2
33-
# CHECK-NEXT: nop
34-
# CHECK-NEXT: nop
35-
# CHECK-NEXT: break 3
36-
# CHECK-NEXT: break 4
37-
# CHECK-NEXT: nop
38-
# CHECK-NEXT: nop
39-
# CHECK-NEXT: pcalau12i $a0, 0
40-
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0
41-
# CHECK-NEXT: pcalau12i $a0, 0
42-
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 56
43-
# CHECK-NEXT: pcalau12i $a0, 0
44-
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 64
45-
# CHECK-EMPTY:
46-
# CHECK-NEXT: <.L1>:
47-
# CHECK-NEXT: nop
48-
# CHECK-NEXT: nop
49-
# CHECK-EMPTY:
50-
# CHECK-NEXT: <.L2>:
51-
# CHECK-NEXT: break 5
52-
53-
# CHECK: <.Ltext2_start>:
54-
# CHECK-NEXT: pcalau12i $a0, 0
55-
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0
56-
# CHECK-NEXT: nop
57-
# CHECK-NEXT: nop
58-
# CHECK-NEXT: break 6
25+
# NOOLD: {{0*}}10000 l .text {{0*}}00 .Lalign_symbol
26+
# OLD: {{0*}}00001 l *ABS* {{0*}}00 old
27+
28+
# NORELAX-DAG: {{0*}}10000 l .text {{0*}}44 .Ltext_start
29+
# NORELAX-DAG: {{0*}}10038 l .text {{0*}}0c .L1
30+
# NORELAX-DAG: {{0*}}10040 l .text {{0*}}04 .L2
31+
# NORELAX-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start
32+
33+
# NORELAX: <.Ltext_start>:
34+
# NORELAX-NEXT: break 1
35+
# NORELAX-NEXT: break 2
36+
# NORELAX-NEXT: nop
37+
# NORELAX-NEXT: nop
38+
# NORELAX-NEXT: break 3
39+
# NORELAX-NEXT: break 4
40+
# NORELAX-NEXT: nop
41+
# NORELAX-NEXT: nop
42+
# NORELAX-NEXT: pcalau12i $a0, 0
43+
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
44+
# NORELAX-NEXT: pcalau12i $a0, 0
45+
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 56
46+
# NORELAX-NEXT: pcalau12i $a0, 0
47+
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 64
48+
# NORELAX-EMPTY:
49+
# NORELAX-NEXT: <.L1>:
50+
# NORELAX-NEXT: nop
51+
# NORELAX-NEXT: nop
52+
# NORELAX-EMPTY:
53+
# NORELAX-NEXT: <.L2>:
54+
# NORELAX-NEXT: break 5
55+
56+
# NORELAX: <.Ltext2_start>:
57+
# NORELAX-NEXT: pcalau12i $a0, 0
58+
# NORELAX-NEXT: addi.{{[dw]}} $a0, $a0, 0
59+
# NORELAX-NEXT: nop
60+
# NORELAX-NEXT: nop
61+
# NORELAX-NEXT: break 6
62+
63+
64+
# RELAX-DAG: {{0*}}10000 l .text {{0*}}34 .Ltext_start
65+
# RELAX-DAG: {{0*}}1002c l .text {{0*}}08 .L1
66+
# RELAX-DAG: {{0*}}10030 l .text {{0*}}04 .L2
67+
# RELAX-DAG: {{0*}}20000 l .text2 {{0*}}14 .Ltext2_start
68+
69+
# RELAX: <.Ltext_start>:
70+
# RELAX-NEXT: break 1
71+
# RELAX-NEXT: break 2
72+
# RELAX-NEXT: nop
73+
# RELAX-NEXT: nop
74+
# RELAX-NEXT: break 3
75+
# RELAX-NEXT: break 4
76+
# RELAX-NEXT: nop
77+
# RELAX-NEXT: nop
78+
# RELAX-NEXT: pcaddi $a0, -8
79+
# RELAX-NEXT: pcaddi $a0, 2
80+
# RELAX-NEXT: pcaddi $a0, 2
81+
# RELAX-EMPTY:
82+
# RELAX-NEXT: <.L1>:
83+
# RELAX-NEXT: nop
84+
# RELAX-EMPTY:
85+
# RELAX-NEXT: <.L2>:
86+
# RELAX-NEXT: break 5
87+
88+
# RELAX: <.Ltext2_start>:
89+
# RELAX-NEXT: pcaddi $a0, 0
90+
# RELAX-NEXT: nop
91+
# RELAX-NEXT: nop
92+
# RELAX-NEXT: nop
93+
# RELAX-NEXT: break 6
5994

6095
# CHECKR: <.Ltext2_start>:
6196
# CHECKR-NEXT: pcalau12i $a0, 0

lld/test/ELF/loongarch-relax-emit-relocs.s

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,64 @@
33

44
# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax %s -o %t.32.o
55
# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o
6-
# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.32.o -o %t.32
7-
# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64
8-
# RUN: llvm-objdump -dr %t.32 | FileCheck %s
9-
# RUN: llvm-objdump -dr %t.64 | FileCheck %s
6+
# RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs %t.32.o -o %t.32
7+
# RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs %t.64.o -o %t.64
8+
# RUN: llvm-objdump -dr %t.32 | FileCheck %s --check-prefix=RELAX
9+
# RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX
1010

1111
## -r should keep original relocations.
1212
# RUN: ld.lld -r %t.64.o -o %t.64.r
1313
# RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR
1414

1515
## --no-relax should keep original relocations.
16-
## TODO Due to R_LARCH_RELAX is not relaxed, it plays same as --relax now.
17-
# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax
18-
# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s
16+
# RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax
17+
# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX
1918

20-
# CHECK: 00010000 <_start>:
21-
# CHECK-NEXT: pcalau12i $a0, 0
22-
# CHECK-NEXT: R_LARCH_PCALA_HI20 _start
23-
# CHECK-NEXT: R_LARCH_RELAX *ABS*
24-
# CHECK-NEXT: addi.{{[dw]}} $a0, $a0, 0
25-
# CHECK-NEXT: R_LARCH_PCALA_LO12 _start
26-
# CHECK-NEXT: R_LARCH_RELAX *ABS*
27-
# CHECK-NEXT: nop
28-
# CHECK-NEXT: R_LARCH_ALIGN *ABS*+0xc
29-
# CHECK-NEXT: nop
30-
# CHECK-NEXT: ret
19+
# RELAX: 00010000 <_start>:
20+
# RELAX-NEXT: pcaddi $a0, 0
21+
# RELAX-NEXT: R_LARCH_RELAX _start
22+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
23+
# RELAX-NEXT: R_LARCH_PCREL20_S2 _start
24+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
25+
# RELAX-NEXT: pcaddi $a0, -1
26+
# RELAX-NEXT: R_LARCH_RELAX _start
27+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
28+
# RELAX-NEXT: R_LARCH_PCREL20_S2 _start
29+
# RELAX-NEXT: R_LARCH_RELAX *ABS*
30+
# RELAX-NEXT: nop
31+
# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc
32+
# RELAX-NEXT: nop
33+
# RELAX-NEXT: ret
34+
35+
# NORELAX: <_start>:
36+
# NORELAX-NEXT: pcalau12i $a0, 0
37+
# NORELAX-NEXT: R_LARCH_PCALA_HI20 _start
38+
# NORELAX-NEXT: R_LARCH_RELAX *ABS*
39+
# NORELAX-NEXT: addi.d $a0, $a0, 0
40+
# NORELAX-NEXT: R_LARCH_PCALA_LO12 _start
41+
# NORELAX-NEXT: R_LARCH_RELAX *ABS*
42+
# NORELAX-NEXT: pcalau12i $a0, 16
43+
# NORELAX-NEXT: R_LARCH_GOT_PC_HI20 _start
44+
# NORELAX-NEXT: R_LARCH_RELAX *ABS*
45+
# NORELAX-NEXT: ld.d $a0, $a0, 0
46+
# NORELAX-NEXT: R_LARCH_GOT_PC_LO12 _start
47+
# NORELAX-NEXT: R_LARCH_RELAX *ABS*
48+
# NORELAX-NEXT: ret
49+
# NORELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc
3150

3251
# CHECKR: <_start>:
3352
# CHECKR-NEXT: pcalau12i $a0, 0
3453
# CHECKR-NEXT: R_LARCH_PCALA_HI20 _start
3554
# CHECKR-NEXT: R_LARCH_RELAX *ABS*
36-
# CHECKR-NEXT: addi.d $a0, $a0, 0
55+
# CHECKR-NEXT: addi.d $a0, $a0, 0
3756
# CHECKR-NEXT: R_LARCH_PCALA_LO12 _start
3857
# CHECKR-NEXT: R_LARCH_RELAX *ABS*
58+
# CHECKR-NEXT: pcalau12i $a0, 0
59+
# CHECKR-NEXT: R_LARCH_GOT_PC_HI20 _start
60+
# CHECKR-NEXT: R_LARCH_RELAX *ABS*
61+
# CHECKR-NEXT: ld.d $a0, $a0, 0
62+
# CHECKR-NEXT: R_LARCH_GOT_PC_LO12 _start
63+
# CHECKR-NEXT: R_LARCH_RELAX *ABS*
3964
# CHECKR-NEXT: nop
4065
# CHECKR-NEXT: R_LARCH_ALIGN *ABS*+0xc
4166
# CHECKR-NEXT: nop
@@ -45,5 +70,6 @@
4570
.global _start
4671
_start:
4772
la.pcrel $a0, _start
73+
la.got $a0, _start
4874
.p2align 4
4975
ret

0 commit comments

Comments
 (0)