diff --git a/lld/test/wasm/check-arch-32-in-64.test b/lld/test/wasm/check-arch-32-in-64.test new file mode 100644 --- /dev/null +++ b/lld/test/wasm/check-arch-32-in-64.test @@ -0,0 +1,4 @@ +RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/start.s -o %t.o +RUN: not wasm-ld -mwasm64 %t.o -o %t.wasm 2>&1 | FileCheck %s + +CHECK: wasm32 object file can't be linked in wasm64 mode diff --git a/lld/test/wasm/check-arch-64-in-32.test b/lld/test/wasm/check-arch-64-in-32.test new file mode 100644 --- /dev/null +++ b/lld/test/wasm/check-arch-64-in-32.test @@ -0,0 +1,4 @@ +RUN: llvm-mc -filetype=obj -triple=wasm64-unknown-unknown %p/Inputs/start.s -o %t.o +RUN: not wasm-ld %t.o -o %t.wasm 2>&1 | FileCheck %s + +CHECK: must specify -mwasm64 to process wasm64 object files diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -60,6 +60,7 @@ for (const WasmRelocation &rel : relocations) { uint64_t existingValue; unsigned bytesRead = 0; + unsigned paddedLEBWidth = 5; auto offset = rel.Offset - getInputSectionOffset(); const uint8_t *loc = data().data() + offset; switch (rel.Type) { @@ -68,17 +69,23 @@ case R_WASM_GLOBAL_INDEX_LEB: case R_WASM_EVENT_INDEX_LEB: case R_WASM_MEMORY_ADDR_LEB: + existingValue = decodeULEB128(loc, &bytesRead); + break; case R_WASM_MEMORY_ADDR_LEB64: existingValue = decodeULEB128(loc, &bytesRead); + paddedLEBWidth = 10; break; case R_WASM_TABLE_INDEX_SLEB: - case R_WASM_TABLE_INDEX_SLEB64: case R_WASM_TABLE_INDEX_REL_SLEB: case R_WASM_MEMORY_ADDR_SLEB: - case R_WASM_MEMORY_ADDR_SLEB64: case R_WASM_MEMORY_ADDR_REL_SLEB: + existingValue = static_cast(decodeSLEB128(loc, &bytesRead)); + break; + case R_WASM_TABLE_INDEX_SLEB64: + case R_WASM_MEMORY_ADDR_SLEB64: case R_WASM_MEMORY_ADDR_REL_SLEB64: existingValue = static_cast(decodeSLEB128(loc, &bytesRead)); + paddedLEBWidth = 10; break; case R_WASM_TABLE_INDEX_I32: case R_WASM_MEMORY_ADDR_I32: @@ -95,8 +102,8 @@ llvm_unreachable("unknown relocation type"); } - if (bytesRead && bytesRead != 5) - warn("expected LEB at relocation site be 5-byte padded"); + if (bytesRead && bytesRead != paddedLEBWidth) + warn("expected LEB at relocation site be 5/10-byte padded"); if (rel.Type != R_WASM_GLOBAL_INDEX_LEB && rel.Type != R_WASM_GLOBAL_INDEX_I32) { diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -13,6 +13,7 @@ #include "lld/Common/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Triple.h" #include "llvm/LTO/LTO.h" #include "llvm/Object/Archive.h" #include "llvm/Object/Wasm.h" @@ -68,6 +69,9 @@ protected: InputFile(Kind k, MemoryBufferRef m) : mb(m), fileKind(k), live(!config->gcSections) {} + + void checkArch(llvm::Triple::ArchType arch) const; + MemoryBufferRef mb; // List of all symbols referenced or defined by this file. diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -40,6 +40,18 @@ } namespace wasm { + +void InputFile::checkArch(Triple::ArchType arch) const { + bool is64 = arch == Triple::wasm64; + if (is64 && !config->is64.hasValue()) { + fatal(toString(this) + + ": must specify -mwasm64 to process wasm64 object files"); + } else if (config->is64.getValueOr(false) != is64) { + fatal(toString(this) + + ": wasm32 object file can't be linked in wasm64 mode"); + } +} + std::unique_ptr tar; Optional readFile(StringRef path) { @@ -286,6 +298,8 @@ bin.release(); wasmObj.reset(obj); + checkArch(obj->getArch()); + // Build up a map of function indices to table indices for use when // verifying the existing table index relocations uint32_t totalFunctions = @@ -583,12 +597,7 @@ error(toString(this) + ": machine type must be wasm32 or wasm64"); return; } - bool is64 = t.getArch() == Triple::wasm64; - if (config->is64.hasValue() && *config->is64 != is64) { - error(toString(this) + ": machine type for all bitcode files must match"); - return; - } - config->is64 = is64; + checkArch(t.getArch()); std::vector keptComdats; for (StringRef s : obj->getComdatTable()) keptComdats.push_back(symtab->addComdat(s));