mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 08:02:08 +00:00
[WebAssembly] Write out undefined symbol addresses as zero
The addresses of undefined symbols that make it into the final executable (i.e. weak references to non-existent symbols) should resolve to zero. Also, make sure to not include function in the indirect function table if they are not included in the output. Differential Revision: https://reviews.llvm.org/D41839 llvm-svn: 322045
This commit is contained in:
parent
0f03c79b6d
commit
87e61923a4
@ -159,7 +159,7 @@ declare i32 @foo_import() local_unnamed_addr
|
||||
; CHECK-NEXT: Offset:
|
||||
; CHECK-NEXT: Opcode: I32_CONST
|
||||
; CHECK-NEXT: Value: 16
|
||||
; CHECK-NEXT: Content: FFFFFFFF
|
||||
; CHECK-NEXT: Content: '00000000'
|
||||
; CHECK-NEXT: - Type: CUSTOM
|
||||
; CHECK-NEXT: Name: linking
|
||||
; CHECK-NEXT: DataSize: 20
|
||||
|
@ -40,8 +40,8 @@ entry:
|
||||
; CHECK-NEXT: - ElemType: ANYFUNC
|
||||
; CHECK-NEXT: Limits:
|
||||
; CHECK-NEXT: Flags: [ HAS_MAX ]
|
||||
; CHECK-NEXT: Initial: 0x00000002
|
||||
; CHECK-NEXT: Maximum: 0x00000002
|
||||
; CHECK-NEXT: Initial: 0x00000001
|
||||
; CHECK-NEXT: Maximum: 0x00000001
|
||||
; CHECK-NEXT: - Type: MEMORY
|
||||
; CHECK-NEXT: Memories:
|
||||
; CHECK-NEXT: - Initial: 0x00000002
|
||||
@ -66,20 +66,14 @@ entry:
|
||||
; CHECK-NEXT: - Name: get_address_of_global_var
|
||||
; CHECK-NEXT: Kind: FUNCTION
|
||||
; CHECK-NEXT: Index: 1
|
||||
; CHECK-NEXT: - Type: ELEM
|
||||
; CHECK-NEXT: Segments:
|
||||
; CHECK-NEXT: - Offset:
|
||||
; CHECK-NEXT: Opcode: I32_CONST
|
||||
; CHECK-NEXT: Value: 1
|
||||
; CHECK-NEXT: Functions: [ 0 ]
|
||||
; CHECK-NEXT: - Type: CODE
|
||||
; CHECK-NEXT: Functions:
|
||||
; CHECK-NEXT: - Locals:
|
||||
; CHECK-NEXT: Body: 4181808080000B
|
||||
; CHECK-NEXT: Body: 4180808080000B
|
||||
; CHECK-NEXT: - Locals:
|
||||
; CHECK-NEXT: Body: 41FFFFFFFF7F0B
|
||||
; CHECK-NEXT: Body: 4180808080000B
|
||||
; CHECK-NEXT: - Locals:
|
||||
; CHECK-NEXT: Body: 41002802FFFFFFFF0F0B
|
||||
; CHECK-NEXT: Body: 4100280280808080000B
|
||||
; CHECK-NEXT: - Type: CUSTOM
|
||||
; CHECK-NEXT: Name: linking
|
||||
; CHECK-NEXT: DataSize: 0
|
@ -83,7 +83,7 @@ uint32_t ObjFile::relocateTypeIndex(uint32_t Original) const {
|
||||
|
||||
uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
||||
Symbol *Sym = getTableSymbol(Original);
|
||||
uint32_t Index = Sym->getTableIndex();
|
||||
uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0;
|
||||
DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original
|
||||
<< " -> " << Index << "\n");
|
||||
return Index;
|
||||
@ -91,7 +91,7 @@ uint32_t ObjFile::relocateTableIndex(uint32_t Original) const {
|
||||
|
||||
uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const {
|
||||
Symbol *Sym = getGlobalSymbol(Original);
|
||||
uint32_t Index = Sym->getOutputIndex();
|
||||
uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0;
|
||||
DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original
|
||||
<< " -> " << Index << "\n");
|
||||
return Index;
|
||||
|
@ -157,16 +157,12 @@ static void calcRelocations(const ObjFile &File,
|
||||
|
||||
if (Config->EmitRelocs)
|
||||
NewReloc.NewIndex = calcNewIndex(File, Reloc);
|
||||
else
|
||||
NewReloc.NewIndex = UINT32_MAX;
|
||||
|
||||
switch (Reloc.Type) {
|
||||
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
|
||||
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
|
||||
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
|
||||
NewReloc.Value = File.getRelocatedAddress(Reloc.Index);
|
||||
if (NewReloc.Value != UINT32_MAX)
|
||||
NewReloc.Value += Reloc.Addend;
|
||||
NewReloc.Value = File.getRelocatedAddress(Reloc.Index) + Reloc.Addend;
|
||||
break;
|
||||
default:
|
||||
NewReloc.Value = calcNewIndex(File, Reloc);
|
||||
|
@ -40,7 +40,7 @@ uint32_t Symbol::getVirtualAddress() const {
|
||||
assert(isGlobal());
|
||||
DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n");
|
||||
if (isUndefined())
|
||||
return UINT32_MAX;
|
||||
return 0;
|
||||
if (VirtualAddress.hasValue())
|
||||
return VirtualAddress.getValue();
|
||||
|
||||
@ -53,12 +53,6 @@ uint32_t Symbol::getVirtualAddress() const {
|
||||
return Segment->translateVA(Global.InitExpr.Value.Int32);
|
||||
}
|
||||
|
||||
uint32_t Symbol::getOutputIndex() const {
|
||||
if (isUndefined() && isWeak())
|
||||
return 0;
|
||||
return OutputIndex.getValue();
|
||||
}
|
||||
|
||||
void Symbol::setVirtualAddress(uint32_t Value) {
|
||||
DEBUG(dbgs() << "setVirtualAddress " << Name << " -> " << Value << "\n");
|
||||
assert(!VirtualAddress.hasValue());
|
||||
|
@ -71,23 +71,28 @@ public:
|
||||
|
||||
bool hasFunctionType() const { return FunctionType != nullptr; }
|
||||
const WasmSignature &getFunctionType() const;
|
||||
uint32_t getOutputIndex() const;
|
||||
uint32_t getTableIndex() const { return TableIndex.getValue(); }
|
||||
|
||||
// Returns the virtual address of a defined global.
|
||||
// Only works for globals, not functions.
|
||||
uint32_t getVirtualAddress() const;
|
||||
uint32_t getOutputIndex() const { return OutputIndex.getValue(); }
|
||||
|
||||
// Returns true if an output index has been set for this symbol
|
||||
bool hasOutputIndex() const { return OutputIndex.hasValue(); }
|
||||
|
||||
// Set the output index of the symbol (in the function or global index
|
||||
// space of the output object.
|
||||
void setOutputIndex(uint32_t Index);
|
||||
|
||||
uint32_t getTableIndex() const { return TableIndex.getValue(); }
|
||||
|
||||
// Returns true if a table index has been set for this symbol
|
||||
bool hasTableIndex() const { return TableIndex.hasValue(); }
|
||||
|
||||
// Set the table index of the symbol
|
||||
void setTableIndex(uint32_t Index);
|
||||
|
||||
// Returns the virtual address of a defined global.
|
||||
// Only works for globals, not functions.
|
||||
uint32_t getVirtualAddress() const;
|
||||
|
||||
void setVirtualAddress(uint32_t VA);
|
||||
|
||||
void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr,
|
||||
|
@ -629,12 +629,14 @@ void Writer::assignSymbolIndexes() {
|
||||
Sym->setOutputIndex(GlobalIndex++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ObjFile *File : Symtab->ObjectFiles) {
|
||||
for (Symbol *Sym : File->getTableSymbols()) {
|
||||
if (!Sym->hasTableIndex()) {
|
||||
Sym->setTableIndex(TableIndex++);
|
||||
IndirectFunctions.emplace_back(Sym);
|
||||
}
|
||||
if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
|
||||
continue;
|
||||
Sym->setTableIndex(TableIndex++);
|
||||
IndirectFunctions.emplace_back(Sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user