diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -161,21 +161,11 @@ if ((isa(Sym) || isa(Sym)) && !Sym->isLive()) return 0; - // Special handling for undefined data symbols. Most relocations against - // such symbols cannot be resolved. - if (isa(Sym) && Sym->isUndefined()) { - if (Sym->isWeak() || Config->Relocatable) - return 0; - // R_WASM_MEMORY_ADDR_I32 relocations in PIC code are turned into runtime - // fixups in __wasm_apply_relocs - if (Config->Pic && Reloc.Type == R_WASM_MEMORY_ADDR_I32) - return 0; - if (Reloc.Type != R_WASM_GLOBAL_INDEX_LEB) { - llvm_unreachable( - ("invalid relocation against undefined data symbol: " + toString(*Sym)) - .c_str()); - } - } + // Special handling for undefined data symbols. For weak symbols or for + // data relocations in PIC mode writing zero is the correct behaviour. For + // other cases, an error will have been reported during scanRelocations. + if (isa(Sym) && Sym->isUndefined()) + return 0; } switch (Reloc.Type) { diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp --- a/lld/wasm/Relocations.cpp +++ b/lld/wasm/Relocations.cpp @@ -50,16 +50,16 @@ if (!isa(Sym)) Out.ImportSec->addGOTEntry(Sym); break; - case R_WASM_MEMORY_ADDR_SLEB: - case R_WASM_MEMORY_ADDR_LEB: - case R_WASM_MEMORY_ADDR_REL_SLEB: - if (!Config->Relocatable && Sym->isUndefined() && !Sym->isWeak()) { + } + + // Handle undefined data symbols. + // For non-weak symbols this is normally an error except in the PIC case + // where we can generate runtime relocations for R_WASM_MEMORY_ADDR_I32. + if (isa(Sym) && !Config->Relocatable && !Sym->isWeak()) + if (!(Config->Pic && Reloc.Type == R_WASM_MEMORY_ADDR_I32)) error(toString(File) + ": cannot resolve relocation of type " + relocTypeToString(Reloc.Type) + " against undefined (non-weak) data symbol: " + toString(*Sym)); - } - break; - } if (Config->Pic) { switch (Reloc.Type) {