Skip to content

Commit 60ec303

Browse files
committedJan 23, 2018
[WebAssembly] Store function index rather than table index in TABLE_INDEX relocations
Relocations of type R_WEBASSEMBLY_TABLE_INDEX represent places where the table index for a given function is needed. While the value stored in this location is a table index, the index in the relocation entry itself is a function index (the index of the function which is to be called indirectly). This is how is was spec'd originally but the LLVM implementation didn't do this. This makes things a little simpler in the linker since the table in the input file can essentially be ignored that the output table can be created purely based on these relocations. Patch by Nicholas Wilson! Differential Revision: https://reviews.llvm.org/D42080 llvm-svn: 323165
1 parent 4ce341f commit 60ec303

File tree

5 files changed

+58
-64
lines changed

5 files changed

+58
-64
lines changed
 

‎llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 53 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -499,25 +499,44 @@ static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) {
499499
}
500500

501501
// Compute a value to write into the code at the location covered
502-
// by RelEntry. This value isn't used by the static linker, since
503-
// we have addends; it just serves to make the code more readable
504-
// and to make standalone wasm modules directly usable.
502+
// by RelEntry. This value isn't used by the static linker; it just serves
503+
// to make the object format more readable and more likely to be directly
504+
// useable.
505505
uint32_t
506506
WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
507-
const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol);
508507

509-
// For undefined symbols, use zero
510-
if (!Sym->isDefined())
511-
return 0;
512-
513-
uint32_t GlobalIndex = SymbolIndices[Sym];
514-
const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports];
515-
uint64_t Address = Global.InitialValue + RelEntry.Addend;
516-
517-
// Ignore overflow. LLVM allows address arithmetic to silently wrap.
518-
uint32_t Value = Address;
519-
520-
return Value;
508+
switch (RelEntry.Type) {
509+
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
510+
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
511+
// Provitional value is the indirect symbol index
512+
if (!IndirectSymbolIndices.count(RelEntry.Symbol))
513+
report_fatal_error("symbol not found in table index space: " +
514+
RelEntry.Symbol->getName());
515+
return IndirectSymbolIndices[RelEntry.Symbol];
516+
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
517+
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
518+
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
519+
// Provitional value is function/type/global index itself
520+
return getRelocationIndexValue(RelEntry);
521+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
522+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
523+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
524+
// Provitional value is address of the global
525+
const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol);
526+
// For undefined symbols, use zero
527+
if (!Sym->isDefined())
528+
return 0;
529+
530+
uint32_t GlobalIndex = SymbolIndices[Sym];
531+
const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports];
532+
uint64_t Address = Global.InitialValue + RelEntry.Addend;
533+
534+
// Ignore overflow. LLVM allows address arithmetic to silently wrap.
535+
return Address;
536+
}
537+
default:
538+
llvm_unreachable("invalid relocation type");
539+
}
521540
}
522541

523542
static void addData(SmallVectorImpl<char> &DataBytes,
@@ -564,32 +583,19 @@ static void addData(SmallVectorImpl<char> &DataBytes,
564583
DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
565584
}
566585

567-
uint32_t WasmObjectWriter::getRelocationIndexValue(
568-
const WasmRelocationEntry &RelEntry) {
569-
switch (RelEntry.Type) {
570-
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
571-
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
572-
if (!IndirectSymbolIndices.count(RelEntry.Symbol))
573-
report_fatal_error("symbol not found in table index space: " +
574-
RelEntry.Symbol->getName());
575-
return IndirectSymbolIndices[RelEntry.Symbol];
576-
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
577-
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
578-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
579-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
580-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
581-
if (!SymbolIndices.count(RelEntry.Symbol))
582-
report_fatal_error("symbol not found in function/global index space: " +
583-
RelEntry.Symbol->getName());
584-
return SymbolIndices[RelEntry.Symbol];
585-
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
586+
uint32_t
587+
WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
588+
if (RelEntry.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) {
586589
if (!TypeIndices.count(RelEntry.Symbol))
587590
report_fatal_error("symbol not found in type index space: " +
588591
RelEntry.Symbol->getName());
589592
return TypeIndices[RelEntry.Symbol];
590-
default:
591-
llvm_unreachable("invalid relocation type");
592593
}
594+
595+
if (!SymbolIndices.count(RelEntry.Symbol))
596+
report_fatal_error("symbol not found in function/global index space: " +
597+
RelEntry.Symbol->getName());
598+
return SymbolIndices[RelEntry.Symbol];
593599
}
594600

595601
// Apply the portions of the relocation records that we can handle ourselves
@@ -603,35 +609,23 @@ void WasmObjectWriter::applyRelocations(
603609
RelEntry.Offset;
604610

605611
DEBUG(dbgs() << "applyRelocation: " << RelEntry << "\n");
612+
uint32_t Value = getProvisionalValue(RelEntry);
613+
606614
switch (RelEntry.Type) {
607-
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
608615
case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
609616
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
610-
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: {
611-
uint32_t Index = getRelocationIndexValue(RelEntry);
612-
WritePatchableSLEB(Stream, Index, Offset);
613-
break;
614-
}
615-
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
616-
uint32_t Index = getRelocationIndexValue(RelEntry);
617-
WriteI32(Stream, Index, Offset);
618-
break;
619-
}
620-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
621-
uint32_t Value = getProvisionalValue(RelEntry);
622-
WritePatchableSLEB(Stream, Value, Offset);
623-
break;
624-
}
625-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: {
626-
uint32_t Value = getProvisionalValue(RelEntry);
617+
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
618+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
627619
WritePatchableLEB(Stream, Value, Offset);
628620
break;
629-
}
630-
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: {
631-
uint32_t Value = getProvisionalValue(RelEntry);
621+
case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
622+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
632623
WriteI32(Stream, Value, Offset);
633624
break;
634-
}
625+
case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
626+
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
627+
WritePatchableSLEB(Stream, Value, Offset);
628+
break;
635629
default:
636630
llvm_unreachable("invalid relocation type");
637631
}

‎llvm/test/MC/WebAssembly/external-func-address.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ declare void @f1(i32) #1
3434
; CHECK: - Type: DATA
3535
; CHECK-NEXT: Relocations:
3636
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
37-
; CHECK-NEXT: Index: 1
37+
; CHECK-NEXT: Index: 0
3838
; CHECK-NEXT: Offset: 0x00000006

‎llvm/test/MC/WebAssembly/func-address.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ entry:
4242
; CHECK: Relocation {
4343
; CHECK: Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1)
4444
; CHECK: Offset: 0x1E
45-
; CHECK: Index: 0x1
45+
; CHECK: Index: 0x2
4646
; CHECK: }
4747
; CHECK: }

‎llvm/test/MC/WebAssembly/global-ctor-dtor.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ declare void @func3()
9595
; CHECK-NEXT: Index: 0
9696
; CHECK-NEXT: Offset: 0x00000004
9797
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
98-
; CHECK-NEXT: Index: 1
98+
; CHECK-NEXT: Index: 5
9999
; CHECK-NEXT: Offset: 0x0000000F
100100
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
101101
; CHECK-NEXT: Index: 0
@@ -107,7 +107,7 @@ declare void @func3()
107107
; CHECK-NEXT: Index: 2
108108
; CHECK-NEXT: Offset: 0x0000002C
109109
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
110-
; CHECK-NEXT: Index: 2
110+
; CHECK-NEXT: Index: 7
111111
; CHECK-NEXT: Offset: 0x00000037
112112
; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
113113
; CHECK-NEXT: Index: 0

‎llvm/test/MC/WebAssembly/weak-alias.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ entry:
174174
; CHECK-NEXT: Index: 1
175175
; CHECK-NEXT: Offset: 0x0000000F
176176
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
177-
; CHECK-NEXT: Index: 2
177+
; CHECK-NEXT: Index: 0
178178
; CHECK-NEXT: Offset: 0x00000018
179179
; CHECK-NEXT: Segments:
180180
; CHECK-NEXT: - SectionOffset: 6

0 commit comments

Comments
 (0)
Please sign in to comment.