Skip to content

Commit eaed22c

Browse files
jrtc27resistor
authored andcommitted
[ELF][RISCV] Use .got rather than .captable for CHERI-RISC-V
1 parent 81bfb0f commit eaed22c

File tree

8 files changed

+256
-210
lines changed

8 files changed

+256
-210
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ RISCV::RISCV(Ctx &ctx) : TargetInfo(ctx) {
143143
tlsOffsetRel = R_RISCV_TLS_DTPREL32;
144144
tlsGotRel = R_RISCV_TLS_TPREL32;
145145
}
146-
gotRel = symbolicRel;
146+
if (ctx.arg.isCheriAbi)
147+
gotRel = *cheriCapRel;
148+
else
149+
gotRel = symbolicRel;
147150
tlsDescRel = R_RISCV_TLSDESC;
148151

149152
// .got[0] = _DYNAMIC
@@ -307,9 +310,8 @@ void RISCV::writePlt(uint8_t *buf, const Symbol &sym,
307310
// nop
308311
uint32_t ptrload = ctx.arg.isCheriAbi ? ctx.arg.is64 ? CLC_128 : CLC_64
309312
: ctx.arg.is64 ? LD : LW;
310-
uint32_t entryva = ctx.arg.isCheriAbi
311-
? sym.getCapTableVA(ctx, ctx.in.plt.get(), 0)
312-
: sym.getGotPltVA(ctx);
313+
uint32_t entryva =
314+
ctx.arg.isCheriAbi ? sym.getGotVA(ctx) : sym.getGotPltVA(ctx);
313315
uint32_t offset = entryva - pltEntryAddr;
314316
write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset)));
315317
write32le(buf + 4, itype(ptrload, X_T3, X_T3, lo12(offset)));
@@ -393,25 +395,27 @@ RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
393395
return RE_RISCV_LEB128;
394396
case R_RISCV_CHERI_CAPABILITY:
395397
return R_CHERI_CAPABILITY;
396-
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
397-
return R_CHERI_CAPABILITY_TABLE_ENTRY_PC;
398-
case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
399-
return R_CHERI_CAPABILITY_TABLE_TLSIE_ENTRY_PC;
400-
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
401-
return R_CHERI_CAPABILITY_TABLE_TLSGD_ENTRY_PC;
402-
case R_RISCV_CHERIOT_COMPARTMENT_HI:
403-
return isPCCRelative(ctx, loc, &s) ? R_PC : R_CHERIOT_COMPARTMENT_CGPREL_HI;
404-
case R_RISCV_CHERIOT_COMPARTMENT_LO_I:
405-
return R_CHERIOT_COMPARTMENT_CGPREL_LO_I;
406-
case R_RISCV_CHERIOT_COMPARTMENT_LO_S:
407-
return R_CHERIOT_COMPARTMENT_CGPREL_LO_S;
408-
case R_RISCV_CHERIOT_COMPARTMENT_SIZE:
409-
return R_CHERIOT_COMPARTMENT_SIZE;
410-
default:
411-
Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
412-
<< ") against symbol " << &s;
413-
return R_NONE;
414-
}
398+
// TODO: Deprecate and eventually remove these
399+
case R_RISCV_CHERI_CAPTAB_PCREL_HI20:
400+
return R_GOT_PC;
401+
case R_RISCV_CHERI_TLS_IE_CAPTAB_PCREL_HI20:
402+
return R_GOT_PC;
403+
case R_RISCV_CHERI_TLS_GD_CAPTAB_PCREL_HI20:
404+
return R_TLSGD_PC;
405+
case R_RISCV_CHERIOT_COMPARTMENT_HI:
406+
return isPCCRelative(ctx, loc, &s) ? R_PC
407+
: R_CHERIOT_COMPARTMENT_CGPREL_HI;
408+
case R_RISCV_CHERIOT_COMPARTMENT_LO_I:
409+
return R_CHERIOT_COMPARTMENT_CGPREL_LO_I;
410+
case R_RISCV_CHERIOT_COMPARTMENT_LO_S:
411+
return R_CHERIOT_COMPARTMENT_CGPREL_LO_S;
412+
case R_RISCV_CHERIOT_COMPARTMENT_SIZE:
413+
return R_CHERIOT_COMPARTMENT_SIZE;
414+
default:
415+
Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
416+
<< ") against symbol " << &s;
417+
return R_NONE;
418+
}
415419
}
416420

417421
void RISCV::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {

lld/ELF/InputSection.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,20 +1020,6 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
10201020
case R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE:
10211021
assert(a == 0 && "capability table index relocs should not have addends");
10221022
return r.sym->getCapTableOffset(ctx, this, r.offset);
1023-
case R_CHERI_CAPABILITY_TABLE_ENTRY_PC: {
1024-
assert(a == 0 && "capability table entry relocs should not have addends");
1025-
return r.sym->getCapTableVA(ctx, this, r.offset) - p;
1026-
}
1027-
case R_CHERI_CAPABILITY_TABLE_TLSGD_ENTRY_PC: {
1028-
assert(a == 0 && "capability table index relocs should not have addends");
1029-
uint64_t capTableOffset = ctx.in.cheriCapTable->getDynTlsOffset(*r.sym);
1030-
return ctx.sym.cheriCapabilityTable->getVA(ctx) + capTableOffset - p;
1031-
}
1032-
case R_CHERI_CAPABILITY_TABLE_TLSIE_ENTRY_PC: {
1033-
assert(a == 0 && "capability table index relocs should not have addends");
1034-
uint64_t capTableOffset = ctx.in.cheriCapTable->getTlsOffset(*r.sym);
1035-
return ctx.sym.cheriCapabilityTable->getVA(ctx) + capTableOffset - p;
1036-
}
10371023
case R_CHERI_CAPABILITY_TABLE_REL:
10381024
if (!ctx.sym.cheriCapabilityTable) {
10391025
error("cannot compute difference between non-existent "

lld/ELF/Relocations.cpp

Lines changed: 40 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -923,20 +923,21 @@ template <class PltSection, class GotPltSection>
923923
static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
924924
RelocationBaseSection &rel, RelType type, Symbol &sym) {
925925
plt.addEntry(sym);
926-
if (ctx.arg.isCheriAbi) {
927-
// TODO: More normal .got.plt rather than piggy-backing on .captable. We
928-
// pass R_CHERI_CAPABILITY_TABLE_INDEX rather than the more obvious
929-
// R_CHERI_CAPABILITY_TABLE_INDEX_CALL to force dynamic relocations into
930-
// .rela.dyn rather than .rela.plt so no rtld changes are needed, as the
931-
// latter doesn't really achieve anything without lazy binding.
932-
ctx.in.cheriCapTable->addEntry(sym, R_CHERI_CAPABILITY_TABLE_INDEX, &plt, 0);
933-
} else {
934-
gotPlt.addEntry(sym);
935-
rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
936-
sym.isPreemptible ? DynamicReloc::AgainstSymbol
937-
: DynamicReloc::AddendOnlyWithTargetVA,
938-
sym, 0, R_ABS});
939-
}
926+
927+
// For CHERI-RISC-V we mark the symbol NEEDS_GOT so it will end up in .got as
928+
// a function pointer, and uses .rela.dyn rather than .rela.plt, so no rtld
929+
// changes are needed.
930+
//
931+
// TODO: More normal .got.plt with lazy-binding rather than piggy-backing on
932+
// .got once rtld supports it.
933+
if (ctx.arg.emachine == EM_RISCV && ctx.arg.isCheriAbi)
934+
return;
935+
936+
gotPlt.addEntry(sym);
937+
rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
938+
sym.isPreemptible ? DynamicReloc::AgainstSymbol
939+
: DynamicReloc::AddendOnlyWithTargetVA,
940+
sym, 0, R_ABS});
940941
}
941942

942943
void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
@@ -952,8 +953,12 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
952953
}
953954

954955
// Otherwise, the value is either a link-time constant or the load base
955-
// plus a constant.
956-
if (!ctx.arg.isPic || isAbsolute(sym))
956+
// plus a constant. For CHERI it always requires run-time initialisation.
957+
if (ctx.arg.isCheriAbi) {
958+
invokeELFT(addCapabilityRelocation, ctx, &sym, *ctx.target->cheriCapRel,
959+
ctx.in.got.get(), off, R_CHERI_CAPABILITY, 0, false,
960+
[] { return ""; });
961+
} else if (!ctx.arg.isPic || isAbsolute(sym))
957962
ctx.in.got->addConstant({R_ABS, ctx.target->symbolicRel, off, 0, &sym});
958963
else
959964
addRelativeReloc(ctx, *ctx.in.got, off, sym, 0, R_ABS,
@@ -1023,25 +1028,22 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
10231028
const Symbol &sym,
10241029
uint64_t relOff) const {
10251030
// These expressions always compute a constant
1026-
if (oneof<
1027-
R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
1028-
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_MIPS_GOT_GP_PC,
1029-
RE_AARCH64_GOT_PAGE_PC, RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC,
1030-
R_GOTONLY_PC, R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
1031-
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
1032-
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
1033-
RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC, RE_LOONGARCH_PLT_PAGE_PC,
1034-
RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC,
1035-
R_CHERI_CAPABILITY_TABLE_INDEX,
1031+
if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
1032+
RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
1033+
RE_MIPS_GOT_GP_PC, RE_AARCH64_GOT_PAGE_PC,
1034+
RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
1035+
R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
1036+
R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
1037+
RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
1038+
RE_AARCH64_AUTH_GOT, RE_AARCH64_AUTH_GOT_PC,
1039+
RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
1040+
RE_LOONGARCH_GOT_PAGE_PC, R_CHERI_CAPABILITY_TABLE_INDEX,
10361041
R_CHERI_CAPABILITY_TABLE_INDEX_SMALL_IMMEDIATE,
10371042
R_CHERI_CAPABILITY_TABLE_INDEX_CALL,
10381043
R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE,
1039-
R_CHERI_CAPABILITY_TABLE_ENTRY_PC,
1040-
R_CHERI_CAPABILITY_TABLE_REL,
1041-
R_CHERIOT_COMPARTMENT_CGPREL_HI,
1044+
R_CHERI_CAPABILITY_TABLE_REL, R_CHERIOT_COMPARTMENT_CGPREL_HI,
10421045
R_CHERIOT_COMPARTMENT_CGPREL_LO_I,
1043-
R_CHERIOT_COMPARTMENT_CGPREL_LO_S,
1044-
R_CHERIOT_COMPARTMENT_SIZE>(e))
1046+
R_CHERIOT_COMPARTMENT_CGPREL_LO_S, R_CHERIOT_COMPARTMENT_SIZE>(e))
10451047
return true;
10461048

10471049
// Cheri capability relocations are never static link time constants since
@@ -1161,20 +1163,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11611163
if (oneof<R_CHERI_CAPABILITY_TABLE_INDEX,
11621164
R_CHERI_CAPABILITY_TABLE_INDEX_SMALL_IMMEDIATE,
11631165
R_CHERI_CAPABILITY_TABLE_INDEX_CALL,
1164-
R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE,
1165-
R_CHERI_CAPABILITY_TABLE_ENTRY_PC>(expr)) {
1166-
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1167-
ctx.in.cheriCapTable->addEntry(sym, expr, sec, offset);
1168-
// Write out the index into the instruction
1169-
sec->relocations.push_back({expr, type, offset, addend, &sym});
1170-
return;
1171-
}
1172-
1173-
if (oneof<R_CHERI_CAPABILITY_TABLE_INDEX,
1174-
R_CHERI_CAPABILITY_TABLE_INDEX_SMALL_IMMEDIATE,
1175-
R_CHERI_CAPABILITY_TABLE_INDEX_CALL,
1176-
R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE,
1177-
R_CHERI_CAPABILITY_TABLE_ENTRY_PC>(expr)) {
1166+
R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE>(expr)) {
11781167
std::lock_guard<std::mutex> lock(ctx.relocMutex);
11791168
ctx.in.cheriCapTable->addEntry(sym, expr, sec, offset);
11801169
// Write out the index into the instruction
@@ -1203,6 +1192,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
12031192
}
12041193
} else if (needsPlt(expr)) {
12051194
sym.setFlags(NEEDS_PLT);
1195+
// See addPltEntry
1196+
if (ctx.arg.emachine == EM_RISCV && ctx.arg.isCheriAbi)
1197+
sym.setFlags(NEEDS_GOT);
12061198
} else if (LLVM_UNLIKELY(isIfunc)) {
12071199
sym.setFlags(HAS_DIRECT_RELOC);
12081200
}
@@ -1359,6 +1351,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
13591351
printLocation(diag, *sec, sym, offset);
13601352
}
13611353
sym.setFlags(NEEDS_COPY | NEEDS_PLT);
1354+
// See addPltEntry
1355+
if (ctx.arg.emachine == EM_RISCV && ctx.arg.isCheriAbi)
1356+
sym.setFlags(NEEDS_GOT);
13621357
sec->addReloc({expr, type, offset, addend, &sym});
13631358
return;
13641359
}
@@ -1501,36 +1496,6 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
15011496
!(isRISCV && expr != R_TLSDESC_PC && expr != R_TLSDESC_CALL) &&
15021497
!sec->file->ppc64DisableTLSRelax;
15031498

1504-
// No targets currently support TLS relaxation, so we can avoid duplicating
1505-
// much of the logic below for the captable.
1506-
if (expr == R_CHERI_CAPABILITY_TABLE_TLSGD_ENTRY_PC) {
1507-
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1508-
ctx.in.cheriCapTable->addDynTlsEntry(sym);
1509-
sec->relocations.push_back({expr, type, offset, addend, &sym});
1510-
return 1;
1511-
}
1512-
if (expr == R_CHERI_CAPABILITY_TABLE_TLSIE_ENTRY_PC) {
1513-
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1514-
ctx.in.cheriCapTable->addTlsEntry(sym);
1515-
sec->relocations.push_back({expr, type, offset, addend, &sym});
1516-
return 1;
1517-
}
1518-
1519-
// No targets currently support TLS relaxation, so we can avoid duplicating
1520-
// much of the logic below for the captable.
1521-
if (expr == R_CHERI_CAPABILITY_TABLE_TLSGD_ENTRY_PC) {
1522-
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1523-
ctx.in.cheriCapTable->addDynTlsEntry(sym);
1524-
sec->relocations.push_back({expr, type, offset, addend, &sym});
1525-
return 1;
1526-
}
1527-
if (expr == R_CHERI_CAPABILITY_TABLE_TLSIE_ENTRY_PC) {
1528-
std::lock_guard<std::mutex> lock(ctx.relocMutex);
1529-
ctx.in.cheriCapTable->addTlsEntry(sym);
1530-
sec->relocations.push_back({expr, type, offset, addend, &sym});
1531-
return 1;
1532-
}
1533-
15341499
// If we are producing an executable and the symbol is non-preemptable, it
15351500
// must be defined and the code sequence can be optimized to use
15361501
// Local-Exesec->

lld/ELF/Relocations.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ enum RelExpr {
126126
R_CHERI_CAPABILITY_TABLE_INDEX_SMALL_IMMEDIATE,
127127
R_CHERI_CAPABILITY_TABLE_INDEX_CALL,
128128
R_CHERI_CAPABILITY_TABLE_INDEX_CALL_SMALL_IMMEDIATE,
129-
R_CHERI_CAPABILITY_TABLE_ENTRY_PC,
130-
R_CHERI_CAPABILITY_TABLE_TLSGD_ENTRY_PC,
131-
R_CHERI_CAPABILITY_TABLE_TLSIE_ENTRY_PC,
132129
R_CHERI_CAPABILITY_TABLE_REL, // relative offset to _CHERI_CAPABILITY_TABLE_
133130
R_MIPS_CHERI_CAPTAB_TLSGD,
134131
R_MIPS_CHERI_CAPTAB_TLSLD,

lld/ELF/SyntheticSections.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,9 @@ GotSection::GotSection(Ctx &ctx)
686686

687687
void GotSection::addConstant(const Relocation &r) { relocations.push_back(r); }
688688
void GotSection::addEntry(const Symbol &sym) {
689+
// TODO: Separate out TLS IE entries for CHERI so we can pack them more
690+
// efficiently rather than consuming a whole capability-sized slot for an
691+
// integer.
689692
assert(sym.auxIdx == ctx.symAux.size() - 1);
690693
ctx.symAux.back().gotIdx = numEntries++;
691694
}
@@ -710,8 +713,12 @@ void GotSection::addTlsDescAuthEntry() {
710713
bool GotSection::addDynTlsEntry(const Symbol &sym) {
711714
assert(sym.auxIdx == ctx.symAux.size() - 1);
712715
ctx.symAux.back().tlsGdIdx = numEntries;
713-
// Global Dynamic TLS entries take two GOT slots.
714-
numEntries += 2;
716+
// Global Dynamic TLS entries take two GOT slots, except on CHERI where they
717+
// can be packed into one GOT slot.
718+
if (ctx.arg.isCheriAbi)
719+
++numEntries;
720+
else
721+
numEntries += 2;
715722
return true;
716723
}
717724

lld/test/ELF/cheri/riscv/plt.s

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# RUN: ld.lld %t.32.o %t1.32.so -z separate-code -o %t.32
88
# RUN: llvm-readelf -S -s %t.32 | FileCheck --check-prefixes=SEC,NM %s
99
# RUN: llvm-readobj -r %t.32 | FileCheck --check-prefix=RELOC32 %s
10-
# RUN: llvm-readelf -x .captable %t.32 | FileCheck --check-prefix=CAPTAB32 %s
10+
# RUN: llvm-readelf -x .got %t.32 | FileCheck --check-prefix=GOT32 %s
1111
# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex=false %t.32 | FileCheck --check-prefixes=DIS,DIS32 %s
1212

1313
# RUN: %riscv64_cheri_purecap_llvm-mc -filetype=obj %t1.s -o %t1.64.o
@@ -16,7 +16,7 @@
1616
# RUN: ld.lld %t.64.o %t1.64.so -z separate-code -o %t.64
1717
# RUN: llvm-readelf -S -s %t.64 | FileCheck --check-prefixes=SEC,NM %s
1818
# RUN: llvm-readobj -r %t.64 | FileCheck --check-prefix=RELOC64 %s
19-
# RUN: llvm-readelf -x .captable %t.64 | FileCheck --check-prefix=CAPTAB64 %s
19+
# RUN: llvm-readelf -x .got %t.64 | FileCheck --check-prefix=GOT64 %s
2020
# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex=false %t.64 | FileCheck --check-prefixes=DIS,DIS64 %s
2121

2222
# SEC: .plt PROGBITS {{0*}}00011030
@@ -27,19 +27,21 @@
2727
# NM: {{0*}}00000000 0 FUNC WEAK DEFAULT UND weak
2828

2929
# RELOC32: .rela.dyn {
30-
# RELOC32-NEXT: 0x12000 R_RISCV_CHERI_CAPABILITY bar 0x0
31-
# RELOC32-NEXT: 0x12008 R_RISCV_CHERI_CAPABILITY weak 0x0
30+
# RELOC32-NEXT: 0x12068 R_RISCV_CHERI_CAPABILITY bar 0x0
31+
# RELOC32-NEXT: 0x12070 R_RISCV_CHERI_CAPABILITY weak 0x0
3232
# RELOC32-NEXT: }
33-
# CAPTAB32: section '.captable'
34-
# CAPTAB32-NEXT: 0x00012000 00000000 00000000 00000000 00000000
33+
# GOT32: section '.got'
34+
# GOT32-NEXT: 0x00012060 00200100 00000000 00000000 00000000
35+
# GOT32-NEXT: 0x00012070 00000000 00000000
3536

3637
# RELOC64: .rela.dyn {
37-
# RELOC64-NEXT: 0x12000 R_RISCV_CHERI_CAPABILITY bar 0x0
38-
# RELOC64-NEXT: 0x12010 R_RISCV_CHERI_CAPABILITY weak 0x0
38+
# RELOC64-NEXT: 0x120D0 R_RISCV_CHERI_CAPABILITY bar 0x0
39+
# RELOC64-NEXT: 0x120E0 R_RISCV_CHERI_CAPABILITY weak 0x0
3940
# RELOC64-NEXT: }
40-
# CAPTAB64: section '.captable'
41-
# CAPTAB64-NEXT: 0x00012000 00000000 00000000 00000000 00000000
42-
# CAPTAB64-NEXT: 0x00012010 00000000 00000000 00000000 00000000
41+
# GOT64: section '.got'
42+
# GOT64-NEXT: 0x000120c0 00200100 00000000 00000000 00000000
43+
# GOT64-NEXT: 0x000120d0 00000000 00000000 00000000 00000000
44+
# GOT64-NEXT: 0x000120e0 00000000 00000000 00000000 00000000
4345

4446
# DIS: <_start>:
4547
## Direct call
@@ -62,17 +64,19 @@
6264
# DIS: <.plt>:
6365
# DIS-NEXT: ...
6466

65-
## 32-bit: &.captable[bar]-. = 0x12000-0x11050 = 4096*1-80
67+
## 32-bit: &.got[bar]-. = 0x12068-0x11050 = 4096*1+24
68+
## 64-bit: &.got[bar]-. = 0x120d0-0x11050 = 4096*1+128
6669
# DIS: 11050: auipcc t3, 1
67-
# DIS32-NEXT: clc t3, -80(t3)
68-
# DIS64-NEXT: clc t3, -80(t3)
70+
# DIS32-NEXT: clc t3, 24(t3)
71+
# DIS64-NEXT: clc t3, 128(t3)
6972
# DIS-NEXT: cjalr t1, t3
7073
# DIS-NEXT: nop
7174

72-
## 32-bit: &.captable[weak]-. = 0x12008-0x11060 = 4096*1-88
75+
## 32-bit: &.got[weak]-. = 0x12070-0x11060 = 4096*1+16
76+
## 64-bit: &.got[weak]-. = 0x120e0-0x11060 = 4096*1+128
7377
# DIS: 11060: auipcc t3, 1
74-
# DIS32-NEXT: clc t3, -88(t3)
75-
# DIS64-NEXT: clc t3, -80(t3)
78+
# DIS32-NEXT: clc t3, 16(t3)
79+
# DIS64-NEXT: clc t3, 128(t3)
7680
# DIS-NEXT: cjalr t1, t3
7781
# DIS-NEXT: nop
7882

0 commit comments

Comments
 (0)