Skip to content

Commit f6253f8

Browse files
authored
[JITLink][LoongArch] Add label addition and subtraction relocations (#122262)
1 parent b84b717 commit f6253f8

File tree

4 files changed

+269
-0
lines changed

4 files changed

+269
-0
lines changed

llvm/include/llvm/ExecutionEngine/JITLink/loongarch.h

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
#define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
1515

1616
#include "TableManager.h"
17+
#include "llvm/ADT/StringExtras.h"
1718
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
1819
#include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
20+
#include "llvm/Support/LEB128.h"
1921

2022
namespace llvm {
2123
namespace jitlink {
@@ -226,6 +228,90 @@ enum EdgeKind_loongarch : Edge::Kind {
226228
///
227229
Call36PCRel,
228230

231+
/// low 6 bits label addition
232+
///
233+
/// Fixup expression:
234+
/// Fixup <- (*{1}Fixup + (Target + Addend) & 0x3f) : int8
235+
///
236+
Add6,
237+
238+
/// 8 bits label addition
239+
///
240+
/// Fixup expression:
241+
/// Fixup <- (*{1}Fixup + Target + Addend) : int8
242+
///
243+
Add8,
244+
245+
/// 16 bits label addition
246+
///
247+
/// Fixup expression:
248+
/// Fixup <- (*{2}Fixup + Target + Addend) : int16
249+
///
250+
Add16,
251+
252+
/// 32 bits label addition
253+
///
254+
/// Fixup expression:
255+
/// Fixup <- (*{4}Fixup + Target + Addend) : int32
256+
///
257+
Add32,
258+
259+
/// 64 bits label addition
260+
///
261+
/// Fixup expression:
262+
/// Fixup <- (*{8}Fixup + Target + Addend) : int64
263+
///
264+
Add64,
265+
266+
/// ULEB128 bits label addition
267+
///
268+
/// Fixup expression:
269+
/// Fixup <- (Fixup + Target + Addend) : uleb128
270+
///
271+
AddUleb128,
272+
273+
/// low 6 bits label subtraction
274+
///
275+
/// Fixup expression:
276+
/// Fixup <- (*{1}Fixup - (Target + Addend) & 0x3f) : int8
277+
///
278+
Sub6,
279+
280+
/// 8 bits label subtraction
281+
///
282+
/// Fixup expression:
283+
/// Fixup <- (*{1}Fixup - Target - Addend) : int8
284+
///
285+
Sub8,
286+
287+
/// 16 bits label subtraction
288+
///
289+
/// Fixup expression:
290+
/// Fixup <- (*{2}Fixup - Target - Addend) : int16
291+
///
292+
Sub16,
293+
294+
/// 32 bits label subtraction
295+
///
296+
/// Fixup expression:
297+
/// Fixup <- (*{4}Fixup - Target - Addend) : int32
298+
///
299+
Sub32,
300+
301+
/// 64 bits label subtraction
302+
///
303+
/// Fixup expression:
304+
/// Fixup <- (*{8}Fixup - Target - Addend) : int64
305+
///
306+
Sub64,
307+
308+
/// ULEB128 bits label subtraction
309+
///
310+
/// Fixup expression:
311+
/// Fixup <- (Fixup - Target - Addend) : uleb128
312+
///
313+
SubUleb128,
314+
229315
/// Alignment requirement used by linker relaxation.
230316
///
231317
/// Linker relaxation will use this to ensure all code sequences are properly
@@ -369,6 +455,100 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
369455
*(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
370456
break;
371457
}
458+
case Add6: {
459+
int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
460+
Value += ((TargetAddress + Addend) & 0x3f);
461+
*FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
462+
break;
463+
}
464+
case Add8: {
465+
int64_t Value =
466+
TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend;
467+
*FixupPtr = static_cast<int8_t>(Value);
468+
break;
469+
}
470+
case Add16: {
471+
int64_t Value =
472+
TargetAddress + support::endian::read16le(FixupPtr) + Addend;
473+
*(little16_t *)FixupPtr = static_cast<int16_t>(Value);
474+
break;
475+
}
476+
case Add32: {
477+
int64_t Value =
478+
TargetAddress + support::endian::read32le(FixupPtr) + Addend;
479+
*(little32_t *)FixupPtr = static_cast<int32_t>(Value);
480+
break;
481+
}
482+
case Add64: {
483+
int64_t Value =
484+
TargetAddress + support::endian::read64le(FixupPtr) + Addend;
485+
*(little64_t *)FixupPtr = static_cast<int64_t>(Value);
486+
break;
487+
}
488+
case AddUleb128: {
489+
const uint32_t Maxcount = 1 + 64 / 7;
490+
uint32_t Count;
491+
const char *Error = nullptr;
492+
uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
493+
&Count, nullptr, &Error);
494+
495+
if (Count > Maxcount || (Count == Maxcount && Error))
496+
return make_error<JITLinkError>(
497+
"0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
498+
": extra space for uleb128");
499+
500+
uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
501+
encodeULEB128((Orig + TargetAddress + Addend) & Mask,
502+
(reinterpret_cast<uint8_t *>(FixupPtr)), Count);
503+
break;
504+
}
505+
case Sub6: {
506+
int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
507+
Value -= ((TargetAddress + Addend) & 0x3f);
508+
*FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
509+
break;
510+
}
511+
case Sub8: {
512+
int64_t Value =
513+
*(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend;
514+
*FixupPtr = static_cast<int8_t>(Value);
515+
break;
516+
}
517+
case Sub16: {
518+
int64_t Value =
519+
support::endian::read16le(FixupPtr) - TargetAddress - Addend;
520+
*(little16_t *)FixupPtr = static_cast<int16_t>(Value);
521+
break;
522+
}
523+
case Sub32: {
524+
int64_t Value =
525+
support::endian::read32le(FixupPtr) - TargetAddress - Addend;
526+
*(little32_t *)FixupPtr = static_cast<int32_t>(Value);
527+
break;
528+
}
529+
case Sub64: {
530+
int64_t Value =
531+
support::endian::read64le(FixupPtr) - TargetAddress - Addend;
532+
*(little64_t *)FixupPtr = static_cast<int64_t>(Value);
533+
break;
534+
}
535+
case SubUleb128: {
536+
const uint32_t Maxcount = 1 + 64 / 7;
537+
uint32_t Count;
538+
const char *Error = nullptr;
539+
uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)),
540+
&Count, nullptr, &Error);
541+
542+
if (Count > Maxcount || (Count == Maxcount && Error))
543+
return make_error<JITLinkError>(
544+
"0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) +
545+
": extra space for uleb128");
546+
547+
uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL;
548+
encodeULEB128((Orig - TargetAddress - Addend) & Mask,
549+
(reinterpret_cast<uint8_t *>(FixupPtr)), Count);
550+
break;
551+
}
372552
case AlignRelaxable:
373553
// Ignore when the relaxation pass did not run
374554
break;

llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,30 @@ class ELFLinkGraphBuilder_loongarch : public ELFLinkGraphBuilder<ELFT> {
306306
return RequestGOTAndTransformToPageOffset12;
307307
case ELF::R_LARCH_CALL36:
308308
return Call36PCRel;
309+
case ELF::R_LARCH_ADD6:
310+
return Add6;
311+
case ELF::R_LARCH_ADD8:
312+
return Add8;
313+
case ELF::R_LARCH_ADD16:
314+
return Add16;
315+
case ELF::R_LARCH_ADD32:
316+
return Add32;
317+
case ELF::R_LARCH_ADD64:
318+
return Add64;
319+
case ELF::R_LARCH_ADD_ULEB128:
320+
return AddUleb128;
321+
case ELF::R_LARCH_SUB6:
322+
return Sub6;
323+
case ELF::R_LARCH_SUB8:
324+
return Sub8;
325+
case ELF::R_LARCH_SUB16:
326+
return Sub16;
327+
case ELF::R_LARCH_SUB32:
328+
return Sub32;
329+
case ELF::R_LARCH_SUB64:
330+
return Sub64;
331+
case ELF::R_LARCH_SUB_ULEB128:
332+
return SubUleb128;
309333
case ELF::R_LARCH_ALIGN:
310334
return AlignRelaxable;
311335
}

llvm/lib/ExecutionEngine/JITLink/loongarch.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ const char *getEdgeKindName(Edge::Kind K) {
5252
KIND_NAME_CASE(RequestGOTAndTransformToPage20)
5353
KIND_NAME_CASE(RequestGOTAndTransformToPageOffset12)
5454
KIND_NAME_CASE(Call36PCRel)
55+
KIND_NAME_CASE(Add6)
56+
KIND_NAME_CASE(Add8)
57+
KIND_NAME_CASE(Add16)
58+
KIND_NAME_CASE(Add32)
59+
KIND_NAME_CASE(Add64)
60+
KIND_NAME_CASE(AddUleb128)
61+
KIND_NAME_CASE(Sub6)
62+
KIND_NAME_CASE(Sub8)
63+
KIND_NAME_CASE(Sub16)
64+
KIND_NAME_CASE(Sub32)
65+
KIND_NAME_CASE(Sub64)
66+
KIND_NAME_CASE(SubUleb128)
5567
KIND_NAME_CASE(AlignRelaxable)
5668
default:
5769
return getGenericEdgeKindName(K);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# RUN: rm -rf %t && mkdir -p %t
2+
# RUN: llvm-mc --triple=loongarch32 -mattr=+relax --filetype=obj \
3+
# RUN: -o %t/la32_reloc_addsub.o %s
4+
# RUN: llvm-jitlink --noexec --check %s %t/la32_reloc_addsub.o \
5+
# RUN: --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
6+
# RUN: llvm-mc --triple=loongarch64 -mattr=+relax --filetype=obj \
7+
# RUN: -o %t/la64_reloc_addsub.o %s
8+
# RUN: llvm-jitlink --noexec --check %s %t/la64_reloc_addsub.o \
9+
# RUN: --slab-allocate=1Mb --slab-address=0x1000 --slab-page-size=0x4000
10+
11+
# jitlink-check: *{8}(named_data) = 0x8
12+
# jitlink-check: *{4}(named_data+8) = 0x8
13+
# jitlink-check: *{2}(named_data+12) = 0x8
14+
# jitlink-check: *{1}(named_data+14) = 0x8
15+
# jitlink-check: *{1}(named_data+15) = 0x10
16+
17+
# jitlink-check: *{1}(leb_data) = 0x8
18+
# jitlink-check: *{2}(leb_data+1) = 0x180
19+
# jitlink-check: *{8}(leb_data+3) = 0xfffffffffffffff8
20+
# jitlink-check: *{2}(leb_data+11) = 0x1ff
21+
# jitlink-check: *{1}(leb_data+13) = 0x7f
22+
# jitlink-check: *{2}(leb_data+14) = 0x181
23+
24+
.section .alloc_data,"ax",@progbits
25+
.global main
26+
main:
27+
.L0:
28+
# Referencing named_data symbol to avoid the following relocations be
29+
# skipped. This macro instruction will be expand to two instructions
30+
# (pcalau12i + ld.w/d).
31+
la.global $t0, named_data
32+
.L1:
33+
34+
named_data:
35+
.reloc named_data+15, R_LARCH_ADD6, .L1
36+
.reloc named_data+15, R_LARCH_SUB6, .L0
37+
.dword .L1 - .L0
38+
.word .L1 - .L0
39+
.half .L1 - .L0
40+
.byte .L1 - .L0
41+
.byte 0x8
42+
43+
.size named_data, 16
44+
45+
leb_data:
46+
.uleb128 .L1 - .L0
47+
.uleb128 .L1 - .L0 + 120
48+
.uleb128 -(.L1 - .L0)
49+
.uleb128 leb_end - leb_data + 111
50+
.uleb128 leb_end - leb_data + 113
51+
leb_end:
52+
53+
.size leb_data, 16

0 commit comments

Comments
 (0)