return Triple.getArch() == llvm::Triple::arm ||
Triple.getArch() == llvm::Triple::armeb ||
Triple.getArch() == llvm::Triple::thumb ||
- Triple.getArch() == llvm::Triple::thumbeb ||
- Triple.getArch() == llvm::Triple::wasm32 ||
- Triple.getArch() == llvm::Triple::wasm64;
+ Triple.getArch() == llvm::Triple::thumbeb || Triple.isWasm();
} else if (Model == "posix")
return true;
SanitizerKind::Nullability | SanitizerKind::LocalBounds;
if (getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64 ||
- getTriple().getArch() == llvm::Triple::arm ||
- getTriple().getArch() == llvm::Triple::wasm32 ||
- getTriple().getArch() == llvm::Triple::wasm64 || getTriple().isAArch64())
+ getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() ||
+ getTriple().isAArch64())
Res |= SanitizerKind::CFIICall;
if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().isAArch64())
Res |= SanitizerKind::ShadowCallStack;
bool importMemory;
bool sharedMemory;
bool importTable;
- bool is64;
+ llvm::Optional<bool> is64;
bool mergeDataSegments;
bool pie;
bool printGcSections;
args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
// Parse wasm32/64.
- config->is64 = false;
if (auto *arg = args.getLastArg(OPT_m)) {
StringRef s = arg->getValue();
if (s == "wasm32")
static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable,
int value) {
llvm::wasm::WasmGlobal wasmGlobal;
- if (config->is64) {
+ if (config->is64.getValueOr(false)) {
wasmGlobal.Type = {WASM_TYPE_I64, isMutable};
wasmGlobal.InitExpr.Value.Int64 = value;
wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I64_CONST;
if (config->isPic) {
- WasmSym::stackPointer = createUndefinedGlobal(
- "__stack_pointer",
- config->is64 ? &mutableGlobalTypeI64 : &mutableGlobalTypeI32);
+ WasmSym::stackPointer =
+ createUndefinedGlobal("__stack_pointer", config->is64.getValueOr(false)
+ ? &mutableGlobalTypeI64
+ : &mutableGlobalTypeI32);
// For PIC code, we import two global variables (__memory_base and
// __table_base) from the environment and use these as the offset at
// which to load our static data and function table.
// See:
// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
WasmSym::memoryBase = createUndefinedGlobal(
- "__memory_base", config->is64 ? &globalTypeI64 : &globalTypeI32);
+ "__memory_base",
+ config->is64.getValueOr(false) ? &globalTypeI64 : &globalTypeI32);
WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
WasmSym::memoryBase->markLive();
WasmSym::tableBase->markLive();
WasmSym::tlsAlign = createGlobalVariable("__tls_align", false, 1);
WasmSym::initTLS = symtab->addSyntheticFunction(
"__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
- make<SyntheticFunction>(config->is64 ? i64ArgSignature
- : i32ArgSignature,
- "__wasm_init_tls"));
+ make<SyntheticFunction>(
+ config->is64.getValueOr(false) ? i64ArgSignature : i32ArgSignature,
+ "__wasm_init_tls"));
}
}
LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName()
<< " count=" << relocations.size() << "\n");
- unsigned opcode_ptr_const =
- config->is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
- unsigned opcode_ptr_add =
- config->is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
+ unsigned opcode_ptr_const = config->is64.getValueOr(false)
+ ? WASM_OPCODE_I64_CONST
+ : WASM_OPCODE_I32_CONST;
+ unsigned opcode_ptr_add = config->is64.getValueOr(false)
+ ? WASM_OPCODE_I64_ADD
+ : WASM_OPCODE_I32_ADD;
// TODO(sbc): Encode the relocations in the data section and write a loop
// here to apply them.
obj = check(lto::InputFile::create(MemoryBufferRef(
mb.getBuffer(), saver.save(archiveName + mb.getBufferIdentifier()))));
Triple t(obj->getTargetTriple());
- if (t.getArch() != Triple::wasm32) {
- error(toString(this) + ": machine type must be wasm32");
+ if (!t.isWasm()) {
+ 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;
std::vector<bool> keptComdats;
for (StringRef s : obj->getComdatTable())
keptComdats.push_back(symtab->addComdat(s));
}
if (config->sharedMemory)
import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
- if (config->is64)
+ if (config->is64.getValueOr(false))
import.Memory.Flags |= WASM_LIMITS_FLAG_IS_64;
writeImport(os, import);
}
flags |= WASM_LIMITS_FLAG_HAS_MAX;
if (config->sharedMemory)
flags |= WASM_LIMITS_FLAG_IS_SHARED;
- if (config->is64)
+ if (config->is64.getValueOr(false))
flags |= WASM_LIMITS_FLAG_IS_64;
writeUleb128(os, flags, "memory limits flags");
writeUleb128(os, numMemoryPages, "initial pages");
if (WasmSym::heapBase)
WasmSym::heapBase->setVirtualAddress(memoryPtr);
- uint64_t maxMemorySetting = 1ULL << (config->is64 ? 48 : 32);
+ uint64_t maxMemorySetting = 1ULL
+ << (config->is64.getValueOr(false) ? 48 : 32);
if (config->initialMemory != 0) {
if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize))
bool HasLinkingSection = false;
bool HasDylinkSection = false;
bool SeenCodeSection = false;
+ bool HasMemory64 = false;
wasm::WasmLinkingData LinkingData;
uint32_t NumImportedGlobals = 0;
uint32_t NumImportedFunctions = 0;
break;
case wasm::WASM_EXTERNAL_MEMORY:
Im.Memory = readLimits(Ctx);
+ if (Im.Memory.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
+ HasMemory64 = true;
break;
case wasm::WASM_EXTERNAL_TABLE:
Im.Table = readTable(Ctx);
uint32_t Count = readVaruint32(Ctx);
Memories.reserve(Count);
while (Count--) {
- Memories.push_back(readLimits(Ctx));
+ auto Limits = readLimits(Ctx);
+ if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
+ HasMemory64 = true;
+ Memories.push_back(Limits);
}
if (Ctx.Ptr != Ctx.End)
return make_error<GenericBinaryError>("Memory section ended prematurely",
return section_iterator(SectionRef(Ref, this));
}
-uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }
+uint8_t WasmObjectFile::getBytesInAddress() const {
+ return HasMemory64 ? 8 : 4;
+}
StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
-Triple::ArchType WasmObjectFile::getArch() const { return Triple::wasm32; }
+Triple::ArchType WasmObjectFile::getArch() const {
+ return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
+}
SubtargetFeatures WasmObjectFile::getFeatures() const {
return SubtargetFeatures();