]> git.lizzy.rs Git - rust.git/commitdiff
Merge commit '61667dedf55e3e5aa584f7ae2bd0471336b92ce9' into sync_cg_clif-2021-09-19
authorbjorn3 <bjorn3@users.noreply.github.com>
Sun, 19 Sep 2021 11:56:58 +0000 (13:56 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Sun, 19 Sep 2021 11:56:58 +0000 (13:56 +0200)
23 files changed:
1  2 
compiler/rustc_codegen_cranelift/.gitignore
compiler/rustc_codegen_cranelift/Cargo.lock
compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
compiler/rustc_codegen_cranelift/build_system/prepare.rs
compiler/rustc_codegen_cranelift/clean_all.sh
compiler/rustc_codegen_cranelift/docs/usage.md
compiler/rustc_codegen_cranelift/example/alloc_example.rs
compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Disable-unsupported-tests.patch
compiler/rustc_codegen_cranelift/patches/0027-sysroot-128bit-atomic-operations.patch
compiler/rustc_codegen_cranelift/rust-toolchain
compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
compiler/rustc_codegen_cranelift/scripts/tests.sh
compiler/rustc_codegen_cranelift/src/archive.rs
compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs
compiler/rustc_codegen_cranelift/src/bin/cg_clif_build_sysroot.rs
compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs
compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
compiler/rustc_codegen_cranelift/src/debuginfo/object.rs
compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
compiler/rustc_codegen_cranelift/src/driver/aot.rs
compiler/rustc_codegen_cranelift/src/lib.rs
compiler/rustc_codegen_cranelift/src/metadata.rs

index 25080488a88b525f30b290caee0f6874851564fb,0000000000000000000000000000000000000000..b6567aca78679cc0fe53bfd4967636832eda11ff
mode 100644,000000..100644
--- /dev/null
@@@ -1,18 -1,0 +1,18 @@@
- /stdsimd
 +target
 +**/*.rs.bk
 +*.rlib
 +*.o
 +perf.data
 +perf.data.old
 +*.events
 +*.string*
 +/y.bin
 +/build
 +/build_sysroot/sysroot_src
 +/build_sysroot/compiler-builtins
 +/build_sysroot/rustc_version
 +/rust
 +/rand
 +/regex
 +/simple-raytracer
++/portable-simd
index 23c1fdc6ee425c7b73404c78a0303fc6aea9e73c,0000000000000000000000000000000000000000..4afddf76869de4a872b1a49bd5e2f6e7814ff046
mode 100644,000000..100644
--- /dev/null
@@@ -1,304 -1,0 +1,304 @@@
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
 +# This file is automatically @generated by Cargo.
 +# It is not intended for manual editing.
 +version = 3
 +
 +[[package]]
 +name = "anyhow"
 +version = "1.0.42"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
 +
 +[[package]]
 +name = "ar"
 +version = "0.8.0"
 +source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif_ranlib#de9ab0e56bf3a208381d342aa5b60f9ff2891648"
 +
 +[[package]]
 +name = "autocfg"
 +version = "1.0.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 +
 +[[package]]
 +name = "bitflags"
 +version = "1.2.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 +
 +[[package]]
 +name = "cfg-if"
 +version = "1.0.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 +
 +[[package]]
 +name = "cranelift-bforest"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "cranelift-entity",
 +]
 +
 +[[package]]
 +name = "cranelift-codegen"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "cranelift-bforest",
 + "cranelift-codegen-meta",
 + "cranelift-codegen-shared",
 + "cranelift-entity",
 + "gimli",
 + "log",
 + "regalloc",
 + "smallvec",
 + "target-lexicon",
 +]
 +
 +[[package]]
 +name = "cranelift-codegen-meta"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "cranelift-codegen-shared",
 + "cranelift-entity",
 +]
 +
 +[[package]]
 +name = "cranelift-codegen-shared"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +
 +[[package]]
 +name = "cranelift-entity"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +
 +[[package]]
 +name = "cranelift-frontend"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "cranelift-codegen",
 + "log",
 + "smallvec",
 + "target-lexicon",
 +]
 +
 +[[package]]
 +name = "cranelift-jit"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "anyhow",
 + "cranelift-codegen",
 + "cranelift-entity",
 + "cranelift-module",
 + "cranelift-native",
 + "libc",
 + "log",
 + "region",
 + "target-lexicon",
 + "winapi",
 +]
 +
 +[[package]]
 +name = "cranelift-module"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "anyhow",
 + "cranelift-codegen",
 + "cranelift-entity",
 + "log",
 +]
 +
 +[[package]]
 +name = "cranelift-native"
- version = "0.75.0"
- source = "git+https://github.com/bytecodealliance/wasmtime.git#5deda279775dca5e37449c829cda1f6276d6542b"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "cranelift-codegen",
 + "libc",
 + "target-lexicon",
 +]
 +
 +[[package]]
 +name = "cranelift-object"
++version = "0.76.0"
++source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
 +dependencies = [
 + "anyhow",
 + "cranelift-codegen",
 + "cranelift-module",
 + "log",
 + "object",
 + "target-lexicon",
 +]
 +
 +[[package]]
 +name = "crc32fast"
 +version = "1.2.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
 +dependencies = [
 + "cfg-if",
 +]
 +
 +[[package]]
 +name = "gimli"
 +version = "0.25.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
 +dependencies = [
 + "indexmap",
 +]
 +
 +[[package]]
 +name = "hashbrown"
 +version = "0.11.2"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
 +
 +[[package]]
 +name = "indexmap"
 +version = "1.7.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
 +dependencies = [
 + "autocfg",
 + "hashbrown",
 +]
 +
 +[[package]]
 +name = "libc"
 +version = "0.2.98"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
 +
 +[[package]]
 +name = "libloading"
 +version = "0.6.7"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
 +dependencies = [
 + "cfg-if",
 + "winapi",
 +]
 +
 +[[package]]
 +name = "log"
 +version = "0.4.14"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
 +dependencies = [
 + "cfg-if",
 +]
 +
 +[[package]]
 +name = "mach"
 +version = "0.3.2"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
 +dependencies = [
 + "libc",
 +]
 +
 +[[package]]
 +name = "memchr"
 +version = "2.4.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
 +
 +[[package]]
 +name = "object"
 +version = "0.26.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
 +dependencies = [
 + "crc32fast",
 + "indexmap",
 + "memchr",
 +]
 +
 +[[package]]
 +name = "regalloc"
 +version = "0.0.31"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
 +dependencies = [
 + "log",
 + "rustc-hash",
 + "smallvec",
 +]
 +
 +[[package]]
 +name = "region"
 +version = "2.2.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0"
 +dependencies = [
 + "bitflags",
 + "libc",
 + "mach",
 + "winapi",
 +]
 +
 +[[package]]
 +name = "rustc-hash"
 +version = "1.1.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 +
 +[[package]]
 +name = "rustc_codegen_cranelift"
 +version = "0.1.0"
 +dependencies = [
 + "ar",
 + "cranelift-codegen",
 + "cranelift-frontend",
 + "cranelift-jit",
 + "cranelift-module",
 + "cranelift-native",
 + "cranelift-object",
 + "gimli",
 + "indexmap",
 + "libloading",
 + "object",
 + "smallvec",
 + "target-lexicon",
 +]
 +
 +[[package]]
 +name = "smallvec"
 +version = "1.6.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
 +
 +[[package]]
 +name = "target-lexicon"
 +version = "0.12.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "b0652da4c4121005e9ed22b79f6c5f2d9e2752906b53a33e9490489ba421a6fb"
 +
 +[[package]]
 +name = "winapi"
 +version = "0.3.9"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
 +dependencies = [
 + "winapi-i686-pc-windows-gnu",
 + "winapi-x86_64-pc-windows-gnu",
 +]
 +
 +[[package]]
 +name = "winapi-i686-pc-windows-gnu"
 +version = "0.4.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 +
 +[[package]]
 +name = "winapi-x86_64-pc-windows-gnu"
 +version = "0.4.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
index e068f084234bc734fc2e21c5e218a8089dc10d92,0000000000000000000000000000000000000000..22be21cb8dee9a3d1a4ff4096218a2abfbbea13f
mode 100644,000000..100644
--- /dev/null
@@@ -1,318 -1,0 +1,329 @@@
- version = "0.14.1"
 +# This file is automatically @generated by Cargo.
 +# It is not intended for manual editing.
 +version = 3
 +
 +[[package]]
 +name = "addr2line"
- checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
++version = "0.16.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "1.0.69"
++checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
 +dependencies = [
 + "compiler_builtins",
 + "gimli",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "adler"
 +version = "1.0.2"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "alloc"
 +version = "0.0.0"
 +dependencies = [
 + "compiler_builtins",
 + "core",
 +]
 +
 +[[package]]
 +name = "autocfg"
 +version = "1.0.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 +
 +[[package]]
 +name = "cc"
- checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
++version = "1.0.70"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "0.1.46"
++checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
 +
 +[[package]]
 +name = "cfg-if"
 +version = "0.1.10"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "compiler_builtins"
- version = "0.23.0"
++version = "0.1.50"
 +dependencies = [
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "core"
 +version = "0.0.0"
 +
 +[[package]]
 +name = "dlmalloc"
 +version = "0.2.1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
 +dependencies = [
 + "compiler_builtins",
 + "libc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "fortanix-sgx-abi"
 +version = "0.3.3"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "getopts"
 +version = "0.2.21"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
 +dependencies = [
 + "rustc-std-workspace-core",
 + "rustc-std-workspace-std",
 + "unicode-width",
 +]
 +
 +[[package]]
 +name = "gimli"
- checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
++version = "0.25.0"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "0.2.98"
++checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "hashbrown"
 +version = "0.11.2"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "hermit-abi"
 +version = "0.1.19"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 +dependencies = [
 + "compiler_builtins",
 + "libc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "libc"
- checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
++version = "0.2.102"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "0.22.0"
++checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
 +dependencies = [
 + "rustc-std-workspace-core",
 +]
 +
++[[package]]
++name = "memchr"
++version = "2.4.1"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
++dependencies = [
++ "compiler_builtins",
++ "rustc-std-workspace-core",
++]
++
 +[[package]]
 +name = "miniz_oxide"
 +version = "0.4.4"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
 +dependencies = [
 + "adler",
 + "autocfg",
 + "compiler_builtins",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "object"
- checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
++version = "0.26.2"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "0.1.20"
++checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
 +dependencies = [
 + "compiler_builtins",
++ "memchr",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "panic_abort"
 +version = "0.0.0"
 +dependencies = [
 + "alloc",
 + "cfg-if",
 + "compiler_builtins",
 + "core",
 + "libc",
 +]
 +
 +[[package]]
 +name = "panic_unwind"
 +version = "0.0.0"
 +dependencies = [
 + "alloc",
 + "cfg-if",
 + "compiler_builtins",
 + "core",
 + "libc",
 + "unwind",
 +]
 +
 +[[package]]
 +name = "proc_macro"
 +version = "0.0.0"
 +dependencies = [
 + "std",
 +]
 +
 +[[package]]
 +name = "rustc-demangle"
- checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
++version = "0.1.21"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
- version = "0.1.8"
++checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "rustc-std-workspace-alloc"
 +version = "1.99.0"
 +dependencies = [
 + "alloc",
 +]
 +
 +[[package]]
 +name = "rustc-std-workspace-core"
 +version = "1.99.0"
 +dependencies = [
 + "core",
 +]
 +
 +[[package]]
 +name = "rustc-std-workspace-std"
 +version = "1.99.0"
 +dependencies = [
 + "std",
 +]
 +
 +[[package]]
 +name = "std"
 +version = "0.0.0"
 +dependencies = [
 + "addr2line",
 + "alloc",
 + "cfg-if",
 + "compiler_builtins",
 + "core",
 + "dlmalloc",
 + "fortanix-sgx-abi",
 + "hashbrown",
 + "hermit-abi",
 + "libc",
 + "miniz_oxide",
 + "object",
 + "panic_abort",
 + "panic_unwind",
 + "rustc-demangle",
 + "std_detect",
 + "unwind",
 + "wasi",
 +]
 +
 +[[package]]
 +name = "std_detect"
 +version = "0.1.5"
 +dependencies = [
 + "cfg-if",
 + "compiler_builtins",
 + "libc",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
 +
 +[[package]]
 +name = "sysroot"
 +version = "0.0.0"
 +dependencies = [
 + "alloc",
 + "compiler_builtins",
 + "core",
 + "std",
 + "test",
 +]
 +
 +[[package]]
 +name = "test"
 +version = "0.0.0"
 +dependencies = [
 + "cfg-if",
 + "core",
 + "getopts",
 + "libc",
 + "panic_abort",
 + "panic_unwind",
 + "proc_macro",
 + "std",
 +]
 +
 +[[package]]
 +name = "unicode-width"
- checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
++version = "0.1.9"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
++checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-core",
 + "rustc-std-workspace-std",
 +]
 +
 +[[package]]
 +name = "unwind"
 +version = "0.0.0"
 +dependencies = [
 + "cc",
 + "cfg-if",
 + "compiler_builtins",
 + "core",
 + "libc",
 +]
 +
 +[[package]]
 +name = "wasi"
 +version = "0.9.0+wasi-snapshot-preview1"
 +source = "registry+https://github.com/rust-lang/crates.io-index"
 +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 +dependencies = [
 + "compiler_builtins",
 + "rustc-std-workspace-alloc",
 + "rustc-std-workspace-core",
 +]
index 4b2051b605abdd726c99682639f95f5c8a7deeb3,0000000000000000000000000000000000000000..ae9a35048bda9a56873fec5e678bb835e80e6e10
mode 100644,000000..100644
--- /dev/null
@@@ -1,136 -1,0 +1,136 @@@
-         "stdsimd",
-         "https://github.com/rust-lang/stdsimd",
-         "be96995d8ddec03fac9a0caf4d4c51c7fbc33507",
 +use std::env;
 +use std::ffi::OsStr;
 +use std::ffi::OsString;
 +use std::fs;
 +use std::path::Path;
 +use std::process::Command;
 +
 +use crate::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
 +use crate::utils::{copy_dir_recursively, spawn_and_wait};
 +
 +pub(crate) fn prepare() {
 +    prepare_sysroot();
 +
 +    eprintln!("[INSTALL] hyperfine");
 +    Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
 +
 +    clone_repo(
 +        "rand",
 +        "https://github.com/rust-random/rand.git",
 +        "0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
 +    );
 +    apply_patches("rand", Path::new("rand"));
 +
 +    clone_repo(
 +        "regex",
 +        "https://github.com/rust-lang/regex.git",
 +        "341f207c1071f7290e3f228c710817c280c8dca1",
 +    );
 +
 +    clone_repo(
-     apply_patches("stdsimd", Path::new("stdsimd"));
++        "portable-simd",
++        "https://github.com/rust-lang/portable-simd",
++        "8cf7a62e5d2552961df51e5200aaa5b7c890a4bf",
 +    );
-         "0.1.46",
++    apply_patches("portable-simd", Path::new("portable-simd"));
 +
 +    clone_repo(
 +        "simple-raytracer",
 +        "https://github.com/ebobby/simple-raytracer",
 +        "804a7a21b9e673a482797aa289a18ed480e4d813",
 +    );
 +
 +    eprintln!("[LLVM BUILD] simple-raytracer");
 +    let mut build_cmd = Command::new("cargo");
 +    build_cmd.arg("build").env_remove("CARGO_TARGET_DIR").current_dir("simple-raytracer");
 +    spawn_and_wait(build_cmd);
 +    fs::copy(
 +        Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")),
 +        // FIXME use get_file_name here too once testing is migrated to rust
 +        "simple-raytracer/raytracer_cg_llvm",
 +    )
 +    .unwrap();
 +}
 +
 +fn prepare_sysroot() {
 +    let rustc_path = get_rustc_path();
 +    let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
 +    let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
 +
 +    assert!(sysroot_src_orig.exists());
 +
 +    if sysroot_src.exists() {
 +        fs::remove_dir_all(&sysroot_src).unwrap();
 +    }
 +    fs::create_dir_all(sysroot_src.join("library")).unwrap();
 +    eprintln!("[COPY] sysroot src");
 +    copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
 +
 +    let rustc_version = get_rustc_version();
 +    fs::write(Path::new("build_sysroot").join("rustc_version"), &rustc_version).unwrap();
 +
 +    eprintln!("[GIT] init");
 +    let mut git_init_cmd = Command::new("git");
 +    git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
 +    spawn_and_wait(git_init_cmd);
 +
 +    let mut git_add_cmd = Command::new("git");
 +    git_add_cmd.arg("add").arg(".").current_dir(&sysroot_src);
 +    spawn_and_wait(git_add_cmd);
 +
 +    let mut git_commit_cmd = Command::new("git");
 +    git_commit_cmd
 +        .arg("commit")
 +        .arg("-m")
 +        .arg("Initial commit")
 +        .arg("-q")
 +        .current_dir(&sysroot_src);
 +    spawn_and_wait(git_commit_cmd);
 +
 +    apply_patches("sysroot", &sysroot_src);
 +
 +    clone_repo(
 +        "build_sysroot/compiler-builtins",
 +        "https://github.com/rust-lang/compiler-builtins.git",
++        "0.1.50",
 +    );
 +    apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
 +}
 +
 +fn clone_repo(target_dir: &str, repo: &str, rev: &str) {
 +    eprintln!("[CLONE] {}", repo);
 +    // Ignore exit code as the repo may already have been checked out
 +    Command::new("git").arg("clone").arg(repo).arg(target_dir).spawn().unwrap().wait().unwrap();
 +
 +    let mut clean_cmd = Command::new("git");
 +    clean_cmd.arg("checkout").arg("--").arg(".").current_dir(target_dir);
 +    spawn_and_wait(clean_cmd);
 +
 +    let mut checkout_cmd = Command::new("git");
 +    checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(target_dir);
 +    spawn_and_wait(checkout_cmd);
 +}
 +
 +fn get_patches(crate_name: &str) -> Vec<OsString> {
 +    let mut patches: Vec<_> = fs::read_dir("patches")
 +        .unwrap()
 +        .map(|entry| entry.unwrap().path())
 +        .filter(|path| path.extension() == Some(OsStr::new("patch")))
 +        .map(|path| path.file_name().unwrap().to_owned())
 +        .filter(|file_name| {
 +            file_name.to_str().unwrap().split_once("-").unwrap().1.starts_with(crate_name)
 +        })
 +        .collect();
 +    patches.sort();
 +    patches
 +}
 +
 +fn apply_patches(crate_name: &str, target_dir: &Path) {
 +    for patch in get_patches(crate_name) {
 +        eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch);
 +        let patch_arg = env::current_dir().unwrap().join("patches").join(patch);
 +        let mut apply_patch_cmd = Command::new("git");
 +        apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir);
 +        spawn_and_wait(apply_patch_cmd);
 +    }
 +}
index 23e5bf2e0a8fd77fd08e877fe1a2d2baa29cecaf,0000000000000000000000000000000000000000..865de7d234f1419affc4a673bab58986e6d6a790
mode 100755,000000..100755
--- /dev/null
@@@ -1,6 -1,0 +1,6 @@@
- rm -rf rand/ regex/ simple-raytracer/ stdsimd/
 +#!/usr/bin/env bash
 +set -e
 +
 +rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
 +rm -rf target/ build/ perf.data{,.old}
++rm -rf rand/ regex/ simple-raytracer/ portable-simd/
index 87eec0e818bb2407695c4fa6b82ff49eada037a1,0000000000000000000000000000000000000000..bcc5745d9d1974af3115e83f9004151b10eeeba2
mode 100644,000000..100644
--- /dev/null
@@@ -1,65 -1,0 +1,67 @@@
 +# Usage
 +
 +rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
 +
 +Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.rs prepare` and `y.rs build` or `test.sh`).
 +
 +## Cargo
 +
 +In the directory with your project (where you can do the usual `cargo build`), run:
 +
 +```bash
 +$ $cg_clif_dir/build/cargo build
 +```
 +
 +This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
 +
 +## Rustc
 +
 +> You should prefer using the Cargo method.
 +
 +```bash
 +$ $cg_clif_dir/build/bin/cg_clif my_crate.rs
 +```
 +
 +## Jit mode
 +
++> ⚠⚠⚠ The JIT mode is highly experimental. It may be slower than AOT compilation due to lack of incremental compilation. It may also be hard to setup if you have cargo dependencies. ⚠⚠⚠
++
 +In jit mode cg_clif will immediately execute your code without creating an executable file.
 +
 +> This requires all dependencies to be available as dynamic library.
 +> The jit mode will probably need cargo integration to make this possible.
 +
 +```bash
 +$ $cg_clif_dir/build/cargo jit
 +```
 +
 +or
 +
 +```bash
 +$ $cg_clif_dir/build/bin/cg_clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
 +```
 +
 +There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
 +first called.
 +
 +```bash
 +$ $cg_clif_dir/build/cargo lazy-jit
 +```
 +
 +## Shell
 +
 +These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit.
 +
 +```bash
 +function jit_naked() {
 +    echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic
 +}
 +
 +function jit() {
 +    jit_naked "fn main() { $@ }"
 +}
 +
 +function jit_calc() {
 +    jit 'println!("0x{:x}", ' $@ ');';
 +}
 +```
index 2a9f7e58e01c2f93db91629a11a21132188bbedf,0000000000000000000000000000000000000000..d0d492e96742d6601819878ee7f94e4126639b7a
mode 100644,000000..100644
--- /dev/null
@@@ -1,38 -1,0 +1,38 @@@
- #![feature(start, core_intrinsics, alloc_prelude, alloc_error_handler)]
++#![feature(start, core_intrinsics, alloc_prelude, alloc_error_handler, box_syntax)]
 +#![no_std]
 +
 +extern crate alloc;
 +extern crate alloc_system;
 +
 +use alloc::prelude::v1::*;
 +
 +use alloc_system::System;
 +
 +#[global_allocator]
 +static ALLOC: System = System;
 +
 +#[cfg_attr(unix, link(name = "c"))]
 +#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))]
 +extern "C" {
 +    fn puts(s: *const u8) -> i32;
 +}
 +
 +#[panic_handler]
 +fn panic_handler(_: &core::panic::PanicInfo) -> ! {
 +    core::intrinsics::abort();
 +}
 +
 +#[alloc_error_handler]
 +fn alloc_error_handler(_: alloc::alloc::Layout) -> ! {
 +    core::intrinsics::abort();
 +}
 +
 +#[start]
 +fn main(_argc: isize, _argv: *const *const u8) -> isize {
 +    let world: Box<&str> = box "Hello World!\0";
 +    unsafe {
 +        puts(*world as *const str as *const u8);
 +    }
 +
 +    0
 +}
index 6e13e4dcbfbffcb1084d4bb9b2c27e41c760c62e,0000000000000000000000000000000000000000..cbfdb3c44f33e1170c2e9d6a8b9abfb5654c7c7a
mode 100644,000000..100644
--- /dev/null
@@@ -1,475 -1,0 +1,475 @@@
- #![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local)]
++#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, box_syntax)]
 +#![no_core]
 +#![allow(dead_code, non_camel_case_types)]
 +
 +extern crate mini_core;
 +
 +use mini_core::*;
 +use mini_core::libc::*;
 +
 +unsafe extern "C" fn my_puts(s: *const i8) {
 +    puts(s);
 +}
 +
 +macro_rules! assert {
 +    ($e:expr) => {
 +        if !$e {
 +            panic(stringify!(! $e));
 +        }
 +    };
 +}
 +
 +macro_rules! assert_eq {
 +    ($l:expr, $r: expr) => {
 +        if $l != $r {
 +            panic(stringify!($l != $r));
 +        }
 +    }
 +}
 +
 +#[lang = "termination"]
 +trait Termination {
 +    fn report(self) -> i32;
 +}
 +
 +impl Termination for () {
 +    fn report(self) -> i32 {
 +        unsafe {
 +            NUM = 6 * 7 + 1 + (1u8 == 1u8) as u8; // 44
 +            assert_eq!(*NUM_REF as i32, 44);
 +        }
 +        0
 +    }
 +}
 +
 +trait SomeTrait {
 +    fn object_safe(&self);
 +}
 +
 +impl SomeTrait for &'static str {
 +    fn object_safe(&self) {
 +        unsafe {
 +            puts(*self as *const str as *const i8);
 +        }
 +    }
 +}
 +
 +struct NoisyDrop {
 +    text: &'static str,
 +    inner: NoisyDropInner,
 +}
 +
 +struct NoisyDropInner;
 +
 +impl Drop for NoisyDrop {
 +    fn drop(&mut self) {
 +        unsafe {
 +            puts(self.text as *const str as *const i8);
 +        }
 +    }
 +}
 +
 +impl Drop for NoisyDropInner {
 +    fn drop(&mut self) {
 +        unsafe {
 +            puts("Inner got dropped!\0" as *const str as *const i8);
 +        }
 +    }
 +}
 +
 +impl SomeTrait for NoisyDrop {
 +    fn object_safe(&self) {}
 +}
 +
 +enum Ordering {
 +    Less = -1,
 +    Equal = 0,
 +    Greater = 1,
 +}
 +
 +#[lang = "start"]
 +fn start<T: Termination + 'static>(
 +    main: fn() -> T,
 +    argc: isize,
 +    argv: *const *const u8,
 +) -> isize {
 +    if argc == 3 {
 +        unsafe { puts(*argv as *const i8); }
 +        unsafe { puts(*((argv as usize + intrinsics::size_of::<*const u8>()) as *const *const i8)); }
 +        unsafe { puts(*((argv as usize + 2 * intrinsics::size_of::<*const u8>()) as *const *const i8)); }
 +    }
 +
 +    main().report() as isize
 +}
 +
 +static mut NUM: u8 = 6 * 7;
 +static NUM_REF: &'static u8 = unsafe { &NUM };
 +
 +struct Unique<T: ?Sized> {
 +    pointer: *const T,
 +    _marker: PhantomData<T>,
 +}
 +
 +impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
 +
 +unsafe fn zeroed<T>() -> T {
 +    let mut uninit = MaybeUninit { uninit: () };
 +    intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1);
 +    uninit.value.value
 +}
 +
 +fn take_f32(_f: f32) {}
 +fn take_unique(_u: Unique<()>) {}
 +
 +fn return_u128_pair() -> (u128, u128) {
 +    (0, 0)
 +}
 +
 +fn call_return_u128_pair() {
 +    return_u128_pair();
 +}
 +
 +fn main() {
 +    take_unique(Unique {
 +        pointer: 0 as *const (),
 +        _marker: PhantomData,
 +    });
 +    take_f32(0.1);
 +
 +    call_return_u128_pair();
 +
 +    let slice = &[0, 1] as &[i32];
 +    let slice_ptr = slice as *const [i32] as *const i32;
 +
 +    assert_eq!(slice_ptr as usize % 4, 0);
 +
 +    //return;
 +
 +    unsafe {
 +        printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
 +
 +        let hello: &[u8] = b"Hello\0" as &[u8; 6];
 +        let ptr: *const i8 = hello as *const [u8] as *const i8;
 +        puts(ptr);
 +
 +        let world: Box<&str> = box "World!\0";
 +        puts(*world as *const str as *const i8);
 +        world as Box<dyn SomeTrait>;
 +
 +        assert_eq!(intrinsics::bitreverse(0b10101000u8), 0b00010101u8);
 +
 +        assert_eq!(intrinsics::bswap(0xabu8), 0xabu8);
 +        assert_eq!(intrinsics::bswap(0xddccu16), 0xccddu16);
 +        assert_eq!(intrinsics::bswap(0xffee_ddccu32), 0xccdd_eeffu32);
 +        assert_eq!(intrinsics::bswap(0x1234_5678_ffee_ddccu64), 0xccdd_eeff_7856_3412u64);
 +
 +        assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
 +
 +        let chars = &['C', 'h', 'a', 'r', 's'];
 +        let chars = chars as &[char];
 +        assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
 +
 +        let a: &dyn SomeTrait = &"abc\0";
 +        a.object_safe();
 +
 +        assert_eq!(intrinsics::size_of_val(a) as u8, 16);
 +        assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
 +
 +        assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
 +        assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
 +
 +        assert!(!intrinsics::needs_drop::<u8>());
 +        assert!(intrinsics::needs_drop::<NoisyDrop>());
 +
 +        Unique {
 +            pointer: 0 as *const &str,
 +            _marker: PhantomData,
 +        } as Unique<dyn SomeTrait>;
 +
 +        struct MyDst<T: ?Sized>(T);
 +
 +        intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>);
 +
 +        struct Foo {
 +            x: u8,
 +            y: !,
 +        }
 +
 +        unsafe fn uninitialized<T>() -> T {
 +            MaybeUninit { uninit: () }.value.value
 +        }
 +
 +        zeroed::<(u8, u8)>();
 +        #[allow(unreachable_code)]
 +        {
 +            if false {
 +                zeroed::<!>();
 +                zeroed::<Foo>();
 +                uninitialized::<Foo>();
 +            }
 +        }
 +    }
 +
 +    let _ = box NoisyDrop {
 +        text: "Boxed outer got dropped!\0",
 +        inner: NoisyDropInner,
 +    } as Box<dyn SomeTrait>;
 +
 +    const FUNC_REF: Option<fn()> = Some(main);
 +    match FUNC_REF {
 +        Some(_) => {},
 +        None => assert!(false),
 +    }
 +
 +    match Ordering::Less {
 +        Ordering::Less => {},
 +        _ => assert!(false),
 +    }
 +
 +    [NoisyDropInner, NoisyDropInner];
 +
 +    let x = &[0u32, 42u32] as &[u32];
 +    match x {
 +        [] => assert_eq!(0u32, 1),
 +        [_, ref y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize),
 +    }
 +
 +    assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
 +
 +    #[cfg(not(any(jit, windows)))]
 +    {
 +        extern {
 +            #[linkage = "extern_weak"]
 +            static ABC: *const u8;
 +        }
 +
 +        {
 +            extern {
 +                #[linkage = "extern_weak"]
 +                static ABC: *const u8;
 +            }
 +        }
 +
 +        unsafe { assert_eq!(ABC as usize, 0); }
 +    }
 +
 +    &mut (|| Some(0 as *const ())) as &mut dyn FnMut() -> Option<*const ()>;
 +
 +    let f = 1000.0;
 +    assert_eq!(f as u8, 255);
 +    let f2 = -1000.0;
 +    assert_eq!(f2 as i8, -128);
 +    assert_eq!(f2 as u8, 0);
 +
 +    let amount = 0;
 +    assert_eq!(1u128 << amount, 1);
 +
 +    static ANOTHER_STATIC: &u8 = &A_STATIC;
 +    assert_eq!(*ANOTHER_STATIC, 42);
 +
 +    check_niche_behavior();
 +
 +    extern "C" {
 +        type ExternType;
 +    }
 +
 +    struct ExternTypeWrapper {
 +        _a: ExternType,
 +    }
 +
 +    let nullptr = 0 as *const ();
 +    let extern_nullptr = nullptr as *const ExternTypeWrapper;
 +    extern_nullptr as *const ();
 +    let slice_ptr = &[] as *const [u8];
 +    slice_ptr as *const u8;
 +
 +    let repeat = [Some(42); 2];
 +    assert_eq!(repeat[0], Some(42));
 +    assert_eq!(repeat[1], Some(42));
 +
 +    from_decimal_string();
 +
 +    #[cfg(not(any(jit, windows)))]
 +    test_tls();
 +
 +    #[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
 +    unsafe {
 +        global_asm_test();
 +    }
 +
 +    // Both statics have a reference that points to the same anonymous allocation.
 +    static REF1: &u8 = &42;
 +    static REF2: &u8 = REF1;
 +    assert_eq!(*REF1, *REF2);
 +}
 +
 +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
 +extern "C" {
 +    fn global_asm_test();
 +}
 +
 +#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
 +global_asm! {
 +    "
 +    .global global_asm_test
 +    global_asm_test:
 +    // comment that would normally be removed by LLVM
 +    ret
 +    "
 +}
 +
 +#[repr(C)]
 +enum c_void {
 +    _1,
 +    _2,
 +}
 +
 +type c_int = i32;
 +type c_ulong = u64;
 +
 +type pthread_t = c_ulong;
 +
 +#[repr(C)]
 +struct pthread_attr_t {
 +    __size: [u64; 7],
 +}
 +
 +#[link(name = "pthread")]
 +extern "C" {
 +    fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int;
 +
 +    fn pthread_create(
 +        native: *mut pthread_t,
 +        attr: *const pthread_attr_t,
 +        f: extern "C" fn(_: *mut c_void) -> *mut c_void,
 +        value: *mut c_void
 +    ) -> c_int;
 +
 +    fn pthread_join(
 +        native: pthread_t,
 +        value: *mut *mut c_void
 +    ) -> c_int;
 +}
 +
 +#[thread_local]
 +#[cfg(not(jit))]
 +static mut TLS: u8 = 42;
 +
 +#[cfg(not(jit))]
 +extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
 +    unsafe { TLS = 0; }
 +    0 as *mut c_void
 +}
 +
 +#[cfg(not(jit))]
 +fn test_tls() {
 +    unsafe {
 +        let mut attr: pthread_attr_t = zeroed();
 +        let mut thread: pthread_t = 0;
 +
 +        assert_eq!(TLS, 42);
 +
 +        if pthread_attr_init(&mut attr) != 0 {
 +            assert!(false);
 +        }
 +
 +        if pthread_create(&mut thread, &attr, mutate_tls, 0 as *mut c_void) != 0 {
 +            assert!(false);
 +        }
 +
 +        let mut res = 0 as *mut c_void;
 +        pthread_join(thread, &mut res);
 +
 +        // TLS of main thread must not have been changed by the other thread.
 +        assert_eq!(TLS, 42);
 +
 +        puts("TLS works!\n\0" as *const str as *const i8);
 +    }
 +}
 +
 +// Copied ui/issues/issue-61696.rs
 +
 +pub enum Infallible {}
 +
 +// The check that the `bool` field of `V1` is encoding a "niche variant"
 +// (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect,
 +// causing valid `V1` values to be interpreted as other variants.
 +pub enum E1 {
 +    V1 { f: bool },
 +    V2 { f: Infallible },
 +    V3,
 +    V4,
 +}
 +
 +// Computing the discriminant used to be done using the niche type (here `u8`,
 +// from the `bool` field of `V1`), overflowing for variants with large enough
 +// indices (`V3` and `V4`), causing them to be interpreted as other variants.
 +pub enum E2<X> {
 +    V1 { f: bool },
 +
 +    /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X),
 +    _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X),
 +    _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X),
 +    _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X),
 +    _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X),
 +    _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X),
 +    _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X),
 +    _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X),
 +    _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X),
 +    _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X),
 +    _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X),
 +    _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X),
 +    _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X),
 +    _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X),
 +    _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X),
 +    _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X),
 +    _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X),
 +    _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X),
 +    _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X),
 +    _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X),
 +    _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X),
 +    _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X),
 +    _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X),
 +    _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X),
 +    _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X),
 +    _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X),
 +    _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X),
 +    _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X),
 +    _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X),
 +    _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X),
 +    _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X),
 +    _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X),
 +
 +    V3,
 +    V4,
 +}
 +
 +fn check_niche_behavior () {
 +    if let E1::V2 { .. } = (E1::V1 { f: true }) {
 +        intrinsics::abort();
 +    }
 +
 +    if let E2::V1 { .. } = E2::V3::<Infallible> {
 +        intrinsics::abort();
 +    }
 +}
 +
 +fn from_decimal_string() {
 +    loop {
 +        let multiplier = 1;
 +
 +        take_multiplier_ref(&multiplier);
 +
 +        if multiplier == 1 {
 +            break;
 +        }
 +
 +        unreachable();
 +    }
 +}
 +
 +fn take_multiplier_ref(_multiplier: &u128) {}
 +
 +fn unreachable() -> ! {
 +    panic("unreachable")
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2e683694663632c2a80cfe43c9e42c2a5fef2a32
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,152 @@@
++From 6bfce5dc2cbf834c74dbccb7538adc08c6eb57e7 Mon Sep 17 00:00:00 2001
++From: bjorn3 <bjorn3@users.noreply.github.com>
++Date: Sun, 25 Jul 2021 18:39:31 +0200
++Subject: [PATCH] Disable unsupported tests
++
++---
++ crates/core_simd/src/vector.rs        |  2 ++
++ crates/core_simd/src/math.rs         |  4 ++++
++ crates/core_simd/tests/masks.rs      | 12 ------------
++ crates/core_simd/tests/ops_macros.rs |  6 ++++++
++ crates/core_simd/tests/round.rs      |  2 ++
++ 6 files changed, 15 insertions(+), 13 deletions(-)
++
++diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
++index 25c5309..2b3d819 100644
++--- a/crates/core_simd/src/vector.rs
+++++ b/crates/core_simd/src/vector.rs
++@@ -22,6 +22,7 @@ where
++         self.0
++     }
++ 
+++    /*
++     /// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
++     /// If an index is out of bounds, that lane instead selects the value from the "or" vector.
++     /// ```
++@@ -150,6 +151,7 @@ where
++             // Cleared ☢️ *mut T Zone
++         }
++     }
+++    */
++ }
++ 
++ impl<T, const LANES: usize> Copy for Simd<T, LANES>
++diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs
++index 7290a28..e394730 100644
++--- a/crates/core_simd/src/math.rs
+++++ b/crates/core_simd/src/math.rs
++@@ -2,6 +2,7 @@ macro_rules! impl_uint_arith {
++     ($($ty:ty),+) => {
++         $( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
++ 
+++            /*
++             /// Lanewise saturating add.
++             ///
++             /// # Examples
++@@ -38,6 +39,7 @@ macro_rules! impl_uint_arith {
++             pub fn saturating_sub(self, second: Self) -> Self {
++                 unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
++             }
+++            */
++         })+
++     }
++ }
++@@ -46,6 +48,7 @@ macro_rules! impl_int_arith {
++     ($($ty:ty),+) => {
++         $( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
++ 
+++            /*
++             /// Lanewise saturating add.
++             ///
++             /// # Examples
++@@ -141,6 +144,7 @@ macro_rules! impl_int_arith {
++             pub fn saturating_neg(self) -> Self {
++                 Self::splat(0).saturating_sub(self)
++             }
+++            */
++         })+
++     }
++ }
++diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
++index 61d8e44..2bccae2 100644
++--- a/crates/core_simd/tests/masks.rs
+++++ b/crates/core_simd/tests/masks.rs
++@@ -67,19 +67,6 @@ macro_rules! test_mask_api {
++                 assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
++                 assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
++             }
++-
++-            #[cfg(feature = "generic_const_exprs")]
++-            #[test]
++-            fn roundtrip_bitmask_conversion() {
++-                let values = [
++-                    true, false, false, true, false, false, true, false,
++-                    true, true, false, false, false, false, false, true,
++-                ];
++-                let mask = core_simd::Mask::<$type, 16>::from_array(values);
++-                let bitmask = mask.to_bitmask();
++-                assert_eq!(bitmask, [0b01001001, 0b10000011]);
++-                assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
++-            }
++         }
++     }
++ }
++diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
++index cb39e73..fc0ebe1 100644
++--- a/crates/core_simd/tests/ops_macros.rs
+++++ b/crates/core_simd/tests/ops_macros.rs
++@@ -435,6 +435,7 @@ macro_rules! impl_float_tests {
++                     )
++                 }
++ 
+++                /*
++                 fn mul_add<const LANES: usize>() {
++                     test_helpers::test_ternary_elementwise(
++                         &Vector::<LANES>::mul_add,
++@@ -442,6 +443,7 @@ macro_rules! impl_float_tests {
++                         &|_, _, _| true,
++                     )
++                 }
+++                */
++ 
++                 fn recip<const LANES: usize>() {
++                     test_helpers::test_unary_elementwise(
++@@ -581,6 +585,7 @@ macro_rules! impl_float_tests {
++                     });
++                 }
++ 
+++                /*
++                 fn horizontal_max<const LANES: usize>() {
++                     test_helpers::test_1(&|x| {
++                         let vmax = Vector::<LANES>::from_array(x).horizontal_max();
++@@ -604,6 +609,7 @@ macro_rules! impl_float_tests {
++                         Ok(())
++                     });
++                 }
+++                */
++             }
++ 
++             #[cfg(feature = "std")]
++diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
++index 37044a7..4cdc6b7 100644
++--- a/crates/core_simd/tests/round.rs
+++++ b/crates/core_simd/tests/round.rs
++@@ -25,6 +25,7 @@ macro_rules! float_rounding_test {
++                     )
++                 }
++ 
+++                /*
++                 fn round<const LANES: usize>() {
++                     test_helpers::test_unary_elementwise(
++                         &Vector::<LANES>::round,
++@@ -32,6 +33,7 @@ macro_rules! float_rounding_test {
++                         &|_| true,
++                     )
++                 }
+++                */
++ 
++                 fn trunc<const LANES: usize>() {
++                     test_helpers::test_unary_elementwise(
++-- 
++2.26.2.7.g19db9cfb68
++
index cda8153083c337fd004cf2e3d5c0ac631156fd19,0000000000000000000000000000000000000000..e2d07bd12670264d2674919a63809eb55d15a112
mode 100644,000000..100644
--- /dev/null
@@@ -1,103 -1,0 +1,136 @@@
- From 6a4e6f5dc8c8a529a822eb9b57f9e57519595439 Mon Sep 17 00:00:00 2001
++From ad7ffe71baba46865f2e65266ab025920dfdc20b Mon Sep 17 00:00:00 2001
 +From: bjorn3 <bjorn3@users.noreply.github.com>
 +Date: Thu, 18 Feb 2021 18:45:28 +0100
 +Subject: [PATCH] Disable 128bit atomic operations
 +
 +Cranelift doesn't support them yet
 +---
 + library/core/src/panic/unwind_safe.rs |  6 -----
 + library/core/src/sync/atomic.rs       | 38 ---------------------------
 + library/core/tests/atomic.rs          |  4 ---
-  3 files changed, 48 deletions(-)
++ library/std/src/time/monotonic.rs     |  6 +++--
++ 4 files changed, 4 insertions(+), 50 deletions(-)
 +
 +diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs
 +index 092b7cf..158cf71 100644
 +--- a/library/core/src/panic/unwind_safe.rs
 ++++ b/library/core/src/panic/unwind_safe.rs
 +@@ -216,9 +216,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicI32 {}
 + #[cfg(target_has_atomic_load_store = "64")]
 + #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
 + impl RefUnwindSafe for crate::sync::atomic::AtomicI64 {}
 +-#[cfg(target_has_atomic_load_store = "128")]
 +-#[unstable(feature = "integer_atomics", issue = "32976")]
 +-impl RefUnwindSafe for crate::sync::atomic::AtomicI128 {}
 + 
 + #[cfg(target_has_atomic_load_store = "ptr")]
 + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
 +@@ -235,9 +232,6 @@ impl RefUnwindSafe for crate::sync::atomic::AtomicU32 {}
 + #[cfg(target_has_atomic_load_store = "64")]
 + #[stable(feature = "integer_atomics_stable", since = "1.34.0")]
 + impl RefUnwindSafe for crate::sync::atomic::AtomicU64 {}
 +-#[cfg(target_has_atomic_load_store = "128")]
 +-#[unstable(feature = "integer_atomics", issue = "32976")]
 +-impl RefUnwindSafe for crate::sync::atomic::AtomicU128 {}
 + 
 + #[cfg(target_has_atomic_load_store = "8")]
 + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
 +diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
- index 0194c58..25a0038 100644
++index d9de37e..8293fce 100644
 +--- a/library/core/src/sync/atomic.rs
 ++++ b/library/core/src/sync/atomic.rs
- @@ -2229,44 +2229,6 @@ atomic_int! {
++@@ -2234,44 +2234,6 @@ atomic_int! {
 +     "AtomicU64::new(0)",
 +     u64 AtomicU64 ATOMIC_U64_INIT
 + }
 +-#[cfg(target_has_atomic_load_store = "128")]
 +-atomic_int! {
 +-    cfg(target_has_atomic = "128"),
 +-    cfg(target_has_atomic_equal_alignment = "128"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    "i128",
 +-    "#![feature(integer_atomics)]\n\n",
 +-    atomic_min, atomic_max,
 +-    16,
 +-    "AtomicI128::new(0)",
 +-    i128 AtomicI128 ATOMIC_I128_INIT
 +-}
 +-#[cfg(target_has_atomic_load_store = "128")]
 +-atomic_int! {
 +-    cfg(target_has_atomic = "128"),
 +-    cfg(target_has_atomic_equal_alignment = "128"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"),
 +-    unstable(feature = "integer_atomics", issue = "32976"),
 +-    "u128",
 +-    "#![feature(integer_atomics)]\n\n",
 +-    atomic_umin, atomic_umax,
 +-    16,
 +-    "AtomicU128::new(0)",
 +-    u128 AtomicU128 ATOMIC_U128_INIT
 +-}
 + 
 + macro_rules! atomic_int_ptr_sized {
 +     ( $($target_pointer_width:literal $align:literal)* ) => { $(
 +diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs
 +index b735957..ea728b6 100644
 +--- a/library/core/tests/atomic.rs
 ++++ b/library/core/tests/atomic.rs
 +@@ -185,10 +185,6 @@ fn atomic_alignment() {
 +     assert_eq!(align_of::<AtomicU64>(), size_of::<AtomicU64>());
 +     #[cfg(target_has_atomic = "64")]
 +     assert_eq!(align_of::<AtomicI64>(), size_of::<AtomicI64>());
 +-    #[cfg(target_has_atomic = "128")]
 +-    assert_eq!(align_of::<AtomicU128>(), size_of::<AtomicU128>());
 +-    #[cfg(target_has_atomic = "128")]
 +-    assert_eq!(align_of::<AtomicI128>(), size_of::<AtomicI128>());
 +     #[cfg(target_has_atomic = "ptr")]
 +     assert_eq!(align_of::<AtomicUsize>(), size_of::<AtomicUsize>());
 +     #[cfg(target_has_atomic = "ptr")]
++diff --git a/library/std/src/time/monotonic.rs b/library/std/src/time/monotonic.rs
++index fa96b7a..2854f9c 100644
++--- a/library/std/src/time/monotonic.rs
+++++ b/library/std/src/time/monotonic.rs
++@@ -5,7 +5,7 @@ pub(super) fn monotonize(raw: time::Instant) -> time::Instant {
++     inner::monotonize(raw)
++ }
++ 
++-#[cfg(all(target_has_atomic = "64", not(target_has_atomic = "128")))]
+++#[cfg(target_has_atomic = "64")]
++ pub mod inner {
++     use crate::sync::atomic::AtomicU64;
++     use crate::sync::atomic::Ordering::*;
++@@ -70,6 +70,7 @@ pub mod inner {
++     }
++ }
++ 
+++/*
++ #[cfg(target_has_atomic = "128")]
++ pub mod inner {
++     use crate::sync::atomic::AtomicU128;
++@@ -94,8 +95,9 @@ pub mod inner {
++         ZERO.checked_add_duration(&Duration::new(secs, nanos)).unwrap()
++     }
++ }
+++*/
++ 
++-#[cfg(not(any(target_has_atomic = "64", target_has_atomic = "128")))]
+++#[cfg(not(target_has_atomic = "64"))]
++ pub mod inner {
++     use crate::cmp;
++     use crate::sys::time;
 +-- 
 +2.26.2.7.g19db9cfb68
 +
index f074ebe7a42e0dabf88c234aadb2ebcf9896ef64,0000000000000000000000000000000000000000..360570b3ae7a145c8bd24f7496878f6997912678
mode 100644,000000..100644
--- /dev/null
@@@ -1,3 -1,0 +1,3 @@@
- channel = "nightly-2021-08-05"
 +[toolchain]
++channel = "nightly-2021-09-19"
 +components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
index 0ac49dd35740f51e36f1a7ba9265a5ef1f63f0cf,0000000000000000000000000000000000000000..b714d47fec2a6d3d63fedc5d4b80ae3fcdb4b071
mode 100755,000000..100755
--- /dev/null
@@@ -1,93 -1,0 +1,93 @@@
- for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto" src/test/ui); do
 +#!/bin/bash
 +set -e
 +
 +cd $(dirname "$0")/../
 +
 +source ./scripts/setup_rust_fork.sh
 +
 +echo "[TEST] Test suite of rustc"
 +pushd rust
 +
 +cargo install ripgrep
 +
 +rm -r src/test/ui/{extern/,panics/,unsized-locals/,thinlto/,simd*,*lto*.rs,linkage*,unwind-*.rs} || true
++for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto|// needs-asm-support" src/test/ui); do
 +  rm $test
 +done
 +
 +for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do
 +  rm $test
 +done
 +
 +git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
 +
 +# these all depend on unwinding support
 +rm src/test/ui/backtrace.rs
 +rm src/test/ui/array-slice-vec/box-of-array-of-drop-*.rs
 +rm src/test/ui/array-slice-vec/slice-panic-*.rs
 +rm src/test/ui/array-slice-vec/nested-vec-3.rs
 +rm src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
 +rm src/test/ui/issues/issue-26655.rs
 +rm src/test/ui/issues/issue-29485.rs
 +rm src/test/ui/issues/issue-30018-panic.rs
 +rm src/test/ui/multi-panic.rs
 +rm src/test/ui/sepcomp/sepcomp-unwind.rs
 +rm src/test/ui/structs-enums/unit-like-struct-drop-run.rs
 +rm src/test/ui/terminate-in-initializer.rs
 +rm src/test/ui/threads-sendsync/task-stderr.rs
 +rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
 +rm src/test/ui/drop/drop-trait-enum.rs
 +rm src/test/ui/numbers-arithmetic/issue-8460.rs
 +rm src/test/ui/rt-explody-panic-payloads.rs
 +rm src/test/incremental/change_crate_dep_kind.rs
 +
 +rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
 +rm src/test/ui/init-large-type.rs # same
 +rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
 +rm src/test/ui/issues/issue-33992.rs # unsupported linkages
 +rm src/test/ui/issues/issue-51947.rs # same
 +rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result
 +rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
 +rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
 +rm src/test/ui/consts/issue-33537.rs # same
 +rm src/test/ui/async-await/async-fn-size-moved-locals.rs # -Cpanic=abort shrinks some generator by one byte
 +rm src/test/ui/async-await/async-fn-size-uninit-locals.rs # same
 +rm src/test/ui/generator/size-moved-locals.rs # same
 +rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
 +rm src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs # "Cannot run dynamic test fn out-of-process"
 +rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
 +
 +rm src/test/incremental/hashes/inline_asm.rs # inline asm
 +rm src/test/incremental/issue-72386.rs # same
 +rm src/test/incremental/issue-49482.rs # same
 +rm src/test/incremental/issue-54059.rs # same
 +rm src/test/incremental/lto.rs # requires lto
 +
 +rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
 +rm -r src/test/run-make/unstable-flag-required # same
 +rm -r src/test/run-make/emit-named-files # requires full --emit support
 +
 +rm src/test/pretty/asm.rs # inline asm
 +rm src/test/pretty/raw-str-nonexpr.rs # same
 +
 +rm -r src/test/run-pass-valgrind/unsized-locals
 +
 +rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning
 +rm src/test/ui/json-bom-plus-crlf.rs # same
 +rm src/test/ui/match/issue-82392.rs # differing error
 +rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep
 +
 +rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
 +rm src/test/ui/cfg/cfg-panic.rs
 +rm -r src/test/ui/hygiene/
 +
 +rm -r src/test/ui/polymorphization/ # polymorphization not yet supported
 +rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same
 +
 +rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
 +rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
 +rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support
 +
 +echo "[TEST] rustc test suite"
 +RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui}
 +popd
index 0eef710239bdd456e90df4ce7f69a8f2d5832a6b,0000000000000000000000000000000000000000..28a7980d6613cf0eef6c013879a59f3f442950f4
mode 100755,000000..100755
--- /dev/null
@@@ -1,163 -1,0 +1,163 @@@
-     pushd stdsimd
-     echo "[TEST] rust-lang/stdsimd"
 +#!/usr/bin/env bash
 +
 +set -e
 +
 +source scripts/config.sh
 +source scripts/ext_config.sh
 +export RUSTC=false # ensure that cg_llvm isn't accidentally used
 +MY_RUSTC="$(pwd)/build/bin/cg_clif $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2"
 +
 +function no_sysroot_tests() {
 +    echo "[BUILD] mini_core"
 +    $MY_RUSTC example/mini_core.rs --crate-name mini_core --crate-type lib,dylib --target "$TARGET_TRIPLE"
 +
 +    echo "[BUILD] example"
 +    $MY_RUSTC example/example.rs --crate-type lib --target "$TARGET_TRIPLE"
 +
 +    if [[ "$JIT_SUPPORTED" = "1" ]]; then
 +        echo "[JIT] mini_core_hello_world"
 +        CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
 +
 +        echo "[JIT-lazy] mini_core_hello_world"
 +        CG_CLIF_JIT_ARGS="abc bcd" $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/mini_core_hello_world.rs --cfg jit --target "$HOST_TRIPLE"
 +    else
 +        echo "[JIT] mini_core_hello_world (skipped)"
 +    fi
 +
 +    echo "[AOT] mini_core_hello_world"
 +    $MY_RUSTC example/mini_core_hello_world.rs --crate-name mini_core_hello_world --crate-type bin -g --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/mini_core_hello_world abc bcd
 +    # (echo "break set -n main"; echo "run"; sleep 1; echo "si -c 10"; sleep 1; echo "frame variable") | lldb -- ./target/out/mini_core_hello_world abc bcd
 +}
 +
 +function base_sysroot_tests() {
 +    echo "[AOT] arbitrary_self_types_pointers_and_wrappers"
 +    $MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
 +
 +    echo "[AOT] alloc_system"
 +    $MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"
 +
 +    echo "[AOT] alloc_example"
 +    $MY_RUSTC example/alloc_example.rs --crate-type bin --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/alloc_example
 +
 +    if [[ "$JIT_SUPPORTED" = "1" ]]; then
 +        echo "[JIT] std_example"
 +        $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
 +
 +        echo "[JIT-lazy] std_example"
 +        $MY_RUSTC -Zunstable-options -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
 +    else
 +        echo "[JIT] std_example (skipped)"
 +    fi
 +
 +    echo "[AOT] dst_field_align"
 +    # FIXME Re-add -Zmir-opt-level=2 once rust-lang/rust#67529 is fixed.
 +    $MY_RUSTC example/dst-field-align.rs --crate-name dst_field_align --crate-type bin --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/dst_field_align || (echo $?; false)
 +
 +    echo "[AOT] std_example"
 +    $MY_RUSTC example/std_example.rs --crate-type bin --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/std_example arg
 +
 +    echo "[AOT] subslice-patterns-const-eval"
 +    $MY_RUSTC example/subslice-patterns-const-eval.rs --crate-type bin -Cpanic=abort --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/subslice-patterns-const-eval
 +
 +    echo "[AOT] track-caller-attribute"
 +    $MY_RUSTC example/track-caller-attribute.rs --crate-type bin -Cpanic=abort --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/track-caller-attribute
 +
 +    echo "[AOT] mod_bench"
 +    $MY_RUSTC example/mod_bench.rs --crate-type bin --target "$TARGET_TRIPLE"
 +    $RUN_WRAPPER ./target/out/mod_bench
 +}
 +
 +function extended_sysroot_tests() {
 +    pushd rand
 +    ../build/cargo clean
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        echo "[TEST] rust-random/rand"
 +        ../build/cargo test --workspace
 +    else
 +        echo "[AOT] rust-random/rand"
 +        ../build/cargo build --workspace --target $TARGET_TRIPLE --tests
 +    fi
 +    popd
 +
 +    pushd simple-raytracer
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        echo "[BENCH COMPILE] ebobby/simple-raytracer"
 +        hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo clean" \
 +        "RUSTC=rustc RUSTFLAGS='' cargo build" \
 +        "../build/cargo build"
 +
 +        echo "[BENCH RUN] ebobby/simple-raytracer"
 +        cp ./target/debug/main ./raytracer_cg_clif
 +        hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
 +    else
 +        ../build/cargo clean
 +        echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
 +        echo "[COMPILE] ebobby/simple-raytracer"
 +        ../build/cargo build --target $TARGET_TRIPLE
 +        echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
 +    fi
 +    popd
 +
 +    pushd build_sysroot/sysroot_src/library/core/tests
 +    echo "[TEST] libcore"
 +    ../../../../../build/cargo clean
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        ../../../../../build/cargo test
 +    else
 +        ../../../../../build/cargo build --target $TARGET_TRIPLE --tests
 +    fi
 +    popd
 +
 +    pushd regex
 +    echo "[TEST] rust-lang/regex example shootout-regex-dna"
 +    ../build/cargo clean
 +    export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
 +    # Make sure `[codegen mono items] start` doesn't poison the diff
 +    ../build/cargo build --example shootout-regex-dna --target $TARGET_TRIPLE
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        cat examples/regexdna-input.txt \
 +            | ../build/cargo run --example shootout-regex-dna --target $TARGET_TRIPLE \
 +            | grep -v "Spawned thread" > res.txt
 +        diff -u res.txt examples/regexdna-output.txt
 +    fi
 +
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        echo "[TEST] rust-lang/regex tests"
 +        ../build/cargo test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
 +    else
 +        echo "[AOT] rust-lang/regex tests"
 +        ../build/cargo build --tests --target $TARGET_TRIPLE
 +    fi
 +    popd
 +
++    pushd portable-simd
++    echo "[TEST] rust-lang/portable-simd"
 +    ../build/cargo clean
 +    ../build/cargo build --all-targets --target $TARGET_TRIPLE
 +    if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
 +        ../build/cargo test -q
 +    fi
 +    popd
 +}
 +
 +case "$1" in
 +    "no_sysroot")
 +        no_sysroot_tests
 +        ;;
 +    "base_sysroot")
 +        base_sysroot_tests
 +        ;;
 +    "extended_sysroot")
 +        extended_sysroot_tests
 +        ;;
 +    *)
 +        echo "unknown test suite"
 +        ;;
 +esac
index 0fa228fc944a160c226f21c2ebec660c1192ba7c,0000000000000000000000000000000000000000..8a1f654399004a3c80280754aa57d4ff6bc3179f
mode 100644,000000..100644
--- /dev/null
@@@ -1,246 -1,0 +1,250 @@@
- use object::{Object, ObjectSymbol, SymbolKind};
 +//! Creation of ar archives like for the lib and staticlib crate type
 +
 +use std::collections::BTreeMap;
++use std::convert::TryFrom;
 +use std::fs::File;
++use std::io::{self, Read, Seek};
 +use std::path::{Path, PathBuf};
 +
 +use rustc_codegen_ssa::back::archive::ArchiveBuilder;
 +use rustc_session::Session;
 +
-     FromArchive { archive_index: usize, entry_index: usize },
++use object::read::archive::ArchiveFile;
++use object::{Object, ObjectSymbol, ReadCache, SymbolKind};
 +
 +#[derive(Debug)]
 +enum ArchiveEntry {
-     src_archives: Vec<(PathBuf, ar::Archive<File>)>,
++    FromArchive { archive_index: usize, file_range: (u64, u64) },
 +    File(PathBuf),
 +}
 +
 +pub(crate) struct ArArchiveBuilder<'a> {
 +    sess: &'a Session,
 +    dst: PathBuf,
 +    use_gnu_style_archive: bool,
 +    no_builtin_ranlib: bool,
 +
-     entries: Vec<(String, ArchiveEntry)>,
++    src_archives: Vec<File>,
 +    // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
 +    // the end of an archive for linkers to not get confused.
-             let mut archive = ar::Archive::new(File::open(input).unwrap());
++    entries: Vec<(Vec<u8>, ArchiveEntry)>,
 +}
 +
 +impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
 +    fn new(sess: &'a Session, output: &Path, input: Option<&Path>) -> Self {
 +        let (src_archives, entries) = if let Some(input) = input {
-             let mut i = 0;
-             while let Some(entry) = archive.next_entry() {
++            let read_cache = ReadCache::new(File::open(input).unwrap());
++            let archive = ArchiveFile::parse(&read_cache).unwrap();
 +            let mut entries = Vec::new();
 +
-                     String::from_utf8(entry.header().identifier().to_vec()).unwrap(),
-                     ArchiveEntry::FromArchive { archive_index: 0, entry_index: i },
++            for entry in archive.members() {
 +                let entry = entry.unwrap();
 +                entries.push((
-                 i += 1;
++                    entry.name().to_vec(),
++                    ArchiveEntry::FromArchive { archive_index: 0, file_range: entry.file_range() },
 +                ));
-             (vec![(input.to_owned(), archive)], entries)
 +            }
 +
-         self.entries.iter().map(|(name, _)| name.clone()).collect()
++            (vec![read_cache.into_inner()], entries)
 +        } else {
 +            (vec![], Vec::new())
 +        };
 +
 +        ArArchiveBuilder {
 +            sess,
 +            dst: output.to_path_buf(),
 +            use_gnu_style_archive: sess.target.archive_format == "gnu",
 +            // FIXME fix builtin ranlib on macOS
 +            no_builtin_ranlib: sess.target.is_like_osx,
 +
 +            src_archives,
 +            entries,
 +        }
 +    }
 +
 +    fn src_files(&mut self) -> Vec<String> {
-             .position(|(entry_name, _)| entry_name == name)
++        self.entries.iter().map(|(name, _)| String::from_utf8(name.clone()).unwrap()).collect()
 +    }
 +
 +    fn remove_file(&mut self, name: &str) {
 +        let index = self
 +            .entries
 +            .iter()
-             file.file_name().unwrap().to_str().unwrap().to_string(),
++            .position(|(entry_name, _)| entry_name == name.as_bytes())
 +            .expect("Tried to remove file not existing in src archive");
 +        self.entries.remove(index);
 +    }
 +
 +    fn add_file(&mut self, file: &Path) {
 +        self.entries.push((
-         let mut archive = ar::Archive::new(std::fs::File::open(&archive_path)?);
++            file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
 +            ArchiveEntry::File(file.to_owned()),
 +        ));
 +    }
 +
 +    fn add_archive<F>(&mut self, archive_path: &Path, mut skip: F) -> std::io::Result<()>
 +    where
 +        F: FnMut(&str) -> bool + 'static,
 +    {
-         let mut i = 0;
-         while let Some(entry) = archive.next_entry() {
-             let entry = entry?;
-             let file_name = String::from_utf8(entry.header().identifier().to_vec())
-                 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?;
++        let read_cache = ReadCache::new(std::fs::File::open(&archive_path)?);
++        let archive = ArchiveFile::parse(&read_cache).unwrap();
 +        let archive_index = self.src_archives.len();
 +
-                 self.entries
-                     .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i }));
++        for entry in archive.members() {
++            let entry = entry.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
++            let file_name = String::from_utf8(entry.name().to_vec())
++                .map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
 +            if !skip(&file_name) {
-             i += 1;
++                self.entries.push((
++                    file_name.into_bytes(),
++                    ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
++                ));
 +            }
-         self.src_archives.push((archive_path.to_owned(), archive));
 +        }
 +
-                 ArchiveEntry::FromArchive { archive_index, entry_index } => {
++        self.src_archives.push(read_cache.into_inner());
 +        Ok(())
 +    }
 +
 +    fn update_symbols(&mut self) {}
 +
 +    fn build(mut self) {
 +        enum BuilderKind {
 +            Bsd(ar::Builder<File>),
 +            Gnu(ar::GnuBuilder<File>),
 +        }
 +
 +        let sess = self.sess;
 +
 +        let mut symbol_table = BTreeMap::new();
 +
 +        let mut entries = Vec::new();
 +
 +        for (entry_name, entry) in self.entries {
 +            // FIXME only read the symbol table of the object files to avoid having to keep all
 +            // object files in memory at once, or read them twice.
 +            let data = match entry {
-                     use std::io::Read;
-                     let (ref _src_archive_path, ref mut src_archive) =
-                         self.src_archives[archive_index];
-                     let mut entry = src_archive.jump_to_entry(entry_index).unwrap();
-                     let mut data = Vec::new();
-                     entry.read_to_end(&mut data).unwrap();
++                ArchiveEntry::FromArchive { archive_index, file_range } => {
 +                    // FIXME read symbols from symtab
-                             entry_name.as_bytes().to_vec(),
++                    let src_read_cache = &mut self.src_archives[archive_index];
++
++                    src_read_cache.seek(io::SeekFrom::Start(file_range.0)).unwrap();
++                    let mut data = std::vec::from_elem(0, usize::try_from(file_range.1).unwrap());
++                    src_read_cache.read_exact(&mut data).unwrap();
++
 +                    data
 +                }
 +                ArchiveEntry::File(file) => std::fs::read(file).unwrap_or_else(|err| {
 +                    sess.fatal(&format!(
 +                        "error while reading object file during archive building: {}",
 +                        err
 +                    ));
 +                }),
 +            };
 +
 +            if !self.no_builtin_ranlib {
 +                match object::File::parse(&*data) {
 +                    Ok(object) => {
 +                        symbol_table.insert(
-                                 entry_name, err
++                            entry_name.to_vec(),
 +                            object
 +                                .symbols()
 +                                .filter_map(|symbol| {
 +                                    if symbol.is_undefined()
 +                                        || symbol.is_local()
 +                                        || symbol.kind() != SymbolKind::Data
 +                                            && symbol.kind() != SymbolKind::Text
 +                                            && symbol.kind() != SymbolKind::Tls
 +                                    {
 +                                        None
 +                                    } else {
 +                                        symbol.name().map(|name| name.as_bytes().to_vec()).ok()
 +                                    }
 +                                })
 +                                .collect::<Vec<_>>(),
 +                        );
 +                    }
 +                    Err(err) => {
 +                        let err = err.to_string();
 +                        if err == "Unknown file magic" {
 +                            // Not an object file; skip it.
 +                        } else {
 +                            sess.fatal(&format!(
 +                                "error parsing `{}` during archive creation: {}",
-                     entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(),
++                                String::from_utf8_lossy(&entry_name),
++                                err
 +                            ));
 +                        }
 +                    }
 +                }
 +            }
 +
 +            entries.push((entry_name, data));
 +        }
 +
 +        let mut builder = if self.use_gnu_style_archive {
 +            BuilderKind::Gnu(
 +                ar::GnuBuilder::new(
 +                    File::create(&self.dst).unwrap_or_else(|err| {
 +                        sess.fatal(&format!(
 +                            "error opening destination during archive building: {}",
 +                            err
 +                        ));
 +                    }),
-             let header = ar::Header::new(entry_name.into_bytes(), data.len() as u64);
++                    entries.iter().map(|(name, _)| name.clone()).collect(),
 +                    ar::GnuSymbolTableFormat::Size32,
 +                    symbol_table,
 +                )
 +                .unwrap(),
 +            )
 +        } else {
 +            BuilderKind::Bsd(
 +                ar::Builder::new(
 +                    File::create(&self.dst).unwrap_or_else(|err| {
 +                        sess.fatal(&format!(
 +                            "error opening destination during archive building: {}",
 +                            err
 +                        ));
 +                    }),
 +                    symbol_table,
 +                )
 +                .unwrap(),
 +            )
 +        };
 +
 +        // Add all files
 +        for (entry_name, data) in entries.into_iter() {
++            let header = ar::Header::new(entry_name, data.len() as u64);
 +            match builder {
 +                BuilderKind::Bsd(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
 +                BuilderKind::Gnu(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
 +            }
 +        }
 +
 +        // Finalize archive
 +        std::mem::drop(builder);
 +
 +        if self.no_builtin_ranlib {
 +            let ranlib = crate::toolchain::get_toolchain_binary(self.sess, "ranlib");
 +
 +            // Run ranlib to be able to link the archive
 +            let status = std::process::Command::new(ranlib)
 +                .arg(self.dst)
 +                .status()
 +                .expect("Couldn't run ranlib");
 +
 +            if !status.success() {
 +                self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
 +            }
 +        }
 +    }
 +
 +    fn inject_dll_import_lib(
 +        &mut self,
 +        _lib_name: &str,
 +        _dll_imports: &[rustc_middle::middle::cstore::DllImport],
 +        _tmpdir: &rustc_data_structures::temp_dir::MaybeTempDir,
 +    ) {
 +        bug!("injecting dll imports is not supported");
 +    }
 +}
index a044b43b86470a3c3e83f99ea5eb0cec9d4ea92e,0000000000000000000000000000000000000000..b924f2085a0fc5546936a82df6019233e48f053a
mode 100644,000000..100644
--- /dev/null
@@@ -1,87 -1,0 +1,90 @@@
 +#![feature(rustc_private, once_cell)]
++#![warn(rust_2018_idioms)]
++#![warn(unused_lifetimes)]
++#![warn(unreachable_pub)]
 +
 +extern crate rustc_data_structures;
 +extern crate rustc_driver;
 +extern crate rustc_interface;
 +extern crate rustc_session;
 +extern crate rustc_target;
 +
 +use std::lazy::SyncLazy;
 +use std::panic;
 +
 +use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 +use rustc_interface::interface;
 +use rustc_session::config::ErrorOutputType;
 +use rustc_session::early_error;
 +use rustc_target::spec::PanicStrategy;
 +
 +const BUG_REPORT_URL: &str = "https://github.com/bjorn3/rustc_codegen_cranelift/issues/new";
 +
 +static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
 +    SyncLazy::new(|| {
 +        let hook = panic::take_hook();
 +        panic::set_hook(Box::new(|info| {
 +            // Invoke the default handler, which prints the actual panic message and optionally a backtrace
 +            (*DEFAULT_HOOK)(info);
 +
 +            // Separate the output with an empty line
 +            eprintln!();
 +
 +            // Print the ICE message
 +            rustc_driver::report_ice(info, BUG_REPORT_URL);
 +        }));
 +        hook
 +    });
 +
 +#[derive(Default)]
 +pub struct CraneliftPassesCallbacks {
 +    time_passes: bool,
 +}
 +
 +impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
 +    fn config(&mut self, config: &mut interface::Config) {
 +        // If a --prints=... option has been given, we don't print the "total"
 +        // time because it will mess up the --prints output. See #64339.
 +        self.time_passes = config.opts.prints.is_empty()
 +            && (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time);
 +
 +        config.opts.cg.panic = Some(PanicStrategy::Abort);
 +        config.opts.debugging_opts.panic_abort_tests = true;
 +        config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| {
 +            std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()
 +        }));
 +    }
 +}
 +
 +fn main() {
 +    let start_time = std::time::Instant::now();
 +    let start_rss = get_resident_set_size();
 +    rustc_driver::init_rustc_env_logger();
 +    let mut callbacks = CraneliftPassesCallbacks::default();
 +    SyncLazy::force(&DEFAULT_HOOK); // Install ice hook
 +    let exit_code = rustc_driver::catch_with_exit_code(|| {
 +        let args = std::env::args_os()
 +            .enumerate()
 +            .map(|(i, arg)| {
 +                arg.into_string().unwrap_or_else(|arg| {
 +                    early_error(
 +                        ErrorOutputType::default(),
 +                        &format!("Argument {} is not valid Unicode: {:?}", i, arg),
 +                    )
 +                })
 +            })
 +            .collect::<Vec<_>>();
 +        let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks);
 +        run_compiler.set_make_codegen_backend(Some(Box::new(move |_| {
 +            Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None })
 +        })));
 +        run_compiler.run()
 +    });
 +
 +    if callbacks.time_passes {
 +        let end_rss = get_resident_set_size();
 +        print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss);
 +    }
 +
 +    std::process::exit(exit_code)
 +}
index e7cd5edbbf654a2888e6b0ba4965da554f37f4a1,0000000000000000000000000000000000000000..bde4d71b9a33c4f385b9640410e68b0bff51d5e5
mode 100644,000000..100644
--- /dev/null
@@@ -1,91 -1,0 +1,93 @@@
- extern crate rustc_data_structures;
 +//! The only difference between this and cg_clif.rs is that this binary defaults to using cg_llvm
 +//! instead of cg_clif and requires `--clif` to use cg_clif and that this binary doesn't have JIT
 +//! support.
 +//! This is necessary as with Cargo `RUSTC` applies to both target crates and host crates. The host
 +//! crates must be built with cg_llvm as we are currently building a sysroot for cg_clif.
 +//! `RUSTFLAGS` however is only applied to target crates, so `--clif` would only be passed to the
 +//! target crates.
 +
 +#![feature(rustc_private)]
++#![warn(rust_2018_idioms)]
++#![warn(unused_lifetimes)]
++#![warn(unreachable_pub)]
 +
 +extern crate rustc_driver;
 +extern crate rustc_interface;
 +extern crate rustc_session;
 +extern crate rustc_target;
 +
 +use std::path::PathBuf;
 +
 +use rustc_interface::interface;
 +use rustc_session::config::ErrorOutputType;
 +use rustc_session::early_error;
 +use rustc_target::spec::PanicStrategy;
 +
 +fn find_sysroot() -> String {
 +    // Taken from https://github.com/Manishearth/rust-clippy/pull/911.
 +    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
 +    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
 +    match (home, toolchain) {
 +        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
 +        _ => option_env!("RUST_SYSROOT")
 +            .expect("need to specify RUST_SYSROOT env var or use rustup or multirust")
 +            .to_owned(),
 +    }
 +}
 +
 +pub struct CraneliftPassesCallbacks {
 +    use_clif: bool,
 +}
 +
 +impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
 +    fn config(&mut self, config: &mut interface::Config) {
 +        if !self.use_clif {
 +            config.opts.maybe_sysroot = Some(PathBuf::from(find_sysroot()));
 +            return;
 +        }
 +
 +        config.opts.cg.panic = Some(PanicStrategy::Abort);
 +        config.opts.debugging_opts.panic_abort_tests = true;
 +        config.opts.maybe_sysroot =
 +            Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned());
 +    }
 +}
 +
 +fn main() {
 +    rustc_driver::init_rustc_env_logger();
 +    rustc_driver::install_ice_hook();
 +    let exit_code = rustc_driver::catch_with_exit_code(|| {
 +        let mut use_clif = false;
 +
 +        let args = std::env::args_os()
 +            .enumerate()
 +            .map(|(i, arg)| {
 +                arg.into_string().unwrap_or_else(|arg| {
 +                    early_error(
 +                        ErrorOutputType::default(),
 +                        &format!("Argument {} is not valid Unicode: {:?}", i, arg),
 +                    )
 +                })
 +            })
 +            .filter(|arg| {
 +                if arg == "--clif" {
 +                    use_clif = true;
 +                    false
 +                } else {
 +                    true
 +                }
 +            })
 +            .collect::<Vec<_>>();
 +
 +        let mut callbacks = CraneliftPassesCallbacks { use_clif };
 +
 +        let mut run_compiler = rustc_driver::RunCompiler::new(&args, &mut callbacks);
 +        if use_clif {
 +            run_compiler.set_make_codegen_backend(Some(Box::new(move |_| {
 +                Box::new(rustc_codegen_cranelift::CraneliftCodegenBackend { config: None })
 +            })));
 +        }
 +        run_compiler.run()
 +    });
 +    std::process::exit(exit_code)
 +}
index fb6ccd7c535845b85d9582de3d82f4638bc1cbe4,0000000000000000000000000000000000000000..c8c2d50b03409619bcc05a668f4e0002a5d3e0d4
mode 100644,000000..100644
--- /dev/null
@@@ -1,192 -1,0 +1,192 @@@
- use crate::backend::WriteDebugInfo;
 +//! Write the debuginfo into an object file.
 +
++use cranelift_object::ObjectProduct;
 +use rustc_data_structures::fx::FxHashMap;
 +
 +use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
 +use gimli::{RunTimeEndian, SectionId};
 +
-     pub(crate) fn emit<P: WriteDebugInfo>(&mut self, product: &mut P) {
++use super::object::WriteDebugInfo;
 +use super::DebugContext;
 +
 +impl DebugContext<'_> {
++    pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
 +        let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
 +        let root = self.dwarf.unit.root();
 +        let root = self.dwarf.unit.get_mut(root);
 +        root.set(gimli::DW_AT_ranges, AttributeValue::RangeListRef(unit_range_list_id));
 +
 +        let mut sections = Sections::new(WriterRelocate::new(self.endian));
 +        self.dwarf.write(&mut sections).unwrap();
 +
 +        let mut section_map = FxHashMap::default();
 +        let _: Result<()> = sections.for_each_mut(|id, section| {
 +            if !section.writer.slice().is_empty() {
 +                let section_id = product.add_debug_section(id, section.writer.take());
 +                section_map.insert(id, section_id);
 +            }
 +            Ok(())
 +        });
 +
 +        let _: Result<()> = sections.for_each(|id, section| {
 +            if let Some(section_id) = section_map.get(&id) {
 +                for reloc in &section.relocs {
 +                    product.add_debug_reloc(&section_map, section_id, reloc);
 +                }
 +            }
 +            Ok(())
 +        });
 +    }
 +}
 +
 +#[derive(Clone)]
 +pub(crate) struct DebugReloc {
 +    pub(crate) offset: u32,
 +    pub(crate) size: u8,
 +    pub(crate) name: DebugRelocName,
 +    pub(crate) addend: i64,
 +    pub(crate) kind: object::RelocationKind,
 +}
 +
 +#[derive(Clone)]
 +pub(crate) enum DebugRelocName {
 +    Section(SectionId),
 +    Symbol(usize),
 +}
 +
 +/// A [`Writer`] that collects all necessary relocations.
 +#[derive(Clone)]
 +pub(super) struct WriterRelocate {
 +    pub(super) relocs: Vec<DebugReloc>,
 +    pub(super) writer: EndianVec<RunTimeEndian>,
 +}
 +
 +impl WriterRelocate {
 +    pub(super) fn new(endian: RunTimeEndian) -> Self {
 +        WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endian) }
 +    }
 +
 +    /// Perform the collected relocations to be usable for JIT usage.
 +    #[cfg(feature = "jit")]
 +    pub(super) fn relocate_for_jit(mut self, jit_module: &cranelift_jit::JITModule) -> Vec<u8> {
 +        use std::convert::TryInto;
 +
 +        for reloc in self.relocs.drain(..) {
 +            match reloc.name {
 +                super::DebugRelocName::Section(_) => unreachable!(),
 +                super::DebugRelocName::Symbol(sym) => {
 +                    let addr = jit_module.get_finalized_function(
 +                        cranelift_module::FuncId::from_u32(sym.try_into().unwrap()),
 +                    );
 +                    let val = (addr as u64 as i64 + reloc.addend) as u64;
 +                    self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap();
 +                }
 +            }
 +        }
 +        self.writer.into_vec()
 +    }
 +}
 +
 +impl Writer for WriterRelocate {
 +    type Endian = RunTimeEndian;
 +
 +    fn endian(&self) -> Self::Endian {
 +        self.writer.endian()
 +    }
 +
 +    fn len(&self) -> usize {
 +        self.writer.len()
 +    }
 +
 +    fn write(&mut self, bytes: &[u8]) -> Result<()> {
 +        self.writer.write(bytes)
 +    }
 +
 +    fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()> {
 +        self.writer.write_at(offset, bytes)
 +    }
 +
 +    fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
 +        match address {
 +            Address::Constant(val) => self.write_udata(val, size),
 +            Address::Symbol { symbol, addend } => {
 +                let offset = self.len() as u64;
 +                self.relocs.push(DebugReloc {
 +                    offset: offset as u32,
 +                    size,
 +                    name: DebugRelocName::Symbol(symbol),
 +                    addend: addend as i64,
 +                    kind: object::RelocationKind::Absolute,
 +                });
 +                self.write_udata(0, size)
 +            }
 +        }
 +    }
 +
 +    fn write_offset(&mut self, val: usize, section: SectionId, size: u8) -> Result<()> {
 +        let offset = self.len() as u32;
 +        self.relocs.push(DebugReloc {
 +            offset,
 +            size,
 +            name: DebugRelocName::Section(section),
 +            addend: val as i64,
 +            kind: object::RelocationKind::Absolute,
 +        });
 +        self.write_udata(0, size)
 +    }
 +
 +    fn write_offset_at(
 +        &mut self,
 +        offset: usize,
 +        val: usize,
 +        section: SectionId,
 +        size: u8,
 +    ) -> Result<()> {
 +        self.relocs.push(DebugReloc {
 +            offset: offset as u32,
 +            size,
 +            name: DebugRelocName::Section(section),
 +            addend: val as i64,
 +            kind: object::RelocationKind::Absolute,
 +        });
 +        self.write_udata_at(offset, 0, size)
 +    }
 +
 +    fn write_eh_pointer(&mut self, address: Address, eh_pe: gimli::DwEhPe, size: u8) -> Result<()> {
 +        match address {
 +            // Address::Constant arm copied from gimli
 +            Address::Constant(val) => {
 +                // Indirect doesn't matter here.
 +                let val = match eh_pe.application() {
 +                    gimli::DW_EH_PE_absptr => val,
 +                    gimli::DW_EH_PE_pcrel => {
 +                        // FIXME better handling of sign
 +                        let offset = self.len() as u64;
 +                        offset.wrapping_sub(val)
 +                    }
 +                    _ => {
 +                        return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe));
 +                    }
 +                };
 +                self.write_eh_pointer_data(val, eh_pe.format(), size)
 +            }
 +            Address::Symbol { symbol, addend } => match eh_pe.application() {
 +                gimli::DW_EH_PE_pcrel => {
 +                    let size = match eh_pe.format() {
 +                        gimli::DW_EH_PE_sdata4 => 4,
 +                        _ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
 +                    };
 +                    self.relocs.push(DebugReloc {
 +                        offset: self.len() as u32,
 +                        size,
 +                        name: DebugRelocName::Symbol(symbol),
 +                        addend,
 +                        kind: object::RelocationKind::Relative,
 +                    });
 +                    self.write_udata(0, size)
 +                }
 +                _ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
 +            },
 +        }
 +    }
 +}
index cabe3e43b342c5bc8f9e20bb336fb0bb9fdc2c50,0000000000000000000000000000000000000000..6d172817cb12ef129fd78aad78ec101d3fb1cf82
mode 100644,000000..100644
--- /dev/null
@@@ -1,382 -1,0 +1,383 @@@
 +//! Handling of everything related to debuginfo.
 +
 +mod emit;
 +mod line_info;
++mod object;
 +mod unwind;
 +
 +use crate::prelude::*;
 +
 +use rustc_index::vec::IndexVec;
 +
 +use cranelift_codegen::entity::EntityRef;
 +use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc};
 +use cranelift_codegen::isa::TargetIsa;
 +use cranelift_codegen::ValueLocRange;
 +
 +use gimli::write::{
 +    Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString, Location,
 +    LocationList, Range, RangeList, UnitEntryId,
 +};
 +use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
 +
 +pub(crate) use emit::{DebugReloc, DebugRelocName};
 +pub(crate) use unwind::UnwindContext;
 +
 +fn target_endian(tcx: TyCtxt<'_>) -> RunTimeEndian {
 +    use rustc_target::abi::Endian;
 +
 +    match tcx.data_layout.endian {
 +        Endian::Big => RunTimeEndian::Big,
 +        Endian::Little => RunTimeEndian::Little,
 +    }
 +}
 +
 +pub(crate) struct DebugContext<'tcx> {
 +    tcx: TyCtxt<'tcx>,
 +
 +    endian: RunTimeEndian,
 +
 +    dwarf: DwarfUnit,
 +    unit_range_list: RangeList,
 +
 +    types: FxHashMap<Ty<'tcx>, UnitEntryId>,
 +}
 +
 +impl<'tcx> DebugContext<'tcx> {
 +    pub(crate) fn new(tcx: TyCtxt<'tcx>, isa: &dyn TargetIsa) -> Self {
 +        let encoding = Encoding {
 +            format: Format::Dwarf32,
 +            // FIXME this should be configurable
 +            // macOS doesn't seem to support DWARF > 3
 +            // 5 version is required for md5 file hash
 +            version: if tcx.sess.target.is_like_osx {
 +                3
 +            } else {
 +                // FIXME change to version 5 once the gdb and lldb shipping with the latest debian
 +                // support it.
 +                4
 +            },
 +            address_size: isa.frontend_config().pointer_bytes(),
 +        };
 +
 +        let mut dwarf = DwarfUnit::new(encoding);
 +
 +        let producer = format!(
 +            "cg_clif (rustc {}, cranelift {})",
 +            rustc_interface::util::version_str().unwrap_or("unknown version"),
 +            cranelift_codegen::VERSION,
 +        );
 +        let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped).into_owned();
 +        let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
 +            Some(path) => {
 +                let name = path.to_string_lossy().into_owned();
 +                (name, None)
 +            }
 +            None => (tcx.crate_name(LOCAL_CRATE).to_string(), None),
 +        };
 +
 +        let mut line_program = LineProgram::new(
 +            encoding,
 +            LineEncoding::default(),
 +            LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings),
 +            LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings),
 +            file_info,
 +        );
 +        line_program.file_has_md5 = file_info.is_some();
 +
 +        dwarf.unit.line_program = line_program;
 +
 +        {
 +            let name = dwarf.strings.add(name);
 +            let comp_dir = dwarf.strings.add(comp_dir);
 +
 +            let root = dwarf.unit.root();
 +            let root = dwarf.unit.get_mut(root);
 +            root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer)));
 +            root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust));
 +            root.set(gimli::DW_AT_name, AttributeValue::StringRef(name));
 +            root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir));
 +            root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0)));
 +        }
 +
 +        DebugContext {
 +            tcx,
 +
 +            endian: target_endian(tcx),
 +
 +            dwarf,
 +            unit_range_list: RangeList(Vec::new()),
 +
 +            types: FxHashMap::default(),
 +        }
 +    }
 +
 +    fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId {
 +        if let Some(type_id) = self.types.get(ty) {
 +            return *type_id;
 +        }
 +
 +        let new_entry = |dwarf: &mut DwarfUnit, tag| dwarf.unit.add(dwarf.unit.root(), tag);
 +
 +        let primitive = |dwarf: &mut DwarfUnit, ate| {
 +            let type_id = new_entry(dwarf, gimli::DW_TAG_base_type);
 +            let type_entry = dwarf.unit.get_mut(type_id);
 +            type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate));
 +            type_id
 +        };
 +
 +        let name = format!("{}", ty);
 +        let layout = self.tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap();
 +
 +        let type_id = match ty.kind() {
 +            ty::Bool => primitive(&mut self.dwarf, gimli::DW_ATE_boolean),
 +            ty::Char => primitive(&mut self.dwarf, gimli::DW_ATE_UTF),
 +            ty::Uint(_) => primitive(&mut self.dwarf, gimli::DW_ATE_unsigned),
 +            ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed),
 +            ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float),
 +            ty::Ref(_, pointee_ty, _mutbl)
 +            | ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => {
 +                let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type);
 +
 +                // Ensure that type is inserted before recursing to avoid duplicates
 +                self.types.insert(ty, type_id);
 +
 +                let pointee = self.dwarf_ty(pointee_ty);
 +
 +                let type_entry = self.dwarf.unit.get_mut(type_id);
 +
 +                //type_entry.set(gimli::DW_AT_mutable, AttributeValue::Flag(mutbl == rustc_hir::Mutability::Mut));
 +                type_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(pointee));
 +
 +                type_id
 +            }
 +            ty::Adt(adt_def, _substs) if adt_def.is_struct() && !layout.is_unsized() => {
 +                let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type);
 +
 +                // Ensure that type is inserted before recursing to avoid duplicates
 +                self.types.insert(ty, type_id);
 +
 +                let variant = adt_def.non_enum_variant();
 +
 +                for (field_idx, field_def) in variant.fields.iter().enumerate() {
 +                    let field_offset = layout.fields.offset(field_idx);
 +                    let field_layout = layout.field(
 +                        &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
 +                        field_idx,
 +                    );
 +
 +                    let field_type = self.dwarf_ty(field_layout.ty);
 +
 +                    let field_id = self.dwarf.unit.add(type_id, gimli::DW_TAG_member);
 +                    let field_entry = self.dwarf.unit.get_mut(field_id);
 +
 +                    field_entry.set(
 +                        gimli::DW_AT_name,
 +                        AttributeValue::String(field_def.ident.as_str().to_string().into_bytes()),
 +                    );
 +                    field_entry.set(
 +                        gimli::DW_AT_data_member_location,
 +                        AttributeValue::Udata(field_offset.bytes()),
 +                    );
 +                    field_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(field_type));
 +                }
 +
 +                type_id
 +            }
 +            _ => new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type),
 +        };
 +
 +        let type_entry = self.dwarf.unit.get_mut(type_id);
 +
 +        type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
 +        type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes()));
 +
 +        self.types.insert(ty, type_id);
 +
 +        type_id
 +    }
 +
 +    fn define_local(&mut self, scope: UnitEntryId, name: String, ty: Ty<'tcx>) -> UnitEntryId {
 +        let dw_ty = self.dwarf_ty(ty);
 +
 +        let var_id = self.dwarf.unit.add(scope, gimli::DW_TAG_variable);
 +        let var_entry = self.dwarf.unit.get_mut(var_id);
 +
 +        var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes()));
 +        var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty));
 +
 +        var_id
 +    }
 +
 +    pub(crate) fn define_function(
 +        &mut self,
 +        instance: Instance<'tcx>,
 +        func_id: FuncId,
 +        name: &str,
 +        isa: &dyn TargetIsa,
 +        context: &Context,
 +        source_info_set: &indexmap::IndexSet<SourceInfo>,
 +        local_map: IndexVec<mir::Local, CPlace<'tcx>>,
 +    ) {
 +        let symbol = func_id.as_u32() as usize;
 +        let mir = self.tcx.instance_mir(instance.def);
 +
 +        // FIXME: add to appropriate scope instead of root
 +        let scope = self.dwarf.unit.root();
 +
 +        let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram);
 +        let entry = self.dwarf.unit.get_mut(entry_id);
 +        let name_id = self.dwarf.strings.add(name);
 +        // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
 +        entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id));
 +        entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id));
 +
 +        let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set);
 +
 +        self.unit_range_list.0.push(Range::StartLength {
 +            begin: Address::Symbol { symbol, addend: 0 },
 +            length: u64::from(end),
 +        });
 +
 +        let func_entry = self.dwarf.unit.get_mut(entry_id);
 +        // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
 +        func_entry.set(
 +            gimli::DW_AT_low_pc,
 +            AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
 +        );
 +        // Using Udata for DW_AT_high_pc requires at least DWARF4
 +        func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
 +
 +        // FIXME make it more reliable and implement scopes before re-enabling this.
 +        if false {
 +            let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
 +
 +            for (local, _local_decl) in mir.local_decls.iter_enumerated() {
 +                let ty = self.tcx.subst_and_normalize_erasing_regions(
 +                    instance.substs,
 +                    ty::ParamEnv::reveal_all(),
 +                    mir.local_decls[local].ty,
 +                );
 +                let var_id = self.define_local(entry_id, format!("{:?}", local), ty);
 +
 +                let location = place_location(
 +                    self,
 +                    isa,
 +                    symbol,
 +                    context,
 +                    &local_map,
 +                    &value_labels_ranges,
 +                    Place { local, projection: ty::List::empty() },
 +                );
 +
 +                let var_entry = self.dwarf.unit.get_mut(var_id);
 +                var_entry.set(gimli::DW_AT_location, location);
 +            }
 +        }
 +
 +        // FIXME create locals for all entries in mir.var_debug_info
 +    }
 +}
 +
 +fn place_location<'tcx>(
 +    debug_context: &mut DebugContext<'tcx>,
 +    isa: &dyn TargetIsa,
 +    symbol: usize,
 +    context: &Context,
 +    local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
 +    #[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
 +        ValueLabel,
 +        Vec<ValueLocRange>,
 +    >,
 +    place: Place<'tcx>,
 +) -> AttributeValue {
 +    assert!(place.projection.is_empty()); // FIXME implement them
 +
 +    match local_map[place.local].inner() {
 +        CPlaceInner::Var(_local, var) => {
 +            let value_label = cranelift_codegen::ir::ValueLabel::new(var.index());
 +            if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) {
 +                let loc_list = LocationList(
 +                    value_loc_ranges
 +                        .iter()
 +                        .map(|value_loc_range| Location::StartEnd {
 +                            begin: Address::Symbol {
 +                                symbol,
 +                                addend: i64::from(value_loc_range.start),
 +                            },
 +                            end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
 +                            data: translate_loc(
 +                                isa,
 +                                value_loc_range.loc,
 +                                &context.func.stack_slots,
 +                            )
 +                            .unwrap(),
 +                        })
 +                        .collect(),
 +                );
 +                let loc_list_id = debug_context.dwarf.unit.locations.add(loc_list);
 +
 +                AttributeValue::LocationListRef(loc_list_id)
 +            } else {
 +                // FIXME set value labels for unused locals
 +
 +                AttributeValue::Exprloc(Expression::new())
 +            }
 +        }
 +        CPlaceInner::VarPair(_, _, _) => {
 +            // FIXME implement this
 +
 +            AttributeValue::Exprloc(Expression::new())
 +        }
 +        CPlaceInner::VarLane(_, _, _) => {
 +            // FIXME implement this
 +
 +            AttributeValue::Exprloc(Expression::new())
 +        }
 +        CPlaceInner::Addr(_, _) => {
 +            // FIXME implement this (used by arguments and returns)
 +
 +            AttributeValue::Exprloc(Expression::new())
 +
 +            // For PointerBase::Stack:
 +            //AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot), &context.func.stack_slots).unwrap())
 +        }
 +    }
 +}
 +
 +// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
 +fn translate_loc(
 +    isa: &dyn TargetIsa,
 +    loc: LabelValueLoc,
 +    stack_slots: &StackSlots,
 +) -> Option<Expression> {
 +    match loc {
 +        LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => {
 +            let machine_reg = isa.map_dwarf_register(reg).unwrap();
 +            let mut expr = Expression::new();
 +            expr.op_reg(gimli::Register(machine_reg));
 +            Some(expr)
 +        }
 +        LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
 +            if let Some(ss_offset) = stack_slots[ss].offset {
 +                let mut expr = Expression::new();
 +                expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16);
 +                Some(expr)
 +            } else {
 +                None
 +            }
 +        }
 +        LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(),
 +        LabelValueLoc::Reg(reg) => {
 +            let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
 +            let mut expr = Expression::new();
 +            expr.op_reg(gimli::Register(machine_reg));
 +            Some(expr)
 +        }
 +        LabelValueLoc::SPOffset(offset) => {
 +            let mut expr = Expression::new();
 +            expr.op_breg(X86_64::RSP, offset);
 +            Some(expr)
 +        }
 +    }
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9984dc92c44d09b15d7dec2ae66322388d9ea72e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,85 @@@
++use std::convert::{TryFrom, TryInto};
++
++use rustc_data_structures::fx::FxHashMap;
++
++use cranelift_module::FuncId;
++use cranelift_object::ObjectProduct;
++
++use object::write::{Relocation, StandardSegment};
++use object::{RelocationEncoding, SectionKind};
++
++use gimli::SectionId;
++
++use crate::debuginfo::{DebugReloc, DebugRelocName};
++
++pub(super) trait WriteDebugInfo {
++    type SectionId: Copy;
++
++    fn add_debug_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
++    fn add_debug_reloc(
++        &mut self,
++        section_map: &FxHashMap<SectionId, Self::SectionId>,
++        from: &Self::SectionId,
++        reloc: &DebugReloc,
++    );
++}
++
++impl WriteDebugInfo for ObjectProduct {
++    type SectionId = (object::write::SectionId, object::write::SymbolId);
++
++    fn add_debug_section(
++        &mut self,
++        id: SectionId,
++        data: Vec<u8>,
++    ) -> (object::write::SectionId, object::write::SymbolId) {
++        let name = if self.object.format() == object::BinaryFormat::MachO {
++            id.name().replace('.', "__") // machO expects __debug_info instead of .debug_info
++        } else {
++            id.name().to_string()
++        }
++        .into_bytes();
++
++        let segment = self.object.segment_name(StandardSegment::Debug).to_vec();
++        // FIXME use SHT_X86_64_UNWIND for .eh_frame
++        let section_id = self.object.add_section(
++            segment,
++            name,
++            if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug },
++        );
++        self.object
++            .section_mut(section_id)
++            .set_data(data, if id == SectionId::EhFrame { 8 } else { 1 });
++        let symbol_id = self.object.section_symbol(section_id);
++        (section_id, symbol_id)
++    }
++
++    fn add_debug_reloc(
++        &mut self,
++        section_map: &FxHashMap<SectionId, Self::SectionId>,
++        from: &Self::SectionId,
++        reloc: &DebugReloc,
++    ) {
++        let (symbol, symbol_offset) = match reloc.name {
++            DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
++            DebugRelocName::Symbol(id) => {
++                let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
++                self.object
++                    .symbol_section_and_offset(symbol_id)
++                    .expect("Debug reloc for undef sym???")
++            }
++        };
++        self.object
++            .add_relocation(
++                from.0,
++                Relocation {
++                    offset: u64::from(reloc.offset),
++                    symbol,
++                    kind: reloc.kind,
++                    encoding: RelocationEncoding::Generic,
++                    size: reloc.size * 8,
++                    addend: i64::try_from(symbol_offset).unwrap() + reloc.addend,
++                },
++            )
++            .unwrap();
++    }
++}
index d1251e749f31fe90687312a9ff7837d7a0149d9b,0000000000000000000000000000000000000000..f0896ea0e167fd09d2ec81e8f29b04e86484cdee
mode 100644,000000..100644
--- /dev/null
@@@ -1,130 -1,0 +1,131 @@@
- use crate::backend::WriteDebugInfo;
 +//! Unwind info generation (`.eh_frame`)
 +
 +use crate::prelude::*;
 +
 +use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
 +
++use cranelift_object::ObjectProduct;
 +use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
 +use gimli::RunTimeEndian;
 +
-     pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
++use super::object::WriteDebugInfo;
 +
 +pub(crate) struct UnwindContext {
 +    endian: RunTimeEndian,
 +    frame_table: FrameTable,
 +    cie_id: Option<CieId>,
 +}
 +
 +impl UnwindContext {
 +    pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, pic_eh_frame: bool) -> Self {
 +        let endian = super::target_endian(tcx);
 +        let mut frame_table = FrameTable::default();
 +
 +        let cie_id = if let Some(mut cie) = isa.create_systemv_cie() {
 +            if pic_eh_frame {
 +                cie.fde_address_encoding =
 +                    gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0);
 +            }
 +            Some(frame_table.add_cie(cie))
 +        } else {
 +            None
 +        };
 +
 +        UnwindContext { endian, frame_table, cie_id }
 +    }
 +
 +    pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
 +        let unwind_info = if let Some(unwind_info) = context.create_unwind_info(isa).unwrap() {
 +            unwind_info
 +        } else {
 +            return;
 +        };
 +
 +        match unwind_info {
 +            UnwindInfo::SystemV(unwind_info) => {
 +                self.frame_table.add_fde(
 +                    self.cie_id.unwrap(),
 +                    unwind_info
 +                        .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
 +                );
 +            }
 +            UnwindInfo::WindowsX64(_) => {
 +                // FIXME implement this
 +            }
 +            unwind_info => unimplemented!("{:?}", unwind_info),
 +        }
 +    }
 +
++    pub(crate) fn emit(self, product: &mut ObjectProduct) {
 +        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(self.endian));
 +        self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
 +
 +        if !eh_frame.0.writer.slice().is_empty() {
 +            let id = eh_frame.id();
 +            let section_id = product.add_debug_section(id, eh_frame.0.writer.into_vec());
 +            let mut section_map = FxHashMap::default();
 +            section_map.insert(id, section_id);
 +
 +            for reloc in &eh_frame.0.relocs {
 +                product.add_debug_reloc(&section_map, &section_id, reloc);
 +            }
 +        }
 +    }
 +
 +    #[cfg(all(feature = "jit", windows))]
 +    pub(crate) unsafe fn register_jit(self, _jit_module: &cranelift_jit::JITModule) {}
 +
 +    #[cfg(all(feature = "jit", not(windows)))]
 +    pub(crate) unsafe fn register_jit(self, jit_module: &cranelift_jit::JITModule) {
 +        let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(self.endian));
 +        self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
 +
 +        if eh_frame.0.writer.slice().is_empty() {
 +            return;
 +        }
 +
 +        let mut eh_frame = eh_frame.0.relocate_for_jit(jit_module);
 +
 +        // GCC expects a terminating "empty" length, so write a 0 length at the end of the table.
 +        eh_frame.extend(&[0, 0, 0, 0]);
 +
 +        // FIXME support unregistering unwind tables once cranelift-jit supports deallocating
 +        // individual functions
 +        #[allow(unused_variables)]
 +        let (eh_frame, eh_frame_len, _) = Vec::into_raw_parts(eh_frame);
 +
 +        // =======================================================================
 +        // Everything after this line up to the end of the file is loosly based on
 +        // https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs
 +        #[cfg(target_os = "macos")]
 +        {
 +            // On macOS, `__register_frame` takes a pointer to a single FDE
 +            let start = eh_frame;
 +            let end = start.add(eh_frame_len);
 +            let mut current = start;
 +
 +            // Walk all of the entries in the frame table and register them
 +            while current < end {
 +                let len = std::ptr::read::<u32>(current as *const u32) as usize;
 +
 +                // Skip over the CIE
 +                if current != start {
 +                    __register_frame(current);
 +                }
 +
 +                // Move to the next table entry (+4 because the length itself is not inclusive)
 +                current = current.add(len + 4);
 +            }
 +        }
 +        #[cfg(not(target_os = "macos"))]
 +        {
 +            // On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
 +            __register_frame(eh_frame);
 +        }
 +    }
 +}
 +
 +extern "C" {
 +    // libunwind import
 +    fn __register_frame(fde: *const u8);
 +}
index 3de706ed6d7afdb547d7171819dbc0a2a711b453,0000000000000000000000000000000000000000..40cbc5e1a7ee473fd317a4f046b602e11722bde6
mode 100644,000000..100644
--- /dev/null
@@@ -1,419 -1,0 +1,428 @@@
- use cranelift_object::ObjectModule;
 +//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
 +//! standalone executable.
 +
 +use std::path::PathBuf;
 +
 +use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 +use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
 +use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 +use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 +use rustc_middle::middle::cstore::EncodedMetadata;
 +use rustc_middle::mir::mono::{CodegenUnit, MonoItem};
 +use rustc_session::cgu_reuse_tracker::CguReuse;
 +use rustc_session::config::{DebugInfo, OutputType};
++use rustc_session::Session;
 +
-     let mut module = crate::backend::make_module(tcx.sess, isa, cgu_name.as_str().to_string());
++use cranelift_codegen::isa::TargetIsa;
++use cranelift_object::{ObjectBuilder, ObjectModule};
 +
 +use crate::{prelude::*, BackendConfig};
 +
 +struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
 +
 +impl<HCX> HashStable<HCX> for ModuleCodegenResult {
 +    fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
 +        // do nothing
 +    }
 +}
 +
++fn make_module(sess: &Session, isa: Box<dyn TargetIsa>, name: String) -> ObjectModule {
++    let mut builder =
++        ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap();
++    // Unlike cg_llvm, cg_clif defaults to disabling -Zfunction-sections. For cg_llvm binary size
++    // is important, while cg_clif cares more about compilation times. Enabling -Zfunction-sections
++    // can easily double the amount of time necessary to perform linking.
++    builder.per_function_section(sess.opts.debugging_opts.function_sections.unwrap_or(false));
++    ObjectModule::new(builder)
++}
++
 +fn emit_module(
 +    tcx: TyCtxt<'_>,
 +    backend_config: &BackendConfig,
 +    name: String,
 +    kind: ModuleKind,
 +    module: ObjectModule,
 +    debug: Option<DebugContext<'_>>,
 +    unwind_context: UnwindContext,
 +) -> ModuleCodegenResult {
 +    let mut product = module.finish();
 +
 +    if let Some(mut debug) = debug {
 +        debug.emit(&mut product);
 +    }
 +
 +    unwind_context.emit(&mut product);
 +
 +    let tmp_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(&name));
 +    let obj = product.object.write().unwrap();
 +    if let Err(err) = std::fs::write(&tmp_file, obj) {
 +        tcx.sess.fatal(&format!("error writing object file: {}", err));
 +    }
 +
 +    let work_product = if backend_config.disable_incr_cache {
 +        None
 +    } else {
 +        rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
 +            tcx.sess,
 +            &name,
 +            &Some(tmp_file.clone()),
 +        )
 +    };
 +
 +    ModuleCodegenResult(
 +        CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None },
 +        work_product,
 +    )
 +}
 +
 +fn reuse_workproduct_for_cgu(
 +    tcx: TyCtxt<'_>,
 +    cgu: &CodegenUnit<'_>,
 +    work_products: &mut FxHashMap<WorkProductId, WorkProduct>,
 +) -> CompiledModule {
 +    let mut object = None;
 +    let work_product = cgu.work_product(tcx);
 +    if let Some(saved_file) = &work_product.saved_file {
 +        let obj_out =
 +            tcx.output_filenames(()).temp_path(OutputType::Object, Some(&cgu.name().as_str()));
 +        object = Some(obj_out.clone());
 +        let source_file = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, &saved_file);
 +        if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
 +            tcx.sess.err(&format!(
 +                "unable to copy {} to {}: {}",
 +                source_file.display(),
 +                obj_out.display(),
 +                err
 +            ));
 +        }
 +    }
 +
 +    work_products.insert(cgu.work_product_id(), work_product);
 +
 +    CompiledModule {
 +        name: cgu.name().to_string(),
 +        kind: ModuleKind::Regular,
 +        object,
 +        dwarf_object: None,
 +        bytecode: None,
 +    }
 +}
 +
 +fn module_codegen(
 +    tcx: TyCtxt<'_>,
 +    (backend_config, cgu_name): (BackendConfig, rustc_span::Symbol),
 +) -> ModuleCodegenResult {
 +    let cgu = tcx.codegen_unit(cgu_name);
 +    let mono_items = cgu.items_in_deterministic_order(tcx);
 +
 +    let isa = crate::build_isa(tcx.sess, &backend_config);
-     let mut allocator_module =
-         crate::backend::make_module(tcx.sess, isa, "allocator_shim".to_string());
++    let mut module = make_module(tcx.sess, isa, cgu_name.as_str().to_string());
 +
 +    let mut cx = crate::CodegenCx::new(
 +        tcx,
 +        backend_config.clone(),
 +        module.isa(),
 +        tcx.sess.opts.debuginfo != DebugInfo::None,
 +    );
 +    super::predefine_mono_items(tcx, &mut module, &mono_items);
 +    for (mono_item, _) in mono_items {
 +        match mono_item {
 +            MonoItem::Fn(inst) => {
 +                cx.tcx
 +                    .sess
 +                    .time("codegen fn", || crate::base::codegen_fn(&mut cx, &mut module, inst));
 +            }
 +            MonoItem::Static(def_id) => crate::constant::codegen_static(tcx, &mut module, def_id),
 +            MonoItem::GlobalAsm(item_id) => {
 +                let item = cx.tcx.hir().item(item_id);
 +                if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
 +                    if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
 +                        cx.global_asm.push_str("\n.intel_syntax noprefix\n");
 +                    } else {
 +                        cx.global_asm.push_str("\n.att_syntax\n");
 +                    }
 +                    for piece in asm.template {
 +                        match *piece {
 +                            InlineAsmTemplatePiece::String(ref s) => cx.global_asm.push_str(s),
 +                            InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
 +                        }
 +                    }
 +                    cx.global_asm.push_str("\n.att_syntax\n\n");
 +                } else {
 +                    bug!("Expected GlobalAsm found {:?}", item);
 +                }
 +            }
 +        }
 +    }
 +    crate::main_shim::maybe_create_entry_wrapper(
 +        tcx,
 +        &mut module,
 +        &mut cx.unwind_context,
 +        false,
 +        cgu.is_primary(),
 +    );
 +
 +    let debug_context = cx.debug_context;
 +    let unwind_context = cx.unwind_context;
 +    let codegen_result = tcx.sess.time("write object file", || {
 +        emit_module(
 +            tcx,
 +            &backend_config,
 +            cgu.name().as_str().to_string(),
 +            ModuleKind::Regular,
 +            module,
 +            debug_context,
 +            unwind_context,
 +        )
 +    });
 +
 +    codegen_global_asm(tcx, &cgu.name().as_str(), &cx.global_asm);
 +
 +    codegen_result
 +}
 +
 +pub(crate) fn run_aot(
 +    tcx: TyCtxt<'_>,
 +    backend_config: BackendConfig,
 +    metadata: EncodedMetadata,
 +    need_metadata_module: bool,
 +) -> Box<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)> {
 +    let mut work_products = FxHashMap::default();
 +
 +    let cgus = if tcx.sess.opts.output_types.should_codegen() {
 +        tcx.collect_and_partition_mono_items(()).1
 +    } else {
 +        // If only `--emit metadata` is used, we shouldn't perform any codegen.
 +        // Also `tcx.collect_and_partition_mono_items` may panic in that case.
 +        &[]
 +    };
 +
 +    if tcx.dep_graph.is_fully_enabled() {
 +        for cgu in &*cgus {
 +            tcx.ensure().codegen_unit(cgu.name());
 +        }
 +    }
 +
 +    let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || {
 +        cgus.iter()
 +            .map(|cgu| {
 +                let cgu_reuse = determine_cgu_reuse(tcx, cgu);
 +                tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
 +
 +                match cgu_reuse {
 +                    _ if backend_config.disable_incr_cache => {}
 +                    CguReuse::No => {}
 +                    CguReuse::PreLto => {
 +                        return reuse_workproduct_for_cgu(tcx, &*cgu, &mut work_products);
 +                    }
 +                    CguReuse::PostLto => unreachable!(),
 +                }
 +
 +                let dep_node = cgu.codegen_dep_node(tcx);
 +                let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task(
 +                    dep_node,
 +                    tcx,
 +                    (backend_config.clone(), cgu.name()),
 +                    module_codegen,
 +                    rustc_middle::dep_graph::hash_result,
 +                );
 +
 +                if let Some((id, product)) = work_product {
 +                    work_products.insert(id, product);
 +                }
 +
 +                module
 +            })
 +            .collect::<Vec<_>>()
 +    });
 +
 +    tcx.sess.abort_if_errors();
 +
 +    let isa = crate::build_isa(tcx.sess, &backend_config);
-             let obj = crate::backend::with_object(tcx.sess, &metadata_cgu_name, |object| {
-                 crate::metadata::write_metadata(tcx, object);
-             });
++    let mut allocator_module = make_module(tcx.sess, isa, "allocator_shim".to_string());
 +    assert_eq!(pointer_ty(tcx), allocator_module.target_config().pointer_type());
 +    let mut allocator_unwind_context = UnwindContext::new(tcx, allocator_module.isa(), true);
 +    let created_alloc_shim =
 +        crate::allocator::codegen(tcx, &mut allocator_module, &mut allocator_unwind_context);
 +
 +    let allocator_module = if created_alloc_shim {
 +        let ModuleCodegenResult(module, work_product) = emit_module(
 +            tcx,
 +            &backend_config,
 +            "allocator_shim".to_string(),
 +            ModuleKind::Allocator,
 +            allocator_module,
 +            None,
 +            allocator_unwind_context,
 +        );
 +        if let Some((id, product)) = work_product {
 +            work_products.insert(id, product);
 +        }
 +        Some(module)
 +    } else {
 +        None
 +    };
 +
 +    let metadata_module = if need_metadata_module {
 +        let _timer = tcx.prof.generic_activity("codegen crate metadata");
 +        let (metadata_cgu_name, tmp_file) = tcx.sess.time("write compressed metadata", || {
 +            use rustc_middle::mir::mono::CodegenUnitNameBuilder;
 +
 +            let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
 +            let metadata_cgu_name = cgu_name_builder
 +                .build_cgu_name(LOCAL_CRATE, &["crate"], Some("metadata"))
 +                .as_str()
 +                .to_string();
 +
 +            let tmp_file =
 +                tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
 +
++            let obj = crate::metadata::new_metadata_object(tcx, &metadata_cgu_name, &metadata);
 +
 +            if let Err(err) = std::fs::write(&tmp_file, obj) {
 +                tcx.sess.fatal(&format!("error writing metadata object file: {}", err));
 +            }
 +
 +            (metadata_cgu_name, tmp_file)
 +        });
 +
 +        Some(CompiledModule {
 +            name: metadata_cgu_name,
 +            kind: ModuleKind::Metadata,
 +            object: Some(tmp_file),
 +            dwarf_object: None,
 +            bytecode: None,
 +        })
 +    } else {
 +        None
 +    };
 +
 +    // FIXME handle `-Ctarget-cpu=native`
 +    let target_cpu =
 +        tcx.sess.opts.cg.target_cpu.as_ref().unwrap_or(&tcx.sess.target.cpu).to_owned();
 +    Box::new((
 +        CodegenResults {
 +            modules,
 +            allocator_module,
 +            metadata_module,
 +            metadata,
 +            crate_info: CrateInfo::new(tcx, target_cpu),
 +        },
 +        work_products,
 +    ))
 +}
 +
 +fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
 +    use std::io::Write;
 +    use std::process::{Command, Stdio};
 +
 +    if global_asm.is_empty() {
 +        return;
 +    }
 +
 +    if cfg!(not(feature = "inline_asm"))
 +        || tcx.sess.target.is_like_osx
 +        || tcx.sess.target.is_like_windows
 +    {
 +        if global_asm.contains("__rust_probestack") {
 +            return;
 +        }
 +
 +        // FIXME fix linker error on macOS
 +        if cfg!(not(feature = "inline_asm")) {
 +            tcx.sess.fatal(
 +                "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
 +            );
 +        } else {
 +            tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows");
 +        }
 +    }
 +
 +    let assembler = crate::toolchain::get_toolchain_binary(tcx.sess, "as");
 +    let linker = crate::toolchain::get_toolchain_binary(tcx.sess, "ld");
 +
 +    // Remove all LLVM style comments
 +    let global_asm = global_asm
 +        .lines()
 +        .map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
 +        .collect::<Vec<_>>()
 +        .join("\n");
 +
 +    let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
 +
 +    // Assemble `global_asm`
 +    let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
 +    let mut child = Command::new(assembler)
 +        .arg("-o")
 +        .arg(&global_asm_object_file)
 +        .stdin(Stdio::piped())
 +        .spawn()
 +        .expect("Failed to spawn `as`.");
 +    child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
 +    let status = child.wait().expect("Failed to wait for `as`.");
 +    if !status.success() {
 +        tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm));
 +    }
 +
 +    // Link the global asm and main object file together
 +    let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
 +    std::fs::rename(&output_object_file, &main_object_file).unwrap();
 +    let status = Command::new(linker)
 +        .arg("-r") // Create a new object file
 +        .arg("-o")
 +        .arg(output_object_file)
 +        .arg(&main_object_file)
 +        .arg(&global_asm_object_file)
 +        .status()
 +        .unwrap();
 +    if !status.success() {
 +        tcx.sess.fatal(&format!(
 +            "Failed to link `{}` and `{}` together",
 +            main_object_file.display(),
 +            global_asm_object_file.display(),
 +        ));
 +    }
 +
 +    std::fs::remove_file(global_asm_object_file).unwrap();
 +    std::fs::remove_file(main_object_file).unwrap();
 +}
 +
 +fn add_file_stem_postfix(mut path: PathBuf, postfix: &str) -> PathBuf {
 +    let mut new_filename = path.file_stem().unwrap().to_owned();
 +    new_filename.push(postfix);
 +    if let Some(extension) = path.extension() {
 +        new_filename.push(".");
 +        new_filename.push(extension);
 +    }
 +    path.set_file_name(new_filename);
 +    path
 +}
 +
 +// Adapted from https://github.com/rust-lang/rust/blob/303d8aff6092709edd4dbd35b1c88e9aa40bf6d8/src/librustc_codegen_ssa/base.rs#L922-L953
 +fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguReuse {
 +    if !tcx.dep_graph.is_fully_enabled() {
 +        return CguReuse::No;
 +    }
 +
 +    let work_product_id = &cgu.work_product_id();
 +    if tcx.dep_graph.previous_work_product(work_product_id).is_none() {
 +        // We don't have anything cached for this CGU. This can happen
 +        // if the CGU did not exist in the previous session.
 +        return CguReuse::No;
 +    }
 +
 +    // Try to mark the CGU as green. If it we can do so, it means that nothing
 +    // affecting the LLVM module has changed and we can re-use a cached version.
 +    // If we compile with any kind of LTO, this means we can re-use the bitcode
 +    // of the Pre-LTO stage (possibly also the Post-LTO version but we'll only
 +    // know that later). If we are not doing LTO, there is only one optimized
 +    // version of each module, so we re-use that.
 +    let dep_node = cgu.codegen_dep_node(tcx);
 +    assert!(
 +        !tcx.dep_graph.dep_node_exists(&dep_node),
 +        "CompileCodegenUnit dep-node for CGU `{}` already exists before marking.",
 +        cgu.name()
 +    );
 +
 +    if tcx.try_mark_green(&dep_node) { CguReuse::PreLto } else { CguReuse::No }
 +}
index 87193e3ef5341a060567ac6dac79fce80d6a62a3,0000000000000000000000000000000000000000..2ceccdd34994d038781f6509bac70cb76f00d086
mode 100644,000000..100644
--- /dev/null
@@@ -1,311 -1,0 +1,311 @@@
- #![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts, once_cell)]
++#![feature(rustc_private, decl_macro)]
++#![cfg_attr(feature = "jit", feature(never_type, vec_into_raw_parts, once_cell))]
 +#![warn(rust_2018_idioms)]
 +#![warn(unused_lifetimes)]
 +#![warn(unreachable_pub)]
 +
 +extern crate snap;
 +#[macro_use]
 +extern crate rustc_middle;
 +extern crate rustc_ast;
 +extern crate rustc_codegen_ssa;
 +extern crate rustc_data_structures;
 +extern crate rustc_errors;
 +extern crate rustc_fs_util;
 +extern crate rustc_hir;
 +extern crate rustc_incremental;
 +extern crate rustc_index;
 +extern crate rustc_interface;
 +extern crate rustc_metadata;
 +extern crate rustc_session;
 +extern crate rustc_span;
 +extern crate rustc_target;
 +
 +// This prevents duplicating functions and statics that are already part of the host rustc process.
 +#[allow(unused_extern_crates)]
 +extern crate rustc_driver;
 +
 +use std::any::Any;
 +
 +use rustc_codegen_ssa::traits::CodegenBackend;
 +use rustc_codegen_ssa::CodegenResults;
 +use rustc_errors::ErrorReported;
 +use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 +use rustc_middle::middle::cstore::EncodedMetadata;
 +use rustc_session::config::OutputFilenames;
 +use rustc_session::Session;
 +
 +use cranelift_codegen::isa::TargetIsa;
 +use cranelift_codegen::settings::{self, Configurable};
 +
 +pub use crate::config::*;
 +use crate::prelude::*;
 +
 +mod abi;
 +mod allocator;
 +mod analyze;
 +mod archive;
- mod backend;
 +mod base;
 +mod cast;
 +mod codegen_i128;
 +mod common;
 +mod compiler_builtins;
 +mod config;
 +mod constant;
 +mod debuginfo;
 +mod discriminant;
 +mod driver;
 +mod inline_asm;
 +mod intrinsics;
 +mod linkage;
 +mod main_shim;
 +mod metadata;
 +mod num;
 +mod optimize;
 +mod pointer;
 +mod pretty_clif;
 +mod toolchain;
 +mod trap;
 +mod unsize;
 +mod value_and_place;
 +mod vtable;
 +
 +mod prelude {
 +    pub(crate) use std::convert::{TryFrom, TryInto};
 +
 +    pub(crate) use rustc_span::{Span, FileNameDisplayPreference};
 +
 +    pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 +    pub(crate) use rustc_middle::bug;
 +    pub(crate) use rustc_middle::mir::{self, *};
 +    pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
 +    pub(crate) use rustc_middle::ty::{
 +        self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
 +        TypeFoldable, UintTy,
 +    };
 +    pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx};
 +
 +    pub(crate) use rustc_data_structures::fx::FxHashMap;
 +
 +    pub(crate) use rustc_index::vec::Idx;
 +
 +    pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
 +    pub(crate) use cranelift_codegen::ir::function::Function;
 +    pub(crate) use cranelift_codegen::ir::types;
 +    pub(crate) use cranelift_codegen::ir::{
 +        AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc,
 +        StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value,
 +    };
 +    pub(crate) use cranelift_codegen::isa::{self, CallConv};
 +    pub(crate) use cranelift_codegen::Context;
 +    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
 +    pub(crate) use cranelift_module::{self, DataContext, FuncId, Linkage, Module};
 +
 +    pub(crate) use crate::abi::*;
 +    pub(crate) use crate::base::{codegen_operand, codegen_place};
 +    pub(crate) use crate::cast::*;
 +    pub(crate) use crate::common::*;
 +    pub(crate) use crate::debuginfo::{DebugContext, UnwindContext};
 +    pub(crate) use crate::pointer::Pointer;
 +    pub(crate) use crate::trap::*;
 +    pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
 +}
 +
 +struct PrintOnPanic<F: Fn() -> String>(F);
 +impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
 +    fn drop(&mut self) {
 +        if ::std::thread::panicking() {
 +            println!("{}", (self.0)());
 +        }
 +    }
 +}
 +
 +/// The codegen context holds any information shared between the codegen of individual functions
 +/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module).
 +struct CodegenCx<'tcx> {
 +    tcx: TyCtxt<'tcx>,
 +    global_asm: String,
 +    cached_context: Context,
 +    debug_context: Option<DebugContext<'tcx>>,
 +    unwind_context: UnwindContext,
 +}
 +
 +impl<'tcx> CodegenCx<'tcx> {
 +    fn new(
 +        tcx: TyCtxt<'tcx>,
 +        backend_config: BackendConfig,
 +        isa: &dyn TargetIsa,
 +        debug_info: bool,
 +    ) -> Self {
 +        assert_eq!(pointer_ty(tcx), isa.pointer_type());
 +
 +        let unwind_context =
 +            UnwindContext::new(tcx, isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
 +        let debug_context = if debug_info { Some(DebugContext::new(tcx, isa)) } else { None };
 +        CodegenCx {
 +            tcx,
 +            global_asm: String::new(),
 +            cached_context: Context::new(),
 +            debug_context,
 +            unwind_context,
 +        }
 +    }
 +}
 +
 +pub struct CraneliftCodegenBackend {
 +    pub config: Option<BackendConfig>,
 +}
 +
 +impl CodegenBackend for CraneliftCodegenBackend {
 +    fn init(&self, sess: &Session) {
 +        use rustc_session::config::Lto;
 +        match sess.lto() {
 +            Lto::No | Lto::ThinLocal => {}
 +            Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."),
 +        }
 +    }
 +
 +    fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
 +        vec![]
 +    }
 +
 +    fn print_version(&self) {
 +        println!("Cranelift version: {}", cranelift_codegen::VERSION);
 +    }
 +
 +    fn codegen_crate(
 +        &self,
 +        tcx: TyCtxt<'_>,
 +        metadata: EncodedMetadata,
 +        need_metadata_module: bool,
 +    ) -> Box<dyn Any> {
 +        tcx.sess.abort_if_errors();
 +        let config = if let Some(config) = self.config.clone() {
 +            config
 +        } else {
 +            if !tcx.sess.unstable_options() && !tcx.sess.opts.cg.llvm_args.is_empty() {
 +                tcx.sess.fatal("`-Z unstable-options` must be passed to allow configuring cg_clif");
 +            }
 +            BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
 +                .unwrap_or_else(|err| tcx.sess.fatal(&err))
 +        };
 +        match config.codegen_mode {
 +            CodegenMode::Aot => driver::aot::run_aot(tcx, config, metadata, need_metadata_module),
 +            CodegenMode::Jit | CodegenMode::JitLazy => {
 +                #[cfg(feature = "jit")]
 +                let _: ! = driver::jit::run_jit(tcx, config);
 +
 +                #[cfg(not(feature = "jit"))]
 +                tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift");
 +            }
 +        }
 +    }
 +
 +    fn join_codegen(
 +        &self,
 +        ongoing_codegen: Box<dyn Any>,
 +        _sess: &Session,
 +    ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
 +        Ok(*ongoing_codegen
 +            .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
 +            .unwrap())
 +    }
 +
 +    fn link(
 +        &self,
 +        sess: &Session,
 +        codegen_results: CodegenResults,
 +        outputs: &OutputFilenames,
 +    ) -> Result<(), ErrorReported> {
 +        use rustc_codegen_ssa::back::link::link_binary;
 +
 +        link_binary::<crate::archive::ArArchiveBuilder<'_>>(sess, &codegen_results, outputs)
 +    }
 +}
 +
 +fn target_triple(sess: &Session) -> target_lexicon::Triple {
 +    match sess.target.llvm_target.parse() {
 +        Ok(triple) => triple,
 +        Err(err) => sess.fatal(&format!("target not recognized: {}", err)),
 +    }
 +}
 +
 +fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::TargetIsa + 'static> {
 +    use target_lexicon::BinaryFormat;
 +
 +    let target_triple = crate::target_triple(sess);
 +
 +    let mut flags_builder = settings::builder();
 +    flags_builder.enable("is_pic").unwrap();
 +    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
 +    let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
 +    flags_builder.set("enable_verifier", enable_verifier).unwrap();
 +
 +    let tls_model = match target_triple.binary_format {
 +        BinaryFormat::Elf => "elf_gd",
 +        BinaryFormat::Macho => "macho",
 +        BinaryFormat::Coff => "coff",
 +        _ => "none",
 +    };
 +    flags_builder.set("tls_model", tls_model).unwrap();
 +
 +    flags_builder.set("enable_simd", "true").unwrap();
 +
 +    flags_builder.set("enable_llvm_abi_extensions", "true").unwrap();
 +
 +    flags_builder.set("regalloc", &backend_config.regalloc).unwrap();
 +
 +    use rustc_session::config::OptLevel;
 +    match sess.opts.optimize {
 +        OptLevel::No => {
 +            flags_builder.set("opt_level", "none").unwrap();
 +        }
 +        OptLevel::Less | OptLevel::Default => {}
 +        OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => {
 +            flags_builder.set("opt_level", "speed_and_size").unwrap();
 +        }
 +    }
 +
 +    let flags = settings::Flags::new(flags_builder);
 +
 +    let variant = cranelift_codegen::isa::BackendVariant::MachInst;
 +
 +    let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
 +        Some("native") => {
 +            let builder = cranelift_native::builder_with_options(variant, true).unwrap();
 +            builder
 +        }
 +        Some(value) => {
 +            let mut builder =
 +                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant)
 +                    .unwrap_or_else(|err| {
 +                        sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
 +                    });
 +            if let Err(_) = builder.enable(value) {
 +                sess.fatal("the specified target cpu isn't currently supported by Cranelift.");
 +            }
 +            builder
 +        }
 +        None => {
 +            let mut builder =
 +                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant)
 +                    .unwrap_or_else(|err| {
 +                        sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
 +                    });
 +            if target_triple.architecture == target_lexicon::Architecture::X86_64 {
 +                // Don't use "haswell" as the default, as it implies `has_lzcnt`.
 +                // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
 +                builder.enable("nehalem").unwrap();
 +            }
 +            builder
 +        }
 +    };
 +
 +    isa_builder.finish(flags)
 +}
 +
 +/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
 +#[no_mangle]
 +pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
 +    Box::new(CraneliftCodegenBackend { config: None })
 +}
index db24bf65eb5a2e015620822b67b81592feeff024,0000000000000000000000000000000000000000..9afa999a87d8d20b3687bd29c2add1215b5e40d2
mode 100644,000000..100644
--- /dev/null
@@@ -1,20 -1,0 +1,72 @@@
- use rustc_middle::ty::TyCtxt;
 +//! Writing of the rustc metadata for dylibs
 +
- use crate::backend::WriteMetadata;
++use object::write::{Object, StandardSegment, Symbol, SymbolSection};
++use object::{SectionKind, SymbolFlags, SymbolKind, SymbolScope};
 +
- pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O) {
++use rustc_middle::middle::cstore::EncodedMetadata;
++use rustc_middle::ty::TyCtxt;
 +
 +// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
-     let metadata = tcx.encode_metadata();
++pub(crate) fn new_metadata_object(tcx: TyCtxt<'_>, cgu_name: &str, metadata: &EncodedMetadata) -> Vec<u8> {
 +    use snap::write::FrameEncoder;
 +    use std::io::Write;
 +
-     object.add_rustc_section(
-         rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
-         compressed,
-     );
 +    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
 +    FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 +
++    let triple = crate::target_triple(tcx.sess);
++
++    let binary_format = match triple.binary_format {
++        target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
++        target_lexicon::BinaryFormat::Coff => object::BinaryFormat::Coff,
++        target_lexicon::BinaryFormat::Macho => object::BinaryFormat::MachO,
++        binary_format => tcx.sess.fatal(&format!("binary format {} is unsupported", binary_format)),
++    };
++    let architecture = match triple.architecture {
++        target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
++        target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
++        target_lexicon::Architecture::Avr => object::Architecture::Avr,
++        target_lexicon::Architecture::Hexagon => object::Architecture::Hexagon,
++        target_lexicon::Architecture::Mips32(_) => object::Architecture::Mips,
++        target_lexicon::Architecture::Mips64(_) => object::Architecture::Mips64,
++        target_lexicon::Architecture::Msp430 => object::Architecture::Msp430,
++        target_lexicon::Architecture::Powerpc => object::Architecture::PowerPc,
++        target_lexicon::Architecture::Powerpc64 => object::Architecture::PowerPc64,
++        target_lexicon::Architecture::Powerpc64le => todo!(),
++        target_lexicon::Architecture::Riscv32(_) => object::Architecture::Riscv32,
++        target_lexicon::Architecture::Riscv64(_) => object::Architecture::Riscv64,
++        target_lexicon::Architecture::S390x => object::Architecture::S390x,
++        target_lexicon::Architecture::Sparc64 => object::Architecture::Sparc64,
++        target_lexicon::Architecture::Sparcv9 => object::Architecture::Sparc64,
++        target_lexicon::Architecture::X86_32(_) => object::Architecture::I386,
++        target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
++        architecture => {
++            tcx.sess.fatal(&format!("target architecture {:?} is unsupported", architecture,))
++        }
++    };
++    let endian = match triple.endianness().unwrap() {
++        target_lexicon::Endianness::Little => object::Endianness::Little,
++        target_lexicon::Endianness::Big => object::Endianness::Big,
++    };
++
++    let mut object = Object::new(binary_format, architecture, endian);
++    object.add_file_symbol(cgu_name.as_bytes().to_vec());
++
++    let segment = object.segment_name(StandardSegment::Data).to_vec();
++    let section_id = object.add_section(segment, b".rustc".to_vec(), SectionKind::Data);
++    let offset = object.append_section_data(section_id, &compressed, 1);
++    // For MachO and probably PE this is necessary to prevent the linker from throwing away the
++    // .rustc section. For ELF this isn't necessary, but it also doesn't harm.
++    object.add_symbol(Symbol {
++        name: rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx).into_bytes(),
++        value: offset,
++        size: compressed.len() as u64,
++        kind: SymbolKind::Data,
++        scope: SymbolScope::Dynamic,
++        weak: false,
++        section: SymbolSection::Section(section_id),
++        flags: SymbolFlags::None,
++    });
++
++    object.write().unwrap()
 +}