Skip to content

[lld][ELF][LoongArch] Add support for R_LARCH_LE_{HI20,ADD,LO12}_R relocations #99486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions lld/ELF/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Symbols.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/LEB128.h"

using namespace llvm;
Expand Down Expand Up @@ -407,7 +408,9 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s,
case R_LARCH_TLS_TPREL32:
case R_LARCH_TLS_TPREL64:
case R_LARCH_TLS_LE_HI20:
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_TLS_LE_LO12:
case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_LE64_LO20:
case R_LARCH_TLS_LE64_HI12:
return R_TPREL;
Expand Down Expand Up @@ -490,6 +493,7 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s,
return R_TLSLD_GOT;
case R_LARCH_TLS_GD_HI20:
return R_TLSGD_GOT;
case R_LARCH_TLS_LE_ADD_R:
case R_LARCH_RELAX:
return config->relax ? R_RELAX_HINT : R_NONE;
case R_LARCH_ALIGN:
Expand Down Expand Up @@ -617,6 +621,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
case R_LARCH_TLS_LE_LO12:
case R_LARCH_TLS_IE_PC_LO12:
case R_LARCH_TLS_IE_LO12:
case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_DESC_PC_LO12:
case R_LARCH_TLS_DESC_LO12:
write32le(loc, setK12(read32le(loc), extractBits(val, 11, 0)));
Expand All @@ -638,6 +643,9 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
case R_LARCH_TLS_DESC_HI20:
write32le(loc, setJ20(read32le(loc), extractBits(val, 31, 12)));
return;
case R_LARCH_TLS_LE_HI20_R:
write32le(loc, setJ20(read32le(loc), extractBits(val + 0x800, 31, 12)));
return;

// Relocs intended for `lu32i.d`.
case R_LARCH_ABS64_LO20:
Expand Down Expand Up @@ -707,6 +715,7 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel,
// no-op
return;

case R_LARCH_TLS_LE_ADD_R:
case R_LARCH_RELAX:
return; // Ignored (for now)

Expand Down
47 changes: 44 additions & 3 deletions lld/test/ELF/loongarch-tls-le.s
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# REQUIRES: loongarch

# RUN: llvm-mc --filetype=obj --triple=loongarch32 %s -o %t.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch32 --defsym ELF32=1 %s -o %t.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t.64.o

# RUN: ld.lld %t.32.o -o %t.32
# RUN: llvm-nm -p %t.32 | FileCheck --check-prefixes=NM %s
# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE %s
# RUN: llvm-objdump -d --no-show-raw-insn %t.32 | FileCheck --check-prefixes=LE,LE32 %s

# RUN: ld.lld %t.64.o -o %t.64
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE %s
# RUN: llvm-objdump -d --no-show-raw-insn %t.64 | FileCheck --check-prefixes=LE,LE64 %s

# RUN: not ld.lld -shared %t.32.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:

# ERR: error: relocation R_LARCH_TLS_LE_HI20 against .LANCHOR0 cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_LO12 against .LANCHOR0 cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_HI20 against a cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_LO12 against a cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_HI20_R against .LANCHOR0 cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_LO12_R against .LANCHOR0 cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_HI20_R against a cannot be used with -shared
# ERR: error: relocation R_LARCH_TLS_LE_LO12_R against a cannot be used with -shared

# NM: {{0*}}00000008 b .LANCHOR0
# NM: {{0*}}00000800 B a
Expand All @@ -26,13 +30,50 @@
# LE-NEXT: ori $a0, $a0, 8
# LE-NEXT: lu12i.w $a1, 0
# LE-NEXT: ori $a1, $a1, 2048

# LE32: add.w $a0, $a0, $tp
# LE32-NEXT: addi.w $a0, $a0, 8
# LE32-NEXT: lu12i.w $a0, 1
# LE32-NEXT: add.w $a0, $a0, $tp
# LE32-NEXT: addi.w $a0, $a0, -2048

# LE64: add.d $a0, $a0, $tp
# LE64-NEXT: addi.d $a0, $a0, 8
# LE64-NEXT: lu12i.w $a0, 1
# LE64-NEXT: add.d $a0, $a0, $tp
# LE64-NEXT: addi.d $a0, $a0, -2048

# LE-EMPTY:

.macro add dst, src1, src2, src3
.ifdef ELF32
add.w \dst, \src1, \src2, \src3
.else
add.d \dst, \src1, \src2, \src3
.endif
.endm
.macro addi dst, src1, src2
.ifdef ELF32
addi.w \dst, \src1, \src2
.else
addi.d \dst, \src1, \src2
.endif
.endm

.text

_start:
la.tls.le $a0, .LANCHOR0
la.tls.le $a1, a

lu12i.w $a0, %le_hi20_r(.LANCHOR0)
add $a0, $a0, $tp, %le_add_r(.LANCHOR0)
addi $a0, $a0, %le_lo12_r(.LANCHOR0)

lu12i.w $a0, %le_hi20_r(a)
add $a0, $a0, $tp, %le_add_r(a)
addi $a0, $a0, %le_lo12_r(a)

.section .tbss,"awT",@nobits
.space 8
.LANCHOR0:
Expand Down
Loading