From 5d777693816b92c92ba24ab6f297eb267ccc521e Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Wed, 27 Feb 2019 17:21:20 -0800 Subject: [PATCH] Hopefully finish the memory manager implementation for llvm RuntimeDyLd --- Cargo.lock | 50 ++++----- lib/llvm-backend/build.rs | 1 + lib/llvm-backend/cpp/object_loader.cpp | 122 ++++++++++++++++++---- lib/llvm-backend/src/code.rs | 2 +- lib/llvm-backend/src/platform/mod.rs | 8 ++ lib/llvm-backend/src/platform/unix/mod.rs | 40 +++++++ 6 files changed, 176 insertions(+), 47 deletions(-) create mode 100644 lib/llvm-backend/src/platform/mod.rs create mode 100644 lib/llvm-backend/src/platform/unix/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 9d743e96c..566a1514b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,7 +63,7 @@ dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -136,7 +136,7 @@ name = "cexpr" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 4.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -269,7 +269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dlopen_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -431,7 +431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "inkwell" version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#e66f8941061a45299ef73533c747c32bcd5d696a" +source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#b8699b0ee594e4162ce850fbedb37892e9cdb7e4" dependencies = [ "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -443,7 +443,7 @@ dependencies = [ [[package]] name = "inkwell_internal_macros" version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#e66f8941061a45299ef73533c747c32bcd5d696a" +source = "git+https://github.com/TheDan64/inkwell?branch=llvm7-0#b8699b0ee594e4162ce850fbedb37892e9cdb7e4" dependencies = [ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", @@ -465,13 +465,13 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" version = "0.2.49" -source = "git+https://github.com/rust-lang/libc#68701e7e673da580de8ba6197c544316bd38e84a" +source = "git+https://github.com/rust-lang/libc#b905aef34008c962ef8a4410216eae65bbb7f68f" [[package]] name = "libc" @@ -496,7 +496,7 @@ dependencies = [ "goblin 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "inkwell 0.1.0 (git+https://github.com/TheDan64/inkwell?branch=llvm7-0)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -512,7 +512,7 @@ version = "70.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -575,7 +575,7 @@ dependencies = [ [[package]] name = "nom" -version = "4.2.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -691,7 +691,7 @@ dependencies = [ "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -759,11 +759,11 @@ dependencies = [ [[package]] name = "rand_pcg" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -907,7 +907,7 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1082,7 +1082,7 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1201,7 +1201,7 @@ dependencies = [ "nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-runtime-core 0.1.2", @@ -1216,7 +1216,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.49 (git+https://github.com/rust-lang/libc)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1229,7 +1229,7 @@ dependencies = [ name = "wasmer-runtime" version = "0.1.4" dependencies = [ - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.1.2", "wasmer-runtime-core 0.1.2", @@ -1254,14 +1254,14 @@ dependencies = [ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasmer-clif-backend 0.1.2", @@ -1415,7 +1415,7 @@ dependencies = [ "checksum inkwell_internal_macros 0.1.0 (git+https://github.com/TheDan64/inkwell?branch=llvm7-0)" = "" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.49 (git+https://github.com/rust-lang/libc)" = "" "checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" @@ -1426,7 +1426,7 @@ dependencies = [ "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f" "checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b" -"checksum nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b30adc557058ce00c9d0d7cb3c6e0b5bc6f36e2e2eabe74b0ba726d194abd588" +"checksum nom 4.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4836e9d6036552017e107edc598c97b2dee245161ff1b1ad4af215004774b354" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242" @@ -1448,7 +1448,7 @@ dependencies = [ "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" "checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" -"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "30a9d219c32c9132f7be513c18be77c9881c7107d2ab5569d205a6a0f0e6dc7d" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" @@ -1467,7 +1467,7 @@ dependencies = [ "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" "checksum serde-bench 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d733da87e79faaac25616e33d26299a41143fd4cd42746cbb0e91d8feea243fd" -"checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" +"checksum serde_bytes 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "defbb8a83d7f34cc8380751eeb892b825944222888aff18996ea7901f24aec88" "checksum serde_derive 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ac38f51a52a556cd17545798e29536885fb1a3fa63d6399f5ef650f4a7d35901" "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" diff --git a/lib/llvm-backend/build.rs b/lib/llvm-backend/build.rs index 0f4d1f195..33ce4525d 100644 --- a/lib/llvm-backend/build.rs +++ b/lib/llvm-backend/build.rs @@ -49,6 +49,7 @@ lazy_static! { use std::io::Read; let mut s = String::new(); file.read_to_string(&mut s).unwrap(); + s.truncate(s.len() - 4); Some(s) } else { None diff --git a/lib/llvm-backend/cpp/object_loader.cpp b/lib/llvm-backend/cpp/object_loader.cpp index 9ab36f4c3..52625b64b 100644 --- a/lib/llvm-backend/cpp/object_loader.cpp +++ b/lib/llvm-backend/cpp/object_loader.cpp @@ -1,19 +1,35 @@ #include "object_loader.hh" #include #include +#include -class MemoryManager : llvm::RuntimeDyld::MemoryManager { +struct MemoryManager : llvm::RuntimeDyld::MemoryManager { public: - MemoryManager() {} + MemoryManager(callbacks_t *callbacks) : callbacks(callbacks) {} - virtual ~MemoryManager() {} - - virtual uint8_t* allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName) override { - return nullptr; + virtual ~MemoryManager() { + // Deallocate all of the allocated memory. + callbacks->dealloc_memory(code_section.base, code_section.size); + callbacks->dealloc_memory(read_section.base, read_section.size); + callbacks->dealloc_memory(readwrite_section.base, readwrite_section.size); } - virtual uint8_t* allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool isReadOnly) override { - return nullptr; + virtual uint8_t* allocateCodeSection(uintptr_t size, unsigned alignment, unsigned section_id, llvm::StringRef section_name) override { + std::cout << "code section name: " << (std::string)section_name << std::endl; + + return allocate_bump(code_section, code_bump_ptr, size, alignment); + } + + virtual uint8_t* allocateDataSection(uintptr_t size, unsigned alignment, unsigned section_id, llvm::StringRef section_name, bool read_only) override { + std::cout << "data section name: " << (std::string)section_name << std::endl; + + // Allocate from the read-only section or the read-write section, depending on if this allocation + // should be read-only or not. + if (read_only) { + return allocate_bump(read_section, read_bump_ptr, size, alignment); + } else { + return allocate_bump(readwrite_section, readwrite_bump_ptr, size, alignment); + } } virtual void reserveAllocationSpace( @@ -24,7 +40,20 @@ public: uintptr_t read_write_data_size, uint32_t read_write_data_align ) override { - + uint8_t *ptr_out = nullptr; + size_t size_out = 0; + + auto code_result = callbacks->alloc_memory(code_size, PROTECT_READ_WRITE, &ptr_out, &size_out); + code_section = Section { ptr_out, size_out }; + code_bump_ptr = (uintptr_t)ptr_out; + + auto read_result = callbacks->alloc_memory(read_data_size, PROTECT_READ_WRITE, &ptr_out, &size_out); + read_section = Section { ptr_out, size_out }; + read_bump_ptr = (uintptr_t)ptr_out; + + auto readwrite_result = callbacks->alloc_memory(read_write_data_size, PROTECT_READ_WRITE, &ptr_out, &size_out); + readwrite_section = Section { ptr_out, size_out }; + readwrite_bump_ptr = (uintptr_t)ptr_out; } /* Turn on the `reserveAllocationSpace` callback. */ @@ -33,38 +62,59 @@ public: } virtual void registerEHFrames(uint8_t* Addr, uint64_t LoadAddr, size_t Size) override { - + std::cout << "should register eh frames" << std::endl; } virtual void deregisterEHFrames() override { - + std::cout << "should deregister eh frames" << std::endl; } virtual bool finalizeMemory(std::string *ErrMsg = nullptr) override { - + auto code_result = callbacks->protect_memory(code_section.base, code_section.size, mem_protect_t::PROTECT_READ_EXECUTE); + if (code_result != RESULT_OK) { + return false; + } + + auto read_result = callbacks->protect_memory(read_section.base, read_section.size, mem_protect_t::PROTECT_READ); + if (read_result != RESULT_OK) { + return false; + } + + // The readwrite section is already mapped as read-write. return false; } - virtual void notifyObjectLoaded(llvm::RuntimeDyld &RTDyld, const llvm::object::ObjectFile &Obj) override { - - } + virtual void notifyObjectLoaded(llvm::RuntimeDyld &RTDyld, const llvm::object::ObjectFile &Obj) override {} private: struct Section { uint8_t* base; - size_t num_pages; - size_t num_commited_bytes; + size_t size; }; - uint8_t *image_base; - size_t num_allocated_pages; + uint8_t* allocate_bump(Section& section, uintptr_t& bump_ptr, size_t size, size_t align) { + auto aligner = [](uintptr_t& ptr, size_t align) { + ptr = (ptr + align - 1) & ~(align - 1); + }; + + // Align the bump pointer to the requires alignment. + aligner(bump_ptr, align); + + auto ret_ptr = bump_ptr; + bump_ptr += size; + + assert(bump_ptr <= (uintptr_t)section.base + section.size); + + return (uint8_t*)ret_ptr; + } Section code_section, read_section, readwrite_section; + uintptr_t code_bump_ptr, read_bump_ptr, readwrite_bump_ptr; - + callbacks_t *callbacks; }; -class SymbolLookup : llvm::JITSymbolResolver { +struct SymbolLookup : llvm::JITSymbolResolver { public: virtual llvm::Expected lookup(const LookupSet& symbols) override { LookupResult result; @@ -93,4 +143,34 @@ private: return llvm::JITEvaluatedSymbol(addr, llvm::JITSymbolFlags::None); } +}; + +class WasmModule { +public: + WasmModule( + const uint8_t *object_start, + size_t object_size, + callbacks_t *callbacks + + ) : memory_manager(std::unique_ptr(new MemoryManager(callbacks))) { + object_file = llvm::cantFail(llvm::object::ObjectFile::createObjectFile(llvm::MemoryBufferRef( + llvm::StringRef((const char *)object_start, object_size), "object" + ))); + + SymbolLookup symbol_resolver; + llvm::RuntimeDyld loader(*memory_manager, symbol_resolver); + + loader.setProcessAllSections(true); + + auto loaded_object_info = loader.loadObject(*object_file); + loader.finalizeWithMemoryManagerLocking(); + + assert(!loader.hasError()); + + + + } +private: + std::unique_ptr memory_manager; + std::unique_ptr object_file; }; \ No newline at end of file diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index e0f4d984f..b0e8f2912 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -616,7 +616,7 @@ fn parse_function( let struct_value = basic_value.into_struct_value(); for i in 0..(count as u32) { let value = - builder.build_extract_value(struct_value, i, &state.var_name()); + builder.build_extract_value(struct_value, i, &state.var_name()).unwrap(); state.push1(value); } } diff --git a/lib/llvm-backend/src/platform/mod.rs b/lib/llvm-backend/src/platform/mod.rs new file mode 100644 index 000000000..bcc0378c2 --- /dev/null +++ b/lib/llvm-backend/src/platform/mod.rs @@ -0,0 +1,8 @@ + +#[cfg(target_family = "unix")] +mod unix; +#[cfg(target_family = "unix")] +pub use self::unix::*; + +#[cfg(target_family = "windows")] +compile_error!("windows not yet supported for the llvm-based compiler backend"); \ No newline at end of file diff --git a/lib/llvm-backend/src/platform/unix/mod.rs b/lib/llvm-backend/src/platform/unix/mod.rs new file mode 100644 index 000000000..c0e86f7ef --- /dev/null +++ b/lib/llvm-backend/src/platform/unix/mod.rs @@ -0,0 +1,40 @@ + +extern "C" { + fn __register_frame(frame: *const u8); + fn __deregister_frame(frame: *const u8); +} + +pub unsafe fn register_eh_frames(eh_frames: *const u8, num_bytes: usize) { + visit_frame_desc_entries(eh_frames, num_bytes, |frame| __register_frame(frame)); +} + +unsafe fn visit_frame_desc_entries(eh_frames: *const u8, num_bytes: usize, visitor: F) +where + F: Fn(*const u8), +{ + let mut next = eh_frames; + let mut end = eh_frames.add(num_bytes); + + loop { + if next >= end { + break; + } + + let cfi = next; + let mut cfi_num_bytes = (next as *const u32).read_unaligned() as u64; + assert!(cfi_num_bytes != 0); + + next = next.add(4); + if num_bytes == 0xffffffff { + let cfi_num_bytes64 = (next as *const u64).read_unaligned(); + cfi_num_bytes = cfi_num_bytes64; + next = next.add(8); + } + + let cie_offset = (next as *const u32).read_unaligned(); + if cie_offset != 0 { + visitor(cfi); + } + next = next.add(cfi_num_bytes as usize); + } +}