[lld][WebAssembly] Handle TLS variables in Symbol::getVA. NFC

In the shared memory case we can always assume that TLS addresses
are relative to __tls_base.  In the non-shared memory case TLS
variables are absolute, just like normal data addresses.

This simplifies the code in calcNewValue so that TLS relocations
no longer need special handling.

Differential Revision: https://reviews.llvm.org/D112831
This commit is contained in:
Sam Clegg 2021-10-29 09:13:40 -07:00
parent 33cc0cfd46
commit fad05465c1
2 changed files with 7 additions and 14 deletions

View File

@ -169,18 +169,12 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
case R_WASM_MEMORY_ADDR_REL_SLEB64:
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_MEMORY_ADDR_TLS_SLEB:
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
case R_WASM_MEMORY_ADDR_LOCREL_I32: {
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
return 0;
auto D = cast<DefinedData>(sym);
// Treat non-TLS relocation against symbols that live in the TLS segment
// like TLS relocations. This behaviour exists to support older object
// files created before we introduced TLS relocations.
// TODO(sbc): Remove this legacy behaviour one day. This will break
// backward compat with old object files built with `-fPIC`.
if (D->segment && D->segment->outputSeg->isTLS())
return D->getOutputSegmentOffset() + reloc.Addend;
uint64_t value = D->getVA() + reloc.Addend;
if (reloc.Type == R_WASM_MEMORY_ADDR_LOCREL_I32) {
const auto *segment = cast<InputSegment>(chunk);
@ -190,12 +184,6 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc, uint64_t tombstone,
}
return value;
}
case R_WASM_MEMORY_ADDR_TLS_SLEB:
case R_WASM_MEMORY_ADDR_TLS_SLEB64:
if (isa<UndefinedData>(sym) || sym->isUndefWeak())
return 0;
// TLS relocations are relative to the start of the TLS output segment
return cast<DefinedData>(sym)->getOutputSegmentOffset() + reloc.Addend;
case R_WASM_TYPE_INDEX_LEB:
return typeMap[reloc.Index];
case R_WASM_FUNCTION_INDEX_LEB:

View File

@ -305,6 +305,11 @@ uint32_t DefinedFunction::getExportedFunctionIndex() const {
uint64_t DefinedData::getVA() const {
LLVM_DEBUG(dbgs() << "getVA: " << getName() << "\n");
// In the shared memory case, TLS symbols are relative to the start of the TLS
// output segment (__tls_base). When building without shared memory, TLS
// symbols absolute, just like non-TLS.
if (isTLS() && config->sharedMemory)
return getOutputSegmentOffset() + value;
if (segment)
return segment->getVA(value);
return value;