--- /dev/null
+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
--- /dev/null
+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
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) {
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<uint64_t>(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<uint64_t>(decodeSLEB128(loc, &bytesRead));
+ paddedLEBWidth = 10;
break;
case R_WASM_TABLE_INDEX_I32:
case R_WASM_MEMORY_ADDR_I32:
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) {
}
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<llvm::TarWriter> tar;
Optional<MemoryBufferRef> readFile(StringRef path) {
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 =
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<bool> keptComdats;
for (StringRef s : obj->getComdatTable())
keptComdats.push_back(symtab->addComdat(s));
#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"
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.