Skip to content

Commit 39c2d7b

Browse files
[WebAssembly] Add new relocation for pc-rel data
This `R_WASM_MEMORY_ADDR_SELFREL_I32` relocation represents an offset between its relocating address and the symbol address. It's very similar to `R_X86_64_PC32` but restricted to be used for only data segments. ``` S + A - P ``` A: Represents the addend used to compute the value of the relocatable field. P: Represents the place of the storage unit being relocated. S: Represents the value of the symbol whose index resides in the relocation entry. Proposal: WebAssembly/tool-conventions#162 Differential Revision: https://reviews.llvm.org/D96659
1 parent 1cbc158 commit 39c2d7b

File tree

13 files changed

+216
-51
lines changed

13 files changed

+216
-51
lines changed

lld/test/wasm/selfrel-reloc.ll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/hello.s -o %t.hello32.o
2+
; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.o
3+
; RUN: wasm-ld --no-entry --no-gc-sections --allow-undefined -o %t.wasm %t.o %t.hello32.o
4+
; RUN: obj2yaml %t.wasm | FileCheck %s
5+
6+
target triple = "wasm32-unknown-unknown"
7+
8+
9+
; @hello_str - @bar_neg
10+
@hello_str = external global i8*
11+
@bar_neg = constant i32 sub (
12+
i32 ptrtoint (i8** @hello_str to i32),
13+
i32 ptrtoint (i32* @bar_neg to i32)
14+
), section ".sec1"
15+
16+
@bar_pos = constant i32 sub (
17+
i32 ptrtoint (i32* @fizz to i32),
18+
i32 ptrtoint (i32* @bar_pos to i32)
19+
), section ".sec1"
20+
21+
22+
; @hello_str - @addend + 4
23+
@fizz = constant i32 42, align 4, section ".sec2"
24+
@addend = constant i32 sub (
25+
i32 ptrtoint (i8** @hello_str to i32),
26+
i32 ptrtoint (i32* @fizz to i32)
27+
), section ".sec2"
28+
29+
30+
; CHECK: - Type: DATA
31+
; CHECK-NEXT: Segments:
32+
; CHECK-NEXT: - SectionOffset: 7
33+
; CHECK-NEXT: InitFlags: 0
34+
; CHECK-NEXT: Offset:
35+
; CHECK-NEXT: Opcode: I32_CONST
36+
; CHECK-NEXT: Value: 1024
37+
; CHECK-NEXT: Content: 68656C6C6F0A00
38+
; CHECK-NEXT: - SectionOffset: 20
39+
; CHECK-NEXT: InitFlags: 0
40+
; CHECK-NEXT: Offset:
41+
; CHECK-NEXT: Opcode: I32_CONST
42+
; CHECK-NEXT: Value: 1032
43+
; CHECK-NEXT: Content: F8FFFFFF04000000
44+
; CHECK-NEXT: - SectionOffset: 34
45+
; CHECK-NEXT: InitFlags: 0
46+
; CHECK-NEXT: Offset:
47+
; CHECK-NEXT: Opcode: I32_CONST
48+
; CHECK-NEXT: Value: 1040
49+
; CHECK-NEXT: Content: 2A000000F0FFFFFF
50+

lld/wasm/InputChunks.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ void InputChunk::verifyRelocTargets() const {
9393
case R_WASM_FUNCTION_OFFSET_I32:
9494
case R_WASM_SECTION_OFFSET_I32:
9595
case R_WASM_GLOBAL_INDEX_I32:
96+
case R_WASM_MEMORY_ADDR_SELFREL_I32:
9697
existingValue = read32le(loc);
9798
break;
9899
case R_WASM_TABLE_INDEX_I64:
@@ -138,7 +139,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
138139

139140
for (const WasmRelocation &rel : relocations) {
140141
uint8_t *loc = buf + rel.Offset + off;
141-
auto value = file->calcNewValue(rel, tombstone);
142+
auto value = file->calcNewValue(rel, tombstone, this);
142143
LLVM_DEBUG(dbgs() << "apply reloc: type=" << relocTypeToString(rel.Type));
143144
if (rel.Type != R_WASM_TYPE_INDEX_LEB)
144145
LLVM_DEBUG(dbgs() << " sym=" << file->getSymbols()[rel.Index]->getName());
@@ -174,6 +175,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
174175
case R_WASM_FUNCTION_OFFSET_I32:
175176
case R_WASM_SECTION_OFFSET_I32:
176177
case R_WASM_GLOBAL_INDEX_I32:
178+
case R_WASM_MEMORY_ADDR_SELFREL_I32:
177179
write32le(loc, value);
178180
break;
179181
case R_WASM_TABLE_INDEX_I64:
@@ -298,7 +300,8 @@ void InputFunction::calculateSize() {
298300
for (const WasmRelocation &rel : relocations) {
299301
LLVM_DEBUG(dbgs() << " region: " << (rel.Offset - lastRelocEnd) << "\n");
300302
compressedFuncSize += rel.Offset - lastRelocEnd;
301-
compressedFuncSize += getRelocWidth(rel, file->calcNewValue(rel, tombstone));
303+
compressedFuncSize +=
304+
getRelocWidth(rel, file->calcNewValue(rel, tombstone, this));
302305
lastRelocEnd = rel.Offset + getRelocWidthPadded(rel);
303306
}
304307
LLVM_DEBUG(dbgs() << " final region: " << (end - lastRelocEnd) << "\n");
@@ -339,7 +342,8 @@ void InputFunction::writeTo(uint8_t *buf) const {
339342
LLVM_DEBUG(dbgs() << " write chunk: " << chunkSize << "\n");
340343
memcpy(buf, lastRelocEnd, chunkSize);
341344
buf += chunkSize;
342-
buf += writeCompressedReloc(buf, rel, file->calcNewValue(rel, tombstone));
345+
buf += writeCompressedReloc(buf, rel,
346+
file->calcNewValue(rel, tombstone, this));
343347
lastRelocEnd = secStart + rel.Offset + getRelocWidthPadded(rel);
344348
}
345349

@@ -410,7 +414,7 @@ void InputSegment::generateRelocationCode(raw_ostream &os) const {
410414
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
411415
writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
412416
writeU8(os, opcode_reloc_const, "CONST");
413-
writeSleb128(os, file->calcNewValue(rel, tombstone), "offset");
417+
writeSleb128(os, file->calcNewValue(rel, tombstone, this), "offset");
414418
writeU8(os, opcode_reloc_add, "ADD");
415419
}
416420

lld/wasm/InputFiles.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ uint64_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const {
125125
case R_WASM_MEMORY_ADDR_I64:
126126
case R_WASM_FUNCTION_OFFSET_I32:
127127
case R_WASM_FUNCTION_OFFSET_I64:
128+
case R_WASM_MEMORY_ADDR_SELFREL_I32:
128129
return reloc.Addend;
129130
case R_WASM_SECTION_OFFSET_I32:
130131
return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend;
@@ -172,6 +173,14 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
172173
else
173174
llvm_unreachable("unknown init expr opcode");
174175
}
176+
case R_WASM_MEMORY_ADDR_SELFREL_I32: {
177+
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
178+
if (sym.isUndefined())
179+
return 0;
180+
const WasmSegment &segment =
181+
wasmObj->dataSegments()[sym.Info.DataRef.Segment];
182+
return segment.Data.Offset.Value.Int32;
183+
}
175184
case R_WASM_FUNCTION_OFFSET_I32:
176185
case R_WASM_FUNCTION_OFFSET_I64: {
177186
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
@@ -197,7 +206,8 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
197206
}
198207

199208
// Translate from the relocation's index into the final linked output value.
200-
uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone) const {
209+
uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
210+
const InputChunk *chunk) const {
201211
const Symbol* sym = nullptr;
202212
if (reloc.Type != R_WASM_TYPE_INDEX_LEB) {
203213
sym = symbols[reloc.Index];
@@ -232,7 +242,8 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone)
232242
case R_WASM_MEMORY_ADDR_REL_SLEB:
233243
case R_WASM_MEMORY_ADDR_REL_SLEB64:
234244
case R_WASM_MEMORY_ADDR_I32:
235-
case R_WASM_MEMORY_ADDR_I64: {
245+
case R_WASM_MEMORY_ADDR_I64:
246+
case R_WASM_MEMORY_ADDR_SELFREL_I32: {
236247
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
237248
return 0;
238249
auto D = cast<DefinedData>(sym);
@@ -243,7 +254,14 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone)
243254
// backward compat with old object files built with `-fPIC`.
244255
if (D->segment && D->segment->outputSeg->name == ".tdata")
245256
return D->getOutputSegmentOffset() + reloc.Addend;
246-
return D->getVirtualAddress() + reloc.Addend;
257+
uint64_t value = D->getVirtualAddress() + reloc.Addend;
258+
if (reloc.Type == R_WASM_MEMORY_ADDR_SELFREL_I32) {
259+
const auto *segment = cast<InputSegment>(chunk);
260+
uint64_t p = segment->outputSeg->startVA + segment->outputSegmentOffset +
261+
reloc.Offset - segment->getInputSectionOffset();
262+
value -= p;
263+
}
264+
return value;
247265
}
248266
case R_WASM_MEMORY_ADDR_TLS_SLEB:
249267
if (isa<UndefinedData>(sym) || sym->isUndefWeak())

lld/wasm/InputFiles.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ class ObjFile : public InputFile {
118118
void dumpInfo() const;
119119

120120
uint32_t calcNewIndex(const WasmRelocation &reloc) const;
121-
uint64_t calcNewValue(const WasmRelocation &reloc, uint64_t tombstone) const;
121+
uint64_t calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
122+
const InputChunk *chunk) const;
122123
uint64_t calcNewAddend(const WasmRelocation &reloc) const;
123124
uint64_t calcExpectedValue(const WasmRelocation &reloc) const;
124125
Symbol *getSymbol(const WasmRelocation &reloc) const {

llvm/include/llvm/BinaryFormat/WasmRelocs.def

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,27 @@
22
#error "WASM_RELOC must be defined"
33
#endif
44

5-
WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0)
6-
WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1)
7-
WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2)
8-
WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3)
9-
WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4)
10-
WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5)
11-
WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6)
12-
WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7)
13-
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8)
14-
WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9)
15-
WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
16-
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
17-
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
18-
WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 13)
19-
WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 14)
20-
WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 15)
21-
WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 16)
22-
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
23-
WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
24-
WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
25-
WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
26-
WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
27-
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
5+
WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0)
6+
WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1)
7+
WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2)
8+
WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3)
9+
WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4)
10+
WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5)
11+
WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6)
12+
WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7)
13+
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8)
14+
WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9)
15+
WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
16+
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
17+
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
18+
WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 13)
19+
WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 14)
20+
WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 15)
21+
WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 16)
22+
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
23+
WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
24+
WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
25+
WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
26+
WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
27+
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
28+
WASM_RELOC(R_WASM_MEMORY_ADDR_SELFREL_I32, 23)

llvm/include/llvm/MC/MCWasmObjectWriter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class MCWasmObjectTargetWriter : public MCObjectTargetWriter {
3333
return W->getFormat() == Triple::Wasm;
3434
}
3535

36-
virtual unsigned getRelocType(const MCValue &Target,
37-
const MCFixup &Fixup) const = 0;
36+
virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
37+
bool IsLocRel) const = 0;
3838

3939
/// \name Accessors
4040
/// @{

llvm/lib/BinaryFormat/Wasm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
5252
case R_WASM_FUNCTION_OFFSET_I32:
5353
case R_WASM_FUNCTION_OFFSET_I64:
5454
case R_WASM_SECTION_OFFSET_I32:
55+
case R_WASM_MEMORY_ADDR_SELFREL_I32:
5556
return true;
5657
default:
5758
return false;

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -447,17 +447,35 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
447447
uint64_t C = Target.getConstant();
448448
uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
449449
MCContext &Ctx = Asm.getContext();
450+
bool IsLocRel = false;
450451

451452
if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
452-
// To get here the A - B expression must have failed evaluateAsRelocatable.
453-
// This means either A or B must be undefined and in WebAssembly we can't
454-
// support either of those cases.
453+
455454
const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol());
456-
Ctx.reportError(
457-
Fixup.getLoc(),
458-
Twine("symbol '") + SymB.getName() +
459-
"': unsupported subtraction expression used in relocation.");
460-
return;
455+
456+
if (FixupSection.getKind().isText()) {
457+
Ctx.reportError(Fixup.getLoc(),
458+
Twine("symbol '") + SymB.getName() +
459+
"' unsupported subtraction expression used in "
460+
"relocation in code section.");
461+
return;
462+
}
463+
464+
if (SymB.isUndefined()) {
465+
Ctx.reportError(Fixup.getLoc(),
466+
Twine("symbol '") + SymB.getName() +
467+
"' can not be undefined in a subtraction expression");
468+
return;
469+
}
470+
const MCSection &SecB = SymB.getSection();
471+
if (&SecB != &FixupSection) {
472+
Ctx.reportError(Fixup.getLoc(),
473+
Twine("symbol '") + SymB.getName() +
474+
"' can not be placed in a different section");
475+
return;
476+
}
477+
IsLocRel = true;
478+
C += FixupOffset - Layout.getSymbolOffset(SymB);
461479
}
462480

463481
// We either rejected the fixup or folded B into C at this point.
@@ -482,8 +500,7 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
482500
// be negative and don't wrap.
483501
FixedValue = 0;
484502

485-
unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup);
486-
assert(SymA);
503+
unsigned Type = TargetObjectWriter->getRelocType(Target, Fixup, IsLocRel);
487504

488505
// Absolute offset within a section or a function.
489506
// Currently only supported for for metadata sections.
@@ -613,7 +630,8 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
613630
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
614631
case wasm::R_WASM_MEMORY_ADDR_I32:
615632
case wasm::R_WASM_MEMORY_ADDR_I64:
616-
case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: {
633+
case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
634+
case wasm::R_WASM_MEMORY_ADDR_SELFREL_I32: {
617635
// Provisional value is address of the global plus the offset
618636
const MCSymbolWasm *Base =
619637
cast<MCSymbolWasm>(Layout.getBaseSymbol(*RelEntry.Symbol));
@@ -712,6 +730,7 @@ void WasmObjectWriter::applyRelocations(
712730
case wasm::R_WASM_FUNCTION_OFFSET_I32:
713731
case wasm::R_WASM_SECTION_OFFSET_I32:
714732
case wasm::R_WASM_GLOBAL_INDEX_I32:
733+
case wasm::R_WASM_MEMORY_ADDR_SELFREL_I32:
715734
patchI32(Stream, Value, Offset);
716735
break;
717736
case wasm::R_WASM_TABLE_INDEX_I64:

llvm/lib/Object/RelocationResolver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ static bool supportsWasm32(uint64_t Type) {
575575
case wasm::R_WASM_EVENT_INDEX_LEB:
576576
case wasm::R_WASM_GLOBAL_INDEX_I32:
577577
case wasm::R_WASM_TABLE_NUMBER_LEB:
578+
case wasm::R_WASM_MEMORY_ADDR_SELFREL_I32:
578579
return true;
579580
default:
580581
return false;
@@ -611,6 +612,7 @@ static uint64_t resolveWasm32(uint64_t Type, uint64_t Offset, uint64_t S,
611612
case wasm::R_WASM_EVENT_INDEX_LEB:
612613
case wasm::R_WASM_GLOBAL_INDEX_I32:
613614
case wasm::R_WASM_TABLE_NUMBER_LEB:
615+
case wasm::R_WASM_MEMORY_ADDR_SELFREL_I32:
614616
// For wasm section, its offset at 0 -- ignoring Value
615617
return LocData;
616618
default:

llvm/lib/Object/WasmObjectFile.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
903903
case wasm::R_WASM_MEMORY_ADDR_I32:
904904
case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
905905
case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
906+
case wasm::R_WASM_MEMORY_ADDR_SELFREL_I32:
906907
if (!isValidDataSymbol(Reloc.Index))
907908
return make_error<GenericBinaryError>("Bad relocation data index",
908909
object_error::parse_failed);
@@ -951,6 +952,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
951952
Size = 10;
952953
if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
953954
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
955+
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SELFREL_I32 ||
954956
Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
955957
Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
956958
Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)

llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
3434
explicit WebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten);
3535

3636
private:
37-
unsigned getRelocType(const MCValue &Target,
38-
const MCFixup &Fixup) const override;
37+
unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup,
38+
bool IsLocRel) const override;
3939
};
4040
} // end anonymous namespace
4141

@@ -63,7 +63,8 @@ static const MCSection *getFixupSection(const MCExpr *Expr) {
6363
}
6464

6565
unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
66-
const MCFixup &Fixup) const {
66+
const MCFixup &Fixup,
67+
bool IsLocRel) const {
6768
const MCSymbolRefExpr *RefA = Target.getSymA();
6869
assert(RefA);
6970
auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol());
@@ -122,7 +123,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
122123
else if (!Section->isWasmData())
123124
return wasm::R_WASM_SECTION_OFFSET_I32;
124125
}
125-
return wasm::R_WASM_MEMORY_ADDR_I32;
126+
return IsLocRel ? wasm::R_WASM_MEMORY_ADDR_SELFREL_I32
127+
: wasm::R_WASM_MEMORY_ADDR_I32;
126128
case FK_Data_8:
127129
if (SymA.isFunction())
128130
return wasm::R_WASM_TABLE_INDEX_I64;

0 commit comments

Comments
 (0)