Bug 1457481 - Run mach vendor rust. r=froydnj,erahm
authorMarkus Stange <mstange@themasta.com>
Tue, 02 Oct 2018 01:50:56 +0000
changeset 487498 255e04ebe3bd06b1ecdcea2a5a699ffc7fd9920d
parent 487497 7566a6bac33d41042243ac2cef94f32b7d0c08df
child 487499 c4a515cf1d8fb6e422a09adb0c807ab240ec6e03
push id246
push userfmarier@mozilla.com
push dateSat, 13 Oct 2018 00:15:40 +0000
reviewersfroydnj, erahm
bugs1457481, 34524820, 34542861, 102400
milestone64.0a1
Bug 1457481 - Run mach vendor rust. r=froydnj,erahm Most importantly, this picks up "object" and "goblin" for ELF binary parsing. We only use the ELF code from goblin, so the mach-O parsing code gets eliminated by the linker. Overall, this increases the Android installer size by 20KB. Try pushes for reference: before: https://treeherder.mozilla.org/#/jobs?repo=try&revision=834b56dc5ab3d63a43a32f740ee8212296ac726d&selectedJob=201600899 after: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6983b27e8d3cb715d3b7e6cbd276683f6466e3cc&selectedJob=201600475 installer size: 34524820 -> 34542861 (34.52MB -> 34.54MB) $ mach vendor rust Updating registry `https://github.com/rust-lang/crates.io-index` Adding goblin v0.0.17 Adding memmap v0.6.2 Adding miniz-sys v0.1.10 Adding object v0.10.0 Adding parity-wasm v0.31.3 Adding plain v0.2.3 Adding profiler_helper v0.1.0 (file:///Users/mstange/code/mozilla/tools/profiler/rust-helper) Adding scroll v0.9.1 Adding scroll_derive v0.9.5 Adding syn v0.15.5 Adding thin-vec v0.1.0 Adding uuid v0.6.5 0:30.11 The following files exceed the filesize limit of 102400: third_party/rust/miniz-sys/miniz.c third_party/rust/syn-0.14.6/src/expr.rs third_party/rust/syn-0.14.6/src/gen/fold.rs third_party/rust/syn-0.14.6/src/gen/visit.rs third_party/rust/syn-0.14.6/src/gen/visit_mut.rs The syn dependency is not compiled for goblin, as far as I can tell - it's only needed for the 'syn' feature of scroll_derive, and scroll does not ask for scroll_derive/syn. object -> goblin -> scroll -> scroll_derive -/-> syn But it looks like other versions of syn were already in the tree. Depends on D7021 Differential Revision: https://phabricator.services.mozilla.com/D7023
Cargo.lock
third_party/rust/goblin/.cargo-checksum.json
third_party/rust/goblin/CHANGELOG.md
third_party/rust/goblin/Cargo.toml
third_party/rust/goblin/LICENSE
third_party/rust/goblin/README.md
third_party/rust/goblin/etc/crt1.rs
third_party/rust/goblin/etc/crt132.rs
third_party/rust/goblin/etc/crt1a.rs
third_party/rust/goblin/examples/ar.rs
third_party/rust/goblin/examples/automagic.rs
third_party/rust/goblin/examples/dyldinfo.rs
third_party/rust/goblin/examples/lipo.rs
third_party/rust/goblin/examples/rdr.rs
third_party/rust/goblin/examples/scroll.rs
third_party/rust/goblin/src/archive/mod.rs
third_party/rust/goblin/src/elf/compression_header.rs
third_party/rust/goblin/src/elf/constants_header.rs
third_party/rust/goblin/src/elf/constants_relocation.rs
third_party/rust/goblin/src/elf/dyn.rs
third_party/rust/goblin/src/elf/gnu_hash.rs
third_party/rust/goblin/src/elf/header.rs
third_party/rust/goblin/src/elf/mod.rs
third_party/rust/goblin/src/elf/note.rs
third_party/rust/goblin/src/elf/program_header.rs
third_party/rust/goblin/src/elf/reloc.rs
third_party/rust/goblin/src/elf/section_header.rs
third_party/rust/goblin/src/elf/sym.rs
third_party/rust/goblin/src/error.rs
third_party/rust/goblin/src/lib.rs
third_party/rust/goblin/src/mach/bind_opcodes.rs
third_party/rust/goblin/src/mach/constants.rs
third_party/rust/goblin/src/mach/exports.rs
third_party/rust/goblin/src/mach/fat.rs
third_party/rust/goblin/src/mach/header.rs
third_party/rust/goblin/src/mach/imports.rs
third_party/rust/goblin/src/mach/load_command.rs
third_party/rust/goblin/src/mach/mod.rs
third_party/rust/goblin/src/mach/relocation.rs
third_party/rust/goblin/src/mach/segment.rs
third_party/rust/goblin/src/mach/symbols.rs
third_party/rust/goblin/src/pe/characteristic.rs
third_party/rust/goblin/src/pe/data_directories.rs
third_party/rust/goblin/src/pe/debug.rs
third_party/rust/goblin/src/pe/export.rs
third_party/rust/goblin/src/pe/header.rs
third_party/rust/goblin/src/pe/import.rs
third_party/rust/goblin/src/pe/mod.rs
third_party/rust/goblin/src/pe/optional_header.rs
third_party/rust/goblin/src/pe/section_table.rs
third_party/rust/goblin/src/pe/utils.rs
third_party/rust/goblin/src/strtab.rs
third_party/rust/goblin/tests/archive.rs
third_party/rust/goblin/tests/compare_dyldinfos.rs
third_party/rust/goblin/tests/macho.rs
third_party/rust/memmap-0.5.2/.appveyor.yml
third_party/rust/memmap-0.5.2/.cargo-checksum.json
third_party/rust/memmap-0.5.2/.travis.yml
third_party/rust/memmap-0.5.2/Cargo.toml
third_party/rust/memmap-0.5.2/LICENSE-APACHE
third_party/rust/memmap-0.5.2/LICENSE-MIT
third_party/rust/memmap-0.5.2/README.md
third_party/rust/memmap-0.5.2/ci/install.sh
third_party/rust/memmap-0.5.2/ci/script.sh
third_party/rust/memmap-0.5.2/examples/cat.rs
third_party/rust/memmap-0.5.2/src/lib.rs
third_party/rust/memmap-0.5.2/src/unix.rs
third_party/rust/memmap-0.5.2/src/windows.rs
third_party/rust/memmap/.appveyor.yml
third_party/rust/memmap/.cargo-checksum.json
third_party/rust/memmap/.travis.yml
third_party/rust/memmap/Cargo.toml
third_party/rust/memmap/README.md
third_party/rust/memmap/ci/script.sh
third_party/rust/memmap/examples/cat.rs
third_party/rust/memmap/src/lib.rs
third_party/rust/memmap/src/unix.rs
third_party/rust/memmap/src/windows.rs
third_party/rust/object/.cargo-checksum.json
third_party/rust/object/Cargo.toml
third_party/rust/object/LICENSE-APACHE
third_party/rust/object/LICENSE-MIT
third_party/rust/object/README.md
third_party/rust/object/examples/nm.rs
third_party/rust/object/examples/objdump.rs
third_party/rust/object/src/elf.rs
third_party/rust/object/src/lib.rs
third_party/rust/object/src/macho.rs
third_party/rust/object/src/pe.rs
third_party/rust/object/src/traits.rs
third_party/rust/object/src/wasm.rs
third_party/rust/plain/.cargo-checksum.json
third_party/rust/plain/.travis.yml
third_party/rust/plain/Cargo.toml
third_party/rust/plain/LICENSE-APACHE
third_party/rust/plain/LICENSE-MIT
third_party/rust/plain/README.md
third_party/rust/plain/src/error.rs
third_party/rust/plain/src/lib.rs
third_party/rust/plain/src/methods.rs
third_party/rust/plain/src/plain.rs
third_party/rust/plain/src/tests.rs
third_party/rust/scroll/.cargo-checksum.json
third_party/rust/scroll/.travis.yml
third_party/rust/scroll/CHANGELOG.md
third_party/rust/scroll/Cargo.toml
third_party/rust/scroll/LICENSE
third_party/rust/scroll/README.md
third_party/rust/scroll/benches/bench.rs
third_party/rust/scroll/build.rs
third_party/rust/scroll/examples/data_ctx.rs
third_party/rust/scroll/src/ctx.rs
third_party/rust/scroll/src/endian.rs
third_party/rust/scroll/src/error.rs
third_party/rust/scroll/src/greater.rs
third_party/rust/scroll/src/leb128.rs
third_party/rust/scroll/src/lesser.rs
third_party/rust/scroll/src/lib.rs
third_party/rust/scroll/src/pread.rs
third_party/rust/scroll/src/pwrite.rs
third_party/rust/scroll/tests/api.rs
third_party/rust/scroll/tests/readme.rs
third_party/rust/scroll_derive/.cargo-checksum.json
third_party/rust/scroll_derive/.cargo_vcs_info.json
third_party/rust/scroll_derive/Cargo.toml
third_party/rust/scroll_derive/LICENSE
third_party/rust/scroll_derive/README.md
third_party/rust/scroll_derive/examples/main.rs
third_party/rust/scroll_derive/src/lib.rs
third_party/rust/scroll_derive/tests/tests.rs
third_party/rust/syn-0.14.6/.cargo-checksum.json
third_party/rust/syn-0.14.6/Cargo.toml
third_party/rust/syn-0.14.6/LICENSE-APACHE
third_party/rust/syn-0.14.6/LICENSE-MIT
third_party/rust/syn-0.14.6/README.md
third_party/rust/syn-0.14.6/src/attr.rs
third_party/rust/syn-0.14.6/src/buffer.rs
third_party/rust/syn-0.14.6/src/data.rs
third_party/rust/syn-0.14.6/src/derive.rs
third_party/rust/syn-0.14.6/src/error.rs
third_party/rust/syn-0.14.6/src/expr.rs
third_party/rust/syn-0.14.6/src/file.rs
third_party/rust/syn-0.14.6/src/gen/fold.rs
third_party/rust/syn-0.14.6/src/gen/visit.rs
third_party/rust/syn-0.14.6/src/gen/visit_mut.rs
third_party/rust/syn-0.14.6/src/gen_helper.rs
third_party/rust/syn-0.14.6/src/generics.rs
third_party/rust/syn-0.14.6/src/item.rs
third_party/rust/syn-0.14.6/src/lib.rs
third_party/rust/syn-0.14.6/src/lifetime.rs
third_party/rust/syn-0.14.6/src/lit.rs
third_party/rust/syn-0.14.6/src/mac.rs
third_party/rust/syn-0.14.6/src/macros.rs
third_party/rust/syn-0.14.6/src/op.rs
third_party/rust/syn-0.14.6/src/parse_quote.rs
third_party/rust/syn-0.14.6/src/parsers.rs
third_party/rust/syn-0.14.6/src/path.rs
third_party/rust/syn-0.14.6/src/punctuated.rs
third_party/rust/syn-0.14.6/src/spanned.rs
third_party/rust/syn-0.14.6/src/synom.rs
third_party/rust/syn-0.14.6/src/token.rs
third_party/rust/syn-0.14.6/src/tt.rs
third_party/rust/syn-0.14.6/src/ty.rs
third_party/rust/syn-0.14.6/src/verbatim.rs
third_party/rust/syn/.cargo-checksum.json
third_party/rust/syn/.cargo_vcs_info.json
third_party/rust/syn/Cargo.toml
third_party/rust/syn/README.md
third_party/rust/syn/src/attr.rs
third_party/rust/syn/src/buffer.rs
third_party/rust/syn/src/data.rs
third_party/rust/syn/src/derive.rs
third_party/rust/syn/src/error.rs
third_party/rust/syn/src/export.rs
third_party/rust/syn/src/expr.rs
third_party/rust/syn/src/ext.rs
third_party/rust/syn/src/file.rs
third_party/rust/syn/src/gen/fold.rs
third_party/rust/syn/src/gen/visit.rs
third_party/rust/syn/src/gen/visit_mut.rs
third_party/rust/syn/src/generics.rs
third_party/rust/syn/src/group.rs
third_party/rust/syn/src/ident.rs
third_party/rust/syn/src/item.rs
third_party/rust/syn/src/keyword.rs
third_party/rust/syn/src/lib.rs
third_party/rust/syn/src/lifetime.rs
third_party/rust/syn/src/lit.rs
third_party/rust/syn/src/lookahead.rs
third_party/rust/syn/src/mac.rs
third_party/rust/syn/src/macros.rs
third_party/rust/syn/src/op.rs
third_party/rust/syn/src/parse.rs
third_party/rust/syn/src/parse_quote.rs
third_party/rust/syn/src/parsers.rs
third_party/rust/syn/src/path.rs
third_party/rust/syn/src/print.rs
third_party/rust/syn/src/punctuated.rs
third_party/rust/syn/src/span.rs
third_party/rust/syn/src/spanned.rs
third_party/rust/syn/src/synom.rs
third_party/rust/syn/src/token.rs
third_party/rust/syn/src/tt.rs
third_party/rust/syn/src/ty.rs
third_party/rust/syn/src/verbatim.rs
third_party/rust/thin-vec/.cargo-checksum.json
third_party/rust/thin-vec/Cargo.toml
third_party/rust/thin-vec/README.md
third_party/rust/thin-vec/src/heap.rs
third_party/rust/thin-vec/src/lib.rs
third_party/rust/thin-vec/src/range.rs
third_party/rust/uuid-0.5.1/.cargo-checksum.json
third_party/rust/uuid-0.5.1/.travis.yml
third_party/rust/uuid-0.5.1/Cargo.toml
third_party/rust/uuid-0.5.1/LICENSE-APACHE
third_party/rust/uuid-0.5.1/LICENSE-MIT
third_party/rust/uuid-0.5.1/README.md
third_party/rust/uuid-0.5.1/benches/parse_str.rs
third_party/rust/uuid-0.5.1/src/lib.rs
third_party/rust/uuid-0.5.1/src/rustc_serialize.rs
third_party/rust/uuid-0.5.1/src/serde.rs
third_party/rust/uuid-0.5.1/src/std_support.rs
third_party/rust/uuid/.cargo-checksum.json
third_party/rust/uuid/.travis.yml
third_party/rust/uuid/CODEOWNERS
third_party/rust/uuid/CODE_OF_CONDUCT.md
third_party/rust/uuid/CONTRIBUTING.md
third_party/rust/uuid/COPYRIGHT
third_party/rust/uuid/Cargo.toml
third_party/rust/uuid/LICENSE-MIT
third_party/rust/uuid/README.md
third_party/rust/uuid/benches/parse_str.rs
third_party/rust/uuid/src/adapter.rs
third_party/rust/uuid/src/core_support.rs
third_party/rust/uuid/src/lib.rs
third_party/rust/uuid/src/prelude.rs
third_party/rust/uuid/src/rustc_serialize.rs
third_party/rust/uuid/src/serde.rs
third_party/rust/uuid/src/serde_support.rs
third_party/rust/uuid/src/slog_support.rs
third_party/rust/uuid/src/std_support.rs
third_party/rust/uuid/src/test_util.rs
third_party/rust/uuid/src/u128_support.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -959,16 +959,17 @@ dependencies = [
  "jsrust_shared 0.1.0",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozurl 0.0.1",
  "mp4parse_capi 0.10.1",
  "netwerk_helper 0.0.1",
  "nserror 0.1.0",
  "nsstring 0.1.0",
  "prefs_parser 0.0.1",
+ "profiler_helper 0.1.0",
  "rkv 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rsdparsa_capi 0.1.0",
  "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "u2fhid 0.2.1",
  "webrender_bindings 0.1.0",
  "xpcom 0.1.0",
 ]
 
@@ -991,16 +992,26 @@ dependencies = [
 ]
 
 [[package]]
 name = "glob"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "goblin"
+version = "0.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "h2"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1368,16 +1379,25 @@ source = "registry+https://github.com/ru
 dependencies = [
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "memmap"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "memoffset"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "miniz_oxide"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1630,16 +1650,26 @@ source = "registry+https://github.com/ru
 name = "num_cpus"
 version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "object"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "ordered-float"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1729,16 +1759,21 @@ dependencies = [
 ]
 
 [[package]]
 name = "pkg-config"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "plain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "plane-split"
 version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1775,16 +1810,25 @@ dependencies = [
 ]
 
 [[package]]
 name = "procedural-masquerade"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "profiler_helper"
+version = "0.1.0"
+dependencies = [
+ "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "object 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thin-vec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "pulse"
 version = "0.2.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulse-ffi 0.1.0",
 ]
 
 [[package]]
@@ -2001,16 +2045,35 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "scopeguard"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "scroll"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "scroll_derive"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "selectors"
 version = "0.20.0"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2278,16 +2341,26 @@ version = "0.14.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "syn"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "synstructure"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2369,16 +2442,24 @@ dependencies = [
 ]
 
 [[package]]
 name = "thin-slice"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "thin-vec"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "thread_local"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2646,16 +2727,24 @@ source = "registry+https://github.com/ru
 name = "uuid"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "uuid"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "vcpkg"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "vec_map"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2996,16 +3085,17 @@ dependencies = [
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "884dbe32a6ae4cd7da5c6db9b78114449df9953b8d490c9d7e1b51720b922c62"
 "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
 "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
 "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
 "checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a"
 "checksum gleam 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ba6539d49223f6bca4f076d9490c001bdbfe07d59cb0ad4079033c75bdc92d"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
+"checksum goblin 0.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2"
 "checksum h2 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "a27e7ed946e8335bdf9a191bc1b9b14a03ba822d013d2f58437f4fabcbd7fc2c"
 "checksum http 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dca621d0fa606a5ff2850b6e337b57ad6137ee4d67e940449643ff45af6874c6"
 "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07"
 "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e"
 "checksum hyper 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c087746de95e20e4dabe86606c3a019964a8fde2d5f386152939063c116c5971"
 "checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
 "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
 "checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220"
@@ -3030,16 +3120,17 @@ dependencies = [
 "checksum lmdb-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5b392838cfe8858e86fac37cf97a0e8c55cc60ba0a18365cadc33092f128ce9"
 "checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
 "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
 "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
 "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
 "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b"
+"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum miniz_oxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aaa2d3ad070f428fffbd7d3ca2ea20bb0d8cffe9024405c44e1840bc1418b398"
 "checksum miniz_oxide_c_api 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "92d98fdbd6145645828069b37ea92ca3de225e000d80702da25c20d3584b38a5"
 "checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560"
 "checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
 "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
 "checksum moz_cbor 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c82a57087fd5990d7122dbff1607c3b20c3d2958e9d9ad9765aab415e2c91c"
 "checksum mp4parse_fallible 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6626c2aef76eb8f984eef02e475883d3fe9112e114720446c5810fc5f045cd30"
@@ -3049,29 +3140,31 @@ dependencies = [
 "checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"
 "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 "checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
 "checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7"
 "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
 "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
 "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
+"checksum object 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cca6ad89d0801138cb4ef606908ae12d83edc4c790ef5178fc7b4c72d959e90"
 "checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2"
 "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
 "checksum parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69376b761943787ebd5cc85a5bc95958651a22609c5c1c2b65de21786baec72b"
 "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
 "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
 "checksum petgraph 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7e5234c228fbfa874c86a77f685886127f82e0aef602ad1d48333fcac6ad61"
 "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
 "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
+"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
 "checksum plane-split 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d252db71f3d2109c4936e87d9f29f3c737e89f9ac239999d78866bdd60b9deda"
 "checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
 "checksum proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "cccdc7557a98fe98453030f077df7f3a042052fae465bb61d2c2c41435cfd9b6"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
 "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
@@ -3093,16 +3186,18 @@ dependencies = [
 "checksum rust-ini 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263"
 "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
 "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
 "checksum ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0568787116e13c652377b6846f5931454a363a8fdf8ae50463ee40935b278b"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
+"checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
+"checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
 "checksum serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)" = "<none>"
 "checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
 "checksum simd 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3686dd9418ebcc3a26a0c0ae56deab0681e53fe899af91f5bbcee667ebffb1"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
@@ -3114,26 +3209,28 @@ dependencies = [
 "checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
 "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
 "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
 "checksum syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4b5274d4a0a3d2749d5c158dc64d3403e60554dc61194648787ada5212473d"
+"checksum syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)" = "455a6ec9b368f8c479b0ae5494d13b22dc00990d2f00d68c9dc6a2dc4f17f210"
 "checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049"
 "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
 "checksum target-lexicon 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a34226bd63b5a26fc909f5f0d7ef4dc55d5851077035e49437e4e14bf567247f"
 "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
 "checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
 "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
 "checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
+"checksum thin-vec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73fdf4b84c65a85168477b7fb6c498e0716bc9487fba24623389ea7f51708044"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf947d192a9be60ef5131cc7a4648886ba89d712f16700ebbf80c8a69d05d48f"
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
 "checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286"
 "checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb"
 "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71"
 "checksum tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "424f0c87ecd66b863045d84e384cb7ce0ae384d8b065b9f0363d29c0d1b30b2f"
 "checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135"
@@ -3152,16 +3249,17 @@ dependencies = [
 "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
 "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
+"checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
 "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
 "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
 "checksum wasmparser 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fed18a63a6796175be2254fccca1da4e8b8fec0abca37ad155aea345feb50798"
 "checksum webidl 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc14e4b71f94b5bb4c6d696e3b3be4d2e9ee6750a60870ecae09ff7138a131a7"
 "checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{"CHANGELOG.md":"02d194f3b3b9467aa4fd951ce707a48f8964a61bb0e86725fbd8437193ea3932","Cargo.toml":"6f0f2fd7076ae2f3ab734bee3c9ed1a00a63f4b73161158055c9f9f65fde4e5f","LICENSE":"036bf6b6d6fd6dd1abda2ff6cdb672a63bdf32c468048720072910f2268a965f","README.md":"0ef544f009d0c57af22b5b4fa7b01ea8c77376647e6183ca4397b98ec9bad8ec","etc/crt1.rs":"50667c3066e00f92e038bfa4fe6968f49a31d7c6986e19c7c9e695ad9b836f74","etc/crt132.rs":"e69920ceeab57958a1890979158b57fc43f33c5a135b5798d43664c989c8c686","etc/crt1a.rs":"d158350f72aaf4fecd8501735d2f33a1a226e99bf370c794b90f7e9882c8ca64","examples/ar.rs":"68ca410b7138c9aad6562dbf6f7b28696f47b6358b50a98f1579dd9a4434e1ac","examples/automagic.rs":"ef6ee1cd23659bcea004d7ee12fc9356a6659bbaddeae80f75f3c800a9c8df0a","examples/dyldinfo.rs":"3823f397153817ff705c2248cce9d14aac1f2a999da52419cd6466a724c8a0f7","examples/lipo.rs":"907bee692b129f48d1458549d7f678fe94d629222806d46682d18ad7a0b305a6","examples/rdr.rs":"ba3463c01fbdba994a5843c5a0f159306e0982d34dcf9eff97676ca265231e12","examples/scroll.rs":"64bef86c37928fa3929d2c123409ff7c068259dcc0a8a5074639a63193276aa8","src/archive/mod.rs":"4dbecbbf45703a3c49bd36eeaf402bae76087e030c6738a6f1bd20846983c368","src/elf/compression_header.rs":"9300d2c0e118e1b5778bb3137b0a4a5597f3f9a128de1ed0f34072ef05cbc60e","src/elf/constants_header.rs":"cdd0eea9f4617f86f14b57dccf5124ae62376df6efe2bf617f95e4b24c176d1d","src/elf/constants_relocation.rs":"a77ecdd1421443111d8ab2ef6a16423184108dbb605f3c2d09a0bda6ff78f6db","src/elf/dyn.rs":"4ebf733eed110c57349d5c49c456faaf246cc5b5314798a9975c61fa0039dc04","src/elf/gnu_hash.rs":"12a9563648ded7ac451bd2e19086143b07908902deda83572fbeaa6dc71b58c7","src/elf/header.rs":"c487d8ebc5486bbc386414d0ffc68255a50b680ec7c01f2e642cfcb1ce195001","src/elf/mod.rs":"015dcf26eea76b118321d2929a2ed586d96999324e55209344b4bcb281099ba0","src/elf/note.rs":"d576f1640d4ab774a1e59799cb29171b93ddfd921f159ba67469d4f68dd4bec3","src/elf/program_header.rs":"e688f267431070e54b22513e4f3cfe6b139c60836f815a00912c88cdc085279b","src/elf/reloc.rs":"ac92ed86dc34ed6f2507dc64f250e6fa19edfa43e180025fe4693e40b35e6c8b","src/elf/section_header.rs":"3a43d5790bdc83b1b0d08bbc4f8598c37d61a3d36c24c755bc17b1df9acb701b","src/elf/sym.rs":"a58a6acad5002295f690779dc971f25c8f7ccdd8284d3ba14de1113a7a3392f1","src/error.rs":"8b66a4d8df655017dfaa376fb31e9e0e71692105e93920be4fa1b202ffb1a245","src/lib.rs":"0c10f653070918585f4bdb219368ce3f0d695a3f01e481ebefb5c20378ea2f37","src/mach/bind_opcodes.rs":"2477021270083fd3d9200adebf5d2a1963b9014c7400be39fb68c8b309e4eebe","src/mach/constants.rs":"5997a13d228335575b2a1c3780d2a6e063b63c5551c8e69d74bdf8577d7bb7a6","src/mach/exports.rs":"41aa1be345dd9f241746c7ce7a5b91e0727638dc7bb966ca0c1832e2a2eb2ed0","src/mach/fat.rs":"7f9469d567b3cc1bf53d96ca25546aa4ca8498f78bec67f0517f07c5d2dc5a62","src/mach/header.rs":"1e854f63e1c37547a49880342a19f3d0bf284a9b4942cde687ee91fd8099f8df","src/mach/imports.rs":"eb8ac6cab5e40463d82cb006c4ab0d81831acb41136baf93b65c296f51fc863d","src/mach/load_command.rs":"6d18fc610ec16e9fcfa3eb9822213aae94958f809737efad0936a7f94873d86f","src/mach/mod.rs":"4319ee5ef373e1644724696c7e90c004a95b291713207ee3c45d7be287da1ef7","src/mach/relocation.rs":"a5a4f979a1ca61d65c5d0d5c0c6442e8aeb332e9d71d4dec44588210a0099198","src/mach/segment.rs":"e743a4f35a1136647f6e82ee93c39ba4582d46bdc39a4d864451665b0f5ff378","src/mach/symbols.rs":"6046079acf01fada8ed269dcf31103ae72ac17c470151ec4d8dbccc6ef8879bb","src/pe/characteristic.rs":"4fa8a7e6de20795b6d70d80fc25568eb999bb3dd9f9735d1407302a8053b3dd1","src/pe/data_directories.rs":"f3fc7757ba20559be0626a8e65cd87aab5b1f1f2ce09584a28686f82c77af88a","src/pe/debug.rs":"a68b78d4868e2b0d410c5175630f3786b84fd17cc7483b5a21ba82dae1fafb99","src/pe/export.rs":"00a5ffece1cc261ecd863de718eb2a26cc35143123f1477d43b43c0654f4c705","src/pe/header.rs":"17789046ba5d366dbab42243e000e1606170e5ecbde0cf09f74139f0e6981a97","src/pe/import.rs":"10352263dcfaf853cf0343e4b3a41892e2d630060612f2e62d19f64d8d89f3ea","src/pe/mod.rs":"c3bffa8481ab995a4992b7f97293a6918cb3390625f3ff99f52780a1f4aca193","src/pe/optional_header.rs":"bd1b6cf33ecc1bfdb59aa6dbf566e905190f6570385fab2b1c855313d3e72dc3","src/pe/section_table.rs":"6755d81ac63153f4fdad94a16a296c37ffd4cdc55e153356e5fc579f6ae8b9b9","src/pe/utils.rs":"93b7e29d517d268fc83031417368ec2a72d95ed33241870796e69908655ea4e6","src/strtab.rs":"e66163a13d43f791f94badefcccfc24a04ef6e2dc784650b68a9e46c988a702a","tests/archive.rs":"2437c669d199392e79b7ac58c2cc25847490db054e21be943a2ad3c4f5f6acdb","tests/compare_dyldinfos.rs":"bd5f3c22a8a7c1563bf23fa12d95868bd630f3ea5ba3ffe659a602de4ec26e39","tests/macho.rs":"e146650ba50531cd00e6c6f74e7ce36189f5918c65daf070641b57396dda6579"},"package":"5911d7df7b8f65ab676c5327b50acea29d3c6a1a4ad05e444cf5dce321b26db2"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/CHANGELOG.md
@@ -0,0 +1,106 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+Before 1.0, this project does not adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+I'm sorry, I will try my best to ease breaking changes.  We're almost to 1.0, don't worry!
+
+## [0.0.17] - 2018-7-16
+### Changed
+ - BREAKING: updated required compiler to 1.19 (technically only required for tests, but assume this is required for building as well)
+ - fixed nightly alloc api issues: https://github.com/m4b/goblin/issues/94
+
+## [0.0.16] - 2018-7-14
+### Changed
+ - BREAKING: pe.export: name is now optional to reflect realities of PE parsing, and add more robustness to parser. many thanks to @tathanhdinh! https://github.com/m4b/goblin/pull/88
+ - elf.note: treat alignment similar to other tools, e.g., readelf. Thanks @xcoldhandsx: https://github.com/m4b/goblin/pull/91
+### Added
+ - elf: more inline annotations on various methods, thanks@amanieu: https://github.com/m4b/goblin/pull/87
+
+## [0.0.15] - 2018-4-22
+### Changed
+ - BREAKING: elf.reloc: u64/i64 used for r_offset/r_addend, and addend is now proper optional, thanks @amanieu! https://github.com/m4b/goblin/pull/86/
+ - update to scroll 0.9
+ - pe32+: parse better, thanks @kjempelodott, https://github.com/m4b/goblin/pull/82
+### Added
+ - mach: add constants for `n_types` when `N_STAB` field is being used, thanks @jrmuizel! https://github.com/m4b/goblin/pull/85
+ - elf: implement support for compressed headers, thanks @rocallahan! https://github.com/m4b/goblin/pull/83
+ - new nightly "alloc" feature: allows compiling the goblin parser on nightly with extern crate + no_std, thanks @philipc! https://github.com/m4b/goblin/pull/77
+ - mach.segments: do not panic on bad internal data bounds: https://github.com/m4b/goblin/issues/74
+ - mach: correctly add weak dylibs to import libs: https://github.com/m4b/goblin/issues/73
+
+## [0.0.14] - 2018-1-15
+### Changed
+- BREAKING: elf: `iter_notes` renamed to `iter_note_headers`
+- BREAKING: mach: remove `is_little_endian()`, `ctx()`, and `container()` methods from header, as they were completely invalid for big-endian architectures since the header was parsed according to the endianness of the binary correctly into memory, and hence would always report `MH_MAGIC` or `MH_MAGIC64` as the magic value.
+- elf: courtesy of @jan-auer, note iterator now properly iterates over multiple PH_NOTEs
+### Added
+- mach: added hotly requested feature - goblin now has new functionality to parse big-endian, powerpc 32-bit mach-o binaries correctly
+- mach: new function to correctly extract the parsing context for a mach-o binary, `parse_magic_and_ctx`
+- elf: note iterator has new `iter_note_sections` method
+
+## [0.0.13] - 2017-12-10
+### Changed
+- BREAKING: remove deprecated goblin::parse method
+- BREAKING: ELF `to_range` removed on program and section headers; use `vm_range` and `file_range` for respective ranges
+- Technically BREAKING: @philipc added Symtab and symbol iterator to ELF, but is basically the same, unless you were explicitly relying on the backing vector
+- use scroll 0.8.0 and us scroll_derive via scroll
+- fix notes including \0 terminator (causes breakage because tools like grep treat resulting output as a binary output...)
+### Added
+- pe: add PE characteristics constants courtesy @philipc
+- mach: SizeWith for RelocationInfo
+- mach: IOWrite and Pwrite impls for Nlist
+
+## [0.0.12] - 2017-10-29
+### Changed
+- fix proper std feature flag to log; this was an oversight in last version
+- proper cputype and cpusubtype constants to mach, along with mappings, courtesy of @mitsuhiko
+- new osx and ios version constants
+- all mach load commands now implement IOread and IOwrite from scroll
+- add new elf::note module and associated structs + constants, and `iter_notes` method to Elf object
+- remove all unused muts; this will make nightly and future stables no longer warn
+
+### Added
+- fix macho nstab treatment, thanks @philipc !
+- mach header cpusubtype bug fixed, thanks @mitsuhiko !
+
+## [0.0.11] - 2017-08-24
+### Added
+- goblin::Object::parse; add deprecation to goblin::parse
+- MAJOR archive now parses bsd style archives AND is zero-copy by @willglynn
+- MAJOR macho import parser bug fixed by @willglynn
+- added writer impls for Section and Segment
+- add get_unsafe to strtab for Option<&str> returns
+- relocations method on mach
+- more elf relocations
+- mach relocations
+- convenience functions for many elf structures that elf writer will appreciate
+- mach relocation iteration
+- update to scroll 0.7
+- add cread/ioread impls for various structs
+
+### Changed
+- BREAKING: sections() and section iterator now return (Section, &[u8])
+- Segment, Section, RelocationIterator are now in segment module
+- removed lifetime from section, removed data and raw data, and embedded ctx
+- all scroll::Error have been removed from public API ref #33
+- better mach symbol iteration
+- better mach section iteration
+- remove wow_so_meta_doge due to linker issues
+- Strtab.get now returns a Option<Result>, when index is bad
+- elf.soname is &str
+- elf.libraries is now Vec<&str>
+
+## [0.0.10] - 2017-05-09
+### Added
+- New goblin::Object for enum containing the parsed binary container, or convenience goblin::parse(&[u8) for parsing bytes into respective container format
+### Changed
+- All binaries formats now have lifetimes
+- Elf has a lifetime
+- Strtab.new now requires a &'a[u8]
+- Strtab.get now returns a scroll::Result<&'a str> (use strtab[index] if you want old behavior and don't care about panics); returning scroll::Error is a bug, fixed in next release
+
+## [0.0.9] - 2017-04-05
+### Changed
+- Archive has a lifetime
+- Mach has a lifetime
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/Cargo.toml
@@ -0,0 +1,55 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "goblin"
+version = "0.0.17"
+authors = ["m4b <m4b.github.io@gmail.com>", "seu <seu@panopticon.re>", "Will Glynn <will@willglynn.com>"]
+include = ["src/**/*", "Cargo.toml", "CHANGELOG.md", "LICENSE", "README.md", "etc/*", "examples/*", "tests/*", "fuzz/**/*"]
+description = "An impish, cross-platform, ELF, Mach-o, and PE binary parsing and loading crate"
+documentation = "https://docs.rs/goblin"
+readme = "README.md"
+keywords = ["binary", "elf", "mach", "pe", "archive"]
+categories = ["parsing", "development-tools::debugging"]
+license = "MIT"
+repository = "https://github.com/m4b/goblin"
+
+[lib]
+[dependencies.log]
+version = "0.4"
+optional = true
+default-features = false
+
+[dependencies.plain]
+version = "0.2.3"
+
+[dependencies.scroll]
+version = "0.9"
+default_features = false
+[dev-dependencies.env_logger]
+version = "0.5"
+
+[features]
+alloc = ["scroll/derive", "log"]
+archive = ["alloc"]
+default = ["std", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "archive", "endian_fd"]
+elf32 = []
+elf64 = []
+endian_fd = ["alloc"]
+mach32 = ["alloc", "endian_fd"]
+mach64 = ["alloc", "endian_fd"]
+pe32 = ["alloc", "endian_fd"]
+pe64 = ["alloc", "endian_fd"]
+std = ["alloc", "scroll/std"]
+[badges.travis-ci]
+branch = "master"
+repository = "m4b/goblin"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) m4b 2016-2018
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/README.md
@@ -0,0 +1,102 @@
+# libgoblin [![Build Status](https://travis-ci.org/m4b/goblin.svg?branch=master)](https://travis-ci.org/m4b/goblin) [![Current Crates.io Version](https://img.shields.io/crates/v/goblin.svg)](https://crates.io/crates/goblin)
+
+![say the right words](https://s-media-cache-ak0.pinimg.com/736x/1b/6a/aa/1b6aaa2bae005e2fed84b1a7c32ecb1b.jpg)
+
+### Documentation
+
+https://docs.rs/goblin/
+
+[changelog](CHANGELOG.md)
+
+### Usage
+
+Goblin requires `rustc` 1.19.
+
+Add to your `Cargo.toml`
+
+```toml
+[dependencies]
+goblin = "0.0.17"
+```
+
+### Features
+
+* awesome crate name
+* zero-copy, cross-platform, endian-aware, ELF64/32 implementation - wow!
+* zero-copy, cross-platform, endian-aware, 32/64 bit Mach-o parser - zoiks!
+* PE 32/64-bit parser - bing!
+* a Unix _and_ BSD style archive parser (latter courtesy of [@willglynn](https://github.com/willglynn)) - huzzah!
+* many cfg options - it will make your head spin, and make you angry when reading the source!
+* fuzzed - " I am happy to report that goblin withstood 100 million fuzzing runs, 1 million runs each for seed 1~100." - [@sanxiyn](https://github.com/sanxiyn)
+* tests
+
+`libgoblin` aims to be your one-stop shop for binary parsing, loading,
+and analysis.
+
+### Use-cases
+
+Goblin primarily supports the following important use cases:
+
+1. Core, std-free `#[repr(C)]` structs, tiny compile time, 32/64 (or both) at your leisure
+
+2. Type punning. Define a function once on a type, but have it work on 32 or 64-bit variants - without really changing anything, and no macros! See `examples/automagic.rs` for a basic example.
+
+3. `std` mode. This throws in read and write impls via `Pread` and `Pwrite`, reading from file, convenience allocations, extra methods, etc. This is for clients who can allocate and want to read binaries off disk.
+
+4. `Endian_fd`. A truly terrible name :laughing: this is for binary analysis like in [panopticon](https://github.com/das-labor/panopticon) or [falcon](https://github.com/endeav0r/falcon) which needs to read binaries of foreign endianness, _or_ as a basis for constructing cross platform foreign architecture binutils, e.g. [cargo-sym](https://github.com/m4b/cargo-sym) and [bingrep](https://github.com/m4b/bingrep) are simple examples of this, but the sky is the limit.
+
+Here are some things you could do with this crate (or help to implement so they could be done):
+
+1. write a compiler and use it to [generate binaries](https://github.com/m4b/faerie) (all the raw C structs have [`Pwrite`](https://github.com/m4b/scroll) derived)
+2. write a binary analysis tool which loads, parses, and analyzes various binary formats, e.g., [panopticon](https://github.com/das-labor/panopticon) or [falcon](https://github.com/endeav0r/falcon)
+3. write a [semi-functioning dynamic linker](http://github.com/m4b/dryad)
+4. write a [kernel](https://github.com/redox-os/redox) and load binaries using `no_std` cfg. I.e., it is essentially just struct and const defs (like a C header) - no fd, no output, no std.
+5. write a bin2json tool (http://github.com/m4b/bin2json), because why shouldn't binary formats be in JSON?
+
+### Cfgs
+
+`libgoblin` is designed to be massively configurable. The current flags are:
+
+* elf64 - 64-bit elf binaries, `repr(C)` struct defs
+* elf32 - 32-bit elf binaries, `repr(C)` struct defs
+* mach64 - 64-bit mach-o `repr(C)` struct defs
+* mach32 - 32-bit mach-o `repr(C)` struct defs
+* pe32 - 32-bit PE `repr(C)` struct defs
+* pe64 - 64-bit PE `repr(C)` struct defs
+* archive - a Unix Archive parser
+* endian_fd - parses according to the endianness in the binary
+* std - to allow `no_std` environments
+
+# Contributors
+
+Thank you all :heart: !
+
+In alphabetic order:
+
+- [@amanieu](https://github.com/amanieu)
+- [@flanfly](https://github.com/flanfly)
+- [@jan-auer](https://github.com/jan-auer)
+- [@jdub](https://github.com/jdub)
+- [@jrmuizel](https://github.com/jrmuizel)
+  [@kjempelodott](https://github.com/kjempelodott)
+- [@le-jzr](https://github.com/le-jzr)
+- [@lion128](https://github.com/lion128)
+- [@llogiq](https://github.com/llogiq)
+- [@mitsuhiko](https://github.com/mitsuhiko)
+- [@mre](https://github.com/mre)
+- [@philipc](https://github.com/philipc)
+- [@rocallahan](https://github.com/rocallahan)
+- [@sanxiyn](https://github.com/sanxiyn)
+- [@tathanhdinh](https://github.com/tathanhdinh)
+- [@ticki](https://github.com/ticki)
+- [@willglynn](https://github.com/willglynn)
+- [@xcoldhandsx](https://github.com/xcoldhandsx)
+
+## Contributing
+
+1. Please prefix commits with the affected binary component; the more specific the better, e.g., if you only modify relocations in the elf module, then do "elf.reloc: added new constants for Z80"
+2. Commit messages must explain their change, no generic "changed", or "fix"; if you push commits like this on a PR, be aware @m4b or someone will most likely squash them.
+3. If you are making a large change to a module, please raise an issue first and lets discuss; I don't want to waste your time if its not a good technical direction, or etc.
+4. If your PR is not getting attention, please respond to all relevant comments raised on the PR, and if still no response, ping @m4b, @philipc, or @willglyn in github and also feel free to email @m4b.
+5. Please add tests if you are adding a new feature. Feel free to add tests even if you are not, tests are awesome and easy in rust.
+6. Once cargo format is officially released, please format your _patch_ using the default settings.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/etc/crt1.rs
@@ -0,0 +1,1 @@
+vec![0x7F,0x45,0x4C,0x46,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x3E,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0xE,0x0,0xB,0x0,0x4,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x47,0x4E,0x55,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x31,0xED,0x49,0x89,0xD1,0x5E,0x48,0x89,0xE2,0x48,0x83,0xE4,0xF0,0x50,0x54,0x49,0xC7,0xC0,0x0,0x0,0x0,0x0,0x48,0xC7,0xC1,0x0,0x0,0x0,0x0,0x48,0xC7,0xC7,0x0,0x0,0x0,0x0,0xFF,0x15,0x0,0x0,0x0,0x0,0xF4,0x0,0x1,0x0,0x2,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x7A,0x52,0x0,0x1,0x78,0x10,0x1,0x1B,0xC,0x7,0x8,0x90,0x1,0x7,0x10,0x14,0x0,0x0,0x0,0x1C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x47,0x43,0x43,0x3A,0x20,0x28,0x47,0x4E,0x55,0x29,0x20,0x36,0x2E,0x31,0x2E,0x31,0x20,0x32,0x30,0x31,0x36,0x30,0x38,0x30,0x32,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0xA,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x4,0x0,0xF1,0xFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x65,0x0,0x0,0x0,0x12,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5A,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x61,0x0,0x0,0x0,0x20,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3E,0x0,0x0,0x0,0x11,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4D,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5F,0x0,0x0,0x0,0x10,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x69,0x6E,0x69,0x74,0x2E,0x63,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x66,0x69,0x6E,0x69,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x69,0x6E,0x69,0x74,0x0,0x5F,0x47,0x4C,0x4F,0x42,0x41,0x4C,0x5F,0x4F,0x46,0x46,0x53,0x45,0x54,0x5F,0x54,0x41,0x42,0x4C,0x45,0x5F,0x0,0x5F,0x49,0x4F,0x5F,0x73,0x74,0x64,0x69,0x6E,0x5F,0x75,0x73,0x65,0x64,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x73,0x74,0x61,0x72,0x74,0x5F,0x6D,0x61,0x69,0x6E,0x0,0x5F,0x5F,0x64,0x61,0x74,0x61,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xA,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xD,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x26,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x29,0x0,0x0,0x0,0x11,0x0,0x0,0x0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2E,0x73,0x79,0x6D,0x74,0x61,0x62,0x0,0x2E,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x73,0x68,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x41,0x42,0x49,0x2D,0x74,0x61,0x67,0x0,0x2E,0x72,0x65,0x6C,0x61,0x2E,0x74,0x65,0x78,0x74,0x0,0x2E,0x72,0x6F,0x64,0x61,0x74,0x61,0x2E,0x63,0x73,0x74,0x34,0x0,0x2E,0x72,0x65,0x6C,0x61,0x2E,0x65,0x68,0x5F,0x66,0x72,0x61,0x6D,0x65,0x0,0x2E,0x64,0x61,0x74,0x61,0x0,0x2E,0x62,0x73,0x73,0x0,0x2E,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x47,0x4E,0x55,0x2D,0x73,0x74,0x61,0x63,0x6B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2E,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x29,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x34,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x46,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x41,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x56,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5B,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x64,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xDF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x11,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x74,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xE0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC8,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0xD,0x0,0x0,0x0,0xA,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xA8,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/etc/crt132.rs
@@ -0,0 +1,1 @@
+vec![0x7F,0x45,0x4C,0x46,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x3,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xBC,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x34,0x0,0x0,0x0,0x0,0x0,0x28,0x0,0xD,0x0,0xA,0x0,0x4,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x47,0x4E,0x55,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x31,0xED,0x5E,0x89,0xE1,0x83,0xE4,0xF0,0x50,0x54,0x52,0x68,0x0,0x0,0x0,0x0,0x68,0x0,0x0,0x0,0x0,0x51,0x56,0x68,0x0,0x0,0x0,0x0,0xE8,0xFC,0xFF,0xFF,0xFF,0xF4,0x3,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x47,0x43,0x43,0x3A,0x20,0x28,0x47,0x4E,0x55,0x29,0x20,0x36,0x2E,0x31,0x2E,0x31,0x20,0x32,0x30,0x31,0x36,0x30,0x38,0x30,0x32,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x9,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0xF1,0xFF,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x11,0x0,0x4,0x0,0xF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x56,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x2,0x0,0x1F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x4B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x52,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x6,0x0,0x2F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x11,0x0,0x5,0x0,0x3E,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x50,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x6,0x0,0x0,0x69,0x6E,0x69,0x74,0x2E,0x63,0x0,0x5F,0x66,0x70,0x5F,0x68,0x77,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x66,0x69,0x6E,0x69,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x69,0x6E,0x69,0x74,0x0,0x5F,0x49,0x4F,0x5F,0x73,0x74,0x64,0x69,0x6E,0x5F,0x75,0x73,0x65,0x64,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x73,0x74,0x61,0x72,0x74,0x5F,0x6D,0x61,0x69,0x6E,0x0,0x5F,0x5F,0x64,0x61,0x74,0x61,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x1,0xB,0x0,0x0,0x11,0x0,0x0,0x0,0x1,0xD,0x0,0x0,0x18,0x0,0x0,0x0,0x1,0xE,0x0,0x0,0x1D,0x0,0x0,0x0,0x2,0x11,0x0,0x0,0x0,0x2E,0x73,0x79,0x6D,0x74,0x61,0x62,0x0,0x2E,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x73,0x68,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x41,0x42,0x49,0x2D,0x74,0x61,0x67,0x0,0x2E,0x72,0x65,0x6C,0x2E,0x74,0x65,0x78,0x74,0x0,0x2E,0x72,0x6F,0x64,0x61,0x74,0x61,0x0,0x2E,0x72,0x6F,0x64,0x61,0x74,0x61,0x2E,0x63,0x73,0x74,0x34,0x0,0x2E,0x64,0x61,0x74,0x61,0x0,0x2E,0x62,0x73,0x73,0x0,0x2E,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x47,0x4E,0x55,0x2D,0x73,0x74,0x61,0x63,0x6B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x34,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2D,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x54,0x0,0x0,0x0,0x22,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x29,0x0,0x0,0x0,0x9,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x2,0x0,0x0,0x20,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x33,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x76,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3B,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7C,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x48,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4E,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x84,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x53,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x84,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x5C,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x11,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50,0x2,0x0,0x0,0x6C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xA0,0x0,0x0,0x0,0x30,0x1,0x0,0x0,0xC,0x0,0x0,0x0,0xA,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x9,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xD0,0x1,0x0,0x0,0x5D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/etc/crt1a.rs
@@ -0,0 +1,1 @@
+vec![0x21,0x3C,0x61,0x72,0x63,0x68,0x3E,0xA,0x2F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x36,0x36,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xA,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x86,0x0,0x0,0x0,0x86,0x0,0x0,0x0,0x86,0x0,0x0,0x0,0x86,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x64,0x61,0x74,0x61,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x5F,0x49,0x4F,0x5F,0x73,0x74,0x64,0x69,0x6E,0x5F,0x75,0x73,0x65,0x64,0x0,0x5F,0x5F,0x64,0x61,0x74,0x61,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x63,0x72,0x74,0x31,0x2E,0x6F,0x2F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x36,0x34,0x34,0x20,0x20,0x20,0x20,0x20,0x31,0x39,0x32,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xA,0x7F,0x45,0x4C,0x46,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x3E,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0xE,0x0,0xB,0x0,0x4,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x47,0x4E,0x55,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x31,0xED,0x49,0x89,0xD1,0x5E,0x48,0x89,0xE2,0x48,0x83,0xE4,0xF0,0x50,0x54,0x49,0xC7,0xC0,0x0,0x0,0x0,0x0,0x48,0xC7,0xC1,0x0,0x0,0x0,0x0,0x48,0xC7,0xC7,0x0,0x0,0x0,0x0,0xFF,0x15,0x0,0x0,0x0,0x0,0xF4,0x0,0x1,0x0,0x2,0x0,0x14,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x7A,0x52,0x0,0x1,0x78,0x10,0x1,0x1B,0xC,0x7,0x8,0x90,0x1,0x7,0x10,0x14,0x0,0x0,0x0,0x1C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x47,0x43,0x43,0x3A,0x20,0x28,0x47,0x4E,0x55,0x29,0x20,0x36,0x2E,0x31,0x2E,0x31,0x20,0x32,0x30,0x31,0x36,0x30,0x38,0x30,0x32,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0xA,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x4,0x0,0xF1,0xFF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x65,0x0,0x0,0x0,0x12,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5A,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x61,0x0,0x0,0x0,0x20,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3E,0x0,0x0,0x0,0x11,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4D,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5F,0x0,0x0,0x0,0x10,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x69,0x6E,0x69,0x74,0x2E,0x63,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x66,0x69,0x6E,0x69,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x63,0x73,0x75,0x5F,0x69,0x6E,0x69,0x74,0x0,0x5F,0x47,0x4C,0x4F,0x42,0x41,0x4C,0x5F,0x4F,0x46,0x46,0x53,0x45,0x54,0x5F,0x54,0x41,0x42,0x4C,0x45,0x5F,0x0,0x5F,0x49,0x4F,0x5F,0x73,0x74,0x64,0x69,0x6E,0x5F,0x75,0x73,0x65,0x64,0x0,0x5F,0x5F,0x6C,0x69,0x62,0x63,0x5F,0x73,0x74,0x61,0x72,0x74,0x5F,0x6D,0x61,0x69,0x6E,0x0,0x5F,0x5F,0x64,0x61,0x74,0x61,0x5F,0x73,0x74,0x61,0x72,0x74,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xA,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x19,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xB,0x0,0x0,0x0,0xD,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x26,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x29,0x0,0x0,0x0,0x11,0x0,0x0,0x0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2E,0x73,0x79,0x6D,0x74,0x61,0x62,0x0,0x2E,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x73,0x68,0x73,0x74,0x72,0x74,0x61,0x62,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x41,0x42,0x49,0x2D,0x74,0x61,0x67,0x0,0x2E,0x72,0x65,0x6C,0x61,0x2E,0x74,0x65,0x78,0x74,0x0,0x2E,0x72,0x6F,0x64,0x61,0x74,0x61,0x2E,0x63,0x73,0x74,0x34,0x0,0x2E,0x72,0x65,0x6C,0x61,0x2E,0x65,0x68,0x5F,0x66,0x72,0x61,0x6D,0x65,0x0,0x2E,0x64,0x61,0x74,0x61,0x0,0x2E,0x62,0x73,0x73,0x0,0x2E,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x0,0x2E,0x6E,0x6F,0x74,0x65,0x2E,0x47,0x4E,0x55,0x2D,0x73,0x74,0x61,0x63,0x6B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2E,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x29,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x34,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x46,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x41,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x50,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x56,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5B,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1B,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x64,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xDF,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x11,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x90,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x74,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xE0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xC8,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0xD,0x0,0x0,0x0,0xA,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xA8,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/ar.rs
@@ -0,0 +1,47 @@
+//cargo run --example=ar -- crt1.a
+
+extern crate goblin;
+
+use goblin::elf;
+use goblin::archive;
+use std::env;
+use std::path::Path;
+use std::fs::File;
+use std::io::Read;
+
+pub fn main () {
+    let len = env::args().len();
+    if len <= 2 {
+        println!("usage: ar <path to archive> member")
+    } else {
+        let mut path = String::default();
+        let mut member = String::default();
+        for (i, arg) in env::args().enumerate() {
+            if i == 1 {
+                path = arg.as_str().to_owned();
+            } else if i == 2 {
+                member = arg.as_str().to_owned();
+            }
+        }
+        let path = Path::new(&path);
+        let buffer = { let mut v = Vec::new(); let mut f = File::open(&path).unwrap(); f.read_to_end(&mut v).unwrap(); v};
+        match archive::Archive::parse(&buffer) {
+            Ok(archive) => {
+                println!("{:#?}", &archive);
+                println!("start: {:?}", archive.member_of_symbol("_start"));
+                match archive.extract(&member, &buffer) {
+                    Ok(bytes) => {
+                        match elf::Elf::parse(&bytes) {
+                            Ok(elf) => {
+                                println!("got elf: {:#?}", elf);
+                            },
+                            Err(err) => println!("Err: {:?}", err)
+                        }
+                    },
+                    Err(err) => println!("Extraction Error: {:?}", err)
+                }
+            },
+            Err(err) => println!("Err: {:?}", err)
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/automagic.rs
@@ -0,0 +1,25 @@
+extern crate goblin;
+
+use std::default::Default;
+
+// demonstrates "automagical" elf32/64 switches via cfg on arch and pub use hacks.
+// SIZEOF_* will change depending on whether it's an x86_64 system or 32-bit x86, or really any cfg you can think of.
+// similarly the printers will be different, since they have different impls. #typepuns4life
+
+#[cfg(target_pointer_width = "64")]
+pub use goblin::elf64 as elf;
+
+#[cfg(target_pointer_width = "32")]
+pub use goblin::elf32 as elf;
+
+#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
+use elf::{header, sym};
+
+#[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))]
+fn main() {
+    let header: header::Header = Default::default();
+    let sym: sym::Sym = Default::default();
+    println!("header: {:?}, sym: {:?}", header, sym);
+    println!("sizeof header: {}", header::SIZEOF_EHDR);
+    println!("sizeof sym: {}", sym::SIZEOF_SYM);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/dyldinfo.rs
@@ -0,0 +1,168 @@
+extern crate goblin;
+
+use goblin::mach;
+use std::env;
+use std::process;
+use std::path::Path;
+use std::fs::File;
+use std::io::Read;
+use std::borrow::Cow;
+
+fn usage() -> ! {
+    println!("usage: dyldinfo <options> <mach-o file>");
+    println!("    -bind             print binds as seen by macho::imports()");
+    println!("    -lazy_bind        print lazy binds as seen by macho::imports()");
+    process::exit(1);
+}
+
+fn name_to_str<'a>(name: &'a [u8; 16]) -> Cow<'a, str> {
+    for i in 0..16 {
+        if name[i] == 0 {
+            return String::from_utf8_lossy(&name[0..i])
+        }
+    }
+    String::from_utf8_lossy(&name[..])
+}
+
+fn dylib_name(name: &str) -> &str {
+    // observed behavior:
+    //   "/usr/lib/libc++.1.dylib" => "libc++"
+    //   "/usr/lib/libSystem.B.dylib" => "libSystem"
+    //   "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" => "CoreFoundation"
+    name
+        .rsplit('/').next().unwrap()
+        .split('.').next().unwrap()
+}
+
+fn print_binds(sections: &[mach::segment::Section], imports: &[mach::imports::Import]) {
+    println!("bind information:");
+
+    println!(
+        "{:7} {:16} {:14} {:7} {:6} {:16} {}",
+        "segment",
+        "section",
+        "address",
+        "type",
+        "addend",
+        "dylib",
+        "symbol"
+    );
+
+    for import in imports.iter().filter(|i| !i.is_lazy) {
+        // find the section that imported this symbol
+        let section = sections.iter()
+            .filter(|s| import.address >= s.addr && import.address < (s.addr + s.size))
+            .next();
+
+        // get &strs for its name
+        let (segname, sectname) = section
+            .map(|sect|  (name_to_str(&sect.segname), name_to_str(&sect.sectname)))
+            .unwrap_or((Cow::Borrowed("?"), Cow::Borrowed("?")));
+
+        println!(
+            "{:7} {:16} 0x{:<12X} {:7} {:6} {:16} {}{}",
+            segname,
+            sectname,
+            import.address,
+            "pointer",
+            import.addend,
+            dylib_name(import.dylib),
+            import.name,
+            if import.is_weak { " (weak import)" } else { "" }
+        );
+    }
+}
+
+fn print_lazy_binds(sections: &[mach::segment::Section], imports: &[mach::imports::Import]) {
+    println!("lazy binding information (from lazy_bind part of dyld info):");
+
+    println!(
+        "{:7} {:16} {:10} {:6} {:16} {}",
+        "segment",
+        "section",
+        "address",
+        "index",
+        "dylib",
+        "symbol"
+    );
+
+    for import in imports.iter().filter(|i| i.is_lazy) {
+        // find the section that imported this symbol
+        let section = sections.iter()
+            .filter(|s| import.address >= s.addr && import.address < (s.addr + s.size))
+            .next();
+
+        // get &strs for its name
+        let (segname, sectname) = section
+            .map(|sect|  (name_to_str(&sect.segname), name_to_str(&sect.sectname)))
+            .unwrap_or((Cow::Borrowed("?"), Cow::Borrowed("?")));
+
+        println!(
+        "{:7} {:16} 0x{:<8X} {:<06} {:16} {}",
+            segname,
+            sectname,
+            import.address,
+            format!("0x{:04X}", import.start_of_sequence_offset),
+            dylib_name(import.dylib),
+            import.name
+        );
+    }
+}
+
+fn main () {
+    let len = env::args().len();
+
+    let mut bind = false;
+    let mut lazy_bind = false;
+
+    if len <= 2 {
+        usage();
+    } else {
+        // parse flags
+        {
+            let mut flags = env::args().collect::<Vec<_>>();
+            flags.pop();
+            flags.remove(0);
+            for option in flags {
+                match option.as_str() {
+                    "-bind" => { bind = true }
+                    "-lazy_bind" => { lazy_bind = true }
+                    other => {
+                        println!("unknown flag: {}", other);
+                        println!("");
+                        usage();
+                    }
+                }
+            }
+        }
+
+        // open the file
+        let path = env::args_os().last().unwrap();
+        let path = Path::new(&path);
+        let buffer = { let mut v = Vec::new(); let mut f = File::open(&path).unwrap(); f.read_to_end(&mut v).unwrap(); v};
+        match mach::MachO::parse(&buffer, 0) {
+            Ok(macho) => {
+                // collect sections and sort by address
+                let mut sections: Vec<mach::segment::Section> = Vec::new();
+                for sects in macho.segments.sections() {
+                    sections.extend(sects.map(|r| r.expect("section").0));
+                }
+                sections.sort_by_key(|s| s.addr);
+
+                // get the imports
+                let imports = macho.imports().expect("imports");
+
+                if bind {
+                    print_binds(&sections, &imports);
+                }
+                if lazy_bind {
+                    print_lazy_binds(&sections, &imports);
+                }
+            },
+            Err(err) => {
+                println!("err: {:?}", err);
+                process::exit(2);
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/lipo.rs
@@ -0,0 +1,70 @@
+extern crate goblin;
+
+use goblin::mach::{self, Mach};
+use std::env;
+use std::process;
+use std::path::Path;
+use std::fs::File;
+use std::io::{Read, Write};
+
+fn usage() -> ! {
+    println!("usage: lipo <options> <mach-o fat file>");
+    println!("    -m64              Extracts and writes the 64-bit binary in this fat container, if any");
+    process::exit(1);
+}
+
+fn main () {
+    let len = env::args().len();
+
+    if len <= 1 {
+        usage();
+    } else {
+        let mut m64 = false;
+        {
+            let mut flags = env::args().collect::<Vec<_>>();
+            flags.pop();
+            flags.remove(0);
+            for option in flags {
+                match option.as_str() {
+                    "-m64" => { m64 = true }
+                    other => {
+                        println!("unknown flag: {}", other);
+                        println!("");
+                        usage();
+                    }
+                }
+            }
+        }
+
+        let path_name = env::args_os().last().unwrap();
+        let path = Path::new(&path_name);
+        let buffer = { let mut v = Vec::new(); let mut f = File::open(&path).unwrap(); f.read_to_end(&mut v).unwrap(); v};
+        match mach::Mach::parse(&buffer) {
+            Ok(Mach::Binary(_macho)) => {
+                println!("Already a single arch binary");
+                process::exit(2);
+            },
+            Ok(Mach::Fat(fat)) => {
+                for (i, arch) in fat.iter_arches().enumerate() {
+                    let arch = arch.unwrap();
+                    let name = format!("{}.{}", &path_name.to_string_lossy(), i);
+                    let path = Path::new(&name);
+                    if arch.is_64() && m64 {
+                        let bytes = &buffer[arch.offset as usize..][..arch.size as usize];
+                        let mut file = File::create(path).unwrap();
+                        file.write_all(bytes).unwrap();
+                        break;
+                    } else if !m64 {
+                        let bytes = &buffer[arch.offset as usize..][..arch.size as usize];
+                        let mut file = File::create(path).unwrap();
+                        file.write_all(bytes).unwrap();
+                    }
+                }
+            },
+            Err(err) => {
+                println!("err: {:?}", err);
+                process::exit(2);
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/rdr.rs
@@ -0,0 +1,29 @@
+extern crate goblin;
+extern crate env_logger;
+
+use goblin::error;
+use std::path::Path;
+use std::env;
+use std::fs::File;
+use std::io::Read;
+
+fn run () -> error::Result<()> {
+    for (i, arg) in env::args().enumerate() {
+        if i == 1 {
+            let path = Path::new(arg.as_str());
+            let mut fd = File::open(path)?;
+            let buffer = { let mut v = Vec::new(); fd.read_to_end(&mut v).unwrap(); v};
+            let res = goblin::Object::parse(&buffer)?;
+            println!("{:#?}", res);
+        }
+    }
+    Ok(())
+}
+
+pub fn main () {
+    env_logger::init();
+    match run() {
+        Ok(()) => (),
+        Err(err) => println!("{:#}", err)
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/examples/scroll.rs
@@ -0,0 +1,35 @@
+/// Demonstrates the magical powers of scroll + goblin
+/// Goblin implements `TryFromCtx` for the header type
+/// which means downstream crates/clients can just "parse" headers out of
+/// arbitrary buffers, without learning new crate specific function names
+/// I.e., all you need are Types + Pread = Happiness
+
+extern crate scroll;
+extern crate goblin;
+
+use goblin::{error, elf64, elf};
+use scroll::{Pwrite, Pread};
+
+fn run () -> error::Result<()> {
+    use Pread;
+    let crt1: Vec<u8> = include!("../etc/crt1.rs");
+    let header: elf64::header::Header = crt1.pread(0)?;
+    assert_eq!(header.e_type, elf64::header::ET_REL);
+    println!("header: {:?}", &header);
+    // now lets write the header into some bytes
+    let mut bytes = [0u8; elf64::header::SIZEOF_EHDR];
+    bytes.pwrite(header, 0)?;
+    // read it back out
+    let header2: elf64::header::Header = bytes.pread(0)?;
+    // they're the same
+    assert_eq!(header, header2);
+    let elf: elf::Elf = crt1.pread(0)?;
+    println!("elf: {:#?}", &elf);
+    let elf = elf::Elf::parse(&crt1)?;
+    println!("elf: {:#?}", &elf);
+    Ok(())
+} 
+
+fn main() {
+    run().unwrap();
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/archive/mod.rs
@@ -0,0 +1,500 @@
+//! Implements a simple parser and extractor for a Unix Archive.
+//!
+//! There are two "common" formats: BSD and SysV
+//!
+//! This crate currently only implements the SysV version, which essentially postfixes all
+//! names in the archive with a / as a sigil for the end of the name, and uses a special symbol
+//! index for looking up symbols faster.
+
+use scroll::{self, Pread};
+
+use strtab;
+use error::{Result, Error};
+
+use core::usize;
+use alloc::collections::btree_map::BTreeMap;
+use alloc::vec::Vec;
+
+pub const SIZEOF_MAGIC: usize = 8;
+/// The magic number of a Unix Archive
+pub const MAGIC: &'static [u8; SIZEOF_MAGIC] = b"!<arch>\x0A";
+
+const SIZEOF_FILE_IDENTIFER: usize = 16;
+const SIZEOF_FILE_SIZE: usize = 10;
+
+#[repr(C)]
+#[derive(Debug, Clone, PartialEq, Pread, Pwrite, SizeWith)]
+/// A Unix Archive Header - meta data for the file/byte blob/whatever that follows exactly after.
+/// All data is right-padded with spaces ASCII `0x20`. The Binary layout is as follows:
+///
+/// |Offset|Length|Name                       |Format     |
+/// |:-----|:-----|:--------------------------|:----------|
+/// |0     |16    |File identifier            |ASCII      |
+/// |16    |12    |File modification timestamp|Decimal    |
+/// |28    |6     |Owner ID                   |Decimal    |
+/// |34    |6     |Group ID                   |Decimal    |
+/// |40    |8     |File mode                  |Octal      |
+/// |48    |10    |Filesize in bytes          |Decimal    |
+/// |58    |2     |Ending characters          |`0x60 0x0A`|
+///
+/// Byte alignment is according to the following:
+/// > Each archive file member begins on an even byte boundary; a newline is inserted between files
+/// > if necessary. Nevertheless, the size given reflects the actual size of the file exclusive
+/// > of padding.
+pub struct MemberHeader {
+    /// The identifier, or name for this file/whatever.
+    pub identifier: [u8; 16],
+    /// The timestamp for when this file was last modified. Base 10 number
+    pub timestamp: [u8; 12],
+    /// The file's owner's id. Base 10 string number
+    pub owner_id: [u8; 6],
+    /// The file's group id. Base 10 string number
+    pub group_id: [u8; 6],
+    /// The file's permissions mode. Base 8 number number
+    pub mode: [u8; 8],
+    /// The size of this file. Base 10 string number
+    pub file_size: [u8; 10],
+    /// The file header's terminator, always `0x60 0x0A`
+    pub terminator: [u8; 2],
+}
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub struct Header<'a> {
+    pub name: &'a str,
+    pub size: usize,
+}
+
+pub const SIZEOF_HEADER: usize = SIZEOF_FILE_IDENTIFER + 12 + 6 + 6 + 8 + SIZEOF_FILE_SIZE + 2;
+
+impl MemberHeader {
+    pub fn name(&self) -> Result<&str> {
+        Ok(self.identifier.pread_with::<&str>(0, ::scroll::ctx::StrCtx::Length(SIZEOF_FILE_IDENTIFER))?)
+    }
+    pub fn size(&self) -> Result<usize> {
+        match usize::from_str_radix(self.file_size.pread_with::<&str>(0, ::scroll::ctx::StrCtx::Length(self.file_size.len()))?.trim_right(), 10) {
+            Ok(file_size) => Ok(file_size),
+            Err(err) => Err(Error::Malformed(format!("{:?} Bad file_size in header: {:?}", err, self)))
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq)]
+/// Represents a single entry in the archive
+pub struct Member<'a> {
+    /// The entry header
+    pub header: Header<'a>,
+    /// File offset from the start of the archive to where the header begins
+    pub header_offset: u64,
+    /// File offset from the start of the archive to where the file begins
+    pub offset: u64,
+    /// BSD `ar` members store the filename separately
+    bsd_name: Option<&'a str>,
+    /// SysV `ar` members store the filename in a string table, a copy of which we hold here
+    sysv_name: Option<&'a str>,
+}
+
+impl<'a> Member<'a> {
+    /// Tries to parse the header in `R`, as well as the offset in `R.
+    /// **NOTE** the Seek will be pointing at the first byte of whatever the file is, skipping padding.
+    /// This is because just like members in the archive, the data section is 2-byte aligned.
+    pub fn parse(buffer: &'a [u8], offset: &mut usize) -> Result<Member<'a>> {
+        let header_offset = *offset;
+        let name = buffer.pread_with::<&str>(*offset, ::scroll::ctx::StrCtx::Length(SIZEOF_FILE_IDENTIFER))?;
+        let archive_header = buffer.gread::<MemberHeader>(offset)?;
+        let mut header = Header { name: name, size: archive_header.size()? };
+
+        // skip newline padding if we're on an uneven byte boundary
+        if *offset & 1 == 1 {
+            *offset += 1;
+        }
+
+        let bsd_name = if let Some(len) = Self::bsd_filename_length(name) {
+            // there's a filename of length `len` right after the header
+            let name = buffer.pread_with::<&str>(header_offset + SIZEOF_HEADER, ::scroll::ctx::StrCtx::Length(len))?;
+
+            // adjust the offset and size accordingly
+            *offset = header_offset + SIZEOF_HEADER + len;
+            header.size -= len;
+
+            // the name may have trailing NULs which we don't really want to keep
+            Some(name.trim_right_matches('\0'))
+        } else {
+            None
+        };
+
+        Ok(Member {
+            header: header,
+            header_offset: header_offset as u64,
+            offset: *offset as u64,
+            bsd_name: bsd_name,
+            sysv_name: None,
+        })
+    }
+
+    /// The size of the Member's content, in bytes. Does **not** include newline padding,
+    /// nor the size of the file header.
+    pub fn size(&self) -> usize {
+        self.header.size
+    }
+
+    /// Parse `#1/123` as `Some(123)`
+    fn bsd_filename_length(name: &str) -> Option<usize> {
+        use core::str::FromStr;
+
+        if name.len() > 3 && &name[0..3] == "#1/" {
+            let trimmed_name = &name[3..].trim_right_matches(' ');
+            if let Ok(len) = usize::from_str(trimmed_name) {
+                Some(len)
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    }
+
+    /// The member name, accounting for SysV and BSD `ar` filename extensions
+    pub fn extended_name(&self) -> &'a str {
+        if let Some(bsd_name) = self.bsd_name {
+            bsd_name
+        } else if let Some(ref sysv_name) = self.sysv_name {
+            sysv_name
+        } else {
+            self.header.name.trim_right_matches(' ').trim_right_matches('/')
+        }
+    }
+
+    /// The untrimmed raw member name, i.e., includes right-aligned space padding and `'/'` end-of-string
+    /// identifier
+    pub fn raw_name(&self) -> &'a str {
+        self.header.name
+    }
+
+}
+
+#[derive(Debug, Default)]
+/// The special index member signified by the name `'/'`.
+/// The data element contains a list of symbol indexes and symbol names, giving their offsets
+/// into the archive for a given name.
+pub struct Index<'a> {
+    /// Big Endian number of symbol_indexes and strings
+    pub size: usize,
+    /// Big Endian u32 index into the archive for this symbol (index in array is the index into the string table)
+    pub symbol_indexes: Vec<u32>,
+    /// Set of zero-terminated strings indexed by above. Number of strings = `self.size`
+    pub strtab: Vec<&'a str>,
+}
+
+/// SysV Archive Variant Symbol Lookup Table "Magic" Name
+const INDEX_NAME: &'static str = "/               ";
+/// SysV Archive Variant Extended Filename String Table Name
+const NAME_INDEX_NAME: &'static str = "//              ";
+/// BSD symbol definitions
+const BSD_SYMDEF_NAME: &'static str = "__.SYMDEF";
+const BSD_SYMDEF_SORTED_NAME: &'static str = "__.SYMDEF SORTED";
+
+impl<'a> Index<'a> {
+    /// Parses the given byte buffer into an Index. NB: the buffer must be the start of the index
+    pub fn parse_sysv_index(buffer: &'a [u8]) -> Result<Self> {
+        let offset = &mut 0;
+        let sizeof_table = buffer.gread_with::<u32>(offset, scroll::BE)? as usize;
+        let mut indexes = Vec::with_capacity(sizeof_table);
+        for _ in 0..sizeof_table {
+            indexes.push(buffer.gread_with::<u32>(offset, scroll::BE)?);
+        }
+        let sizeof_strtab = buffer.len() - ((sizeof_table * 4) + 4);
+        let strtab = strtab::Strtab::parse(buffer, *offset, sizeof_strtab, 0x0)?;
+        Ok (Index {
+            size: sizeof_table,
+            symbol_indexes: indexes,
+            strtab: strtab.to_vec()?, // because i'm lazy
+        })
+    }
+
+    /// Parses the given byte buffer into an Index, in BSD style archives
+    pub fn parse_bsd_symdef(buffer: &'a [u8]) -> Result<Self> {
+        // `llvm-ar` is a suitable reference:
+        //   https://github.com/llvm-mirror/llvm/blob/6ea9891f9310510c621be562d1c5cdfcf5575678/lib/Object/Archive.cpp#L842-L870
+
+        // BSD __.SYMDEF files look like:
+        //
+        //            ┌─────────────┐
+        //  entries:  │   # bytes   │
+        //            ├─────────────┼─────────────┐
+        //            │ name offset │  .o offset  │
+        //            ├─────────────┼─────────────┤
+        //            │ name offset │  .o offset  │
+        //            ├─────────────┼─────────────┤
+        //            │ name offset │  .o offset  │
+        //            ├─────────────┼─────────────┤
+        //            │ name offset │  .o offset  │
+        //            ├─────────────┼─────────────┘
+        //   strings: │   # bytes   │
+        //            ├─────────────┴───────────────────┐
+        //            │  _symbol\0                      │
+        //            ├─────────────────────────────────┴─────────────────────┐
+        //            │  _longer_symbol\0                                     │
+        //            ├────────────────┬──────────────────────────────────────┘
+        //            │  _baz\0        │
+        //            ├────────────────┴───┐
+        //            │  _quxx\0           │
+        //            └────────────────────┘
+        //
+        // All numeric values are u32s. Name offsets are relative to the start of the string table,
+        // and .o offsets are relative to the the start of the archive.
+
+        // Read the number of entries, which is at the start of the symdef (offset 0)
+        let entries_bytes = buffer.pread_with::<u32>(0, scroll::LE)? as usize;
+        let entries = entries_bytes / 8;
+
+        // Set up the string table, the length of which is recorded after the entire entries table,
+        // (`entries_bytes + 4`), and which starts immediately after that (`entries_bytes + 8`).
+        let strtab_bytes = buffer.pread_with::<u32>(entries_bytes + 4, scroll::LE)? as usize;
+        let strtab = strtab::Strtab::parse(buffer, entries_bytes + 8, strtab_bytes, 0x0)?;
+
+        // build the index
+        let mut indexes = Vec::with_capacity(entries);
+        let mut strings = Vec::with_capacity(entries);
+        for i in 0..entries {
+            // The entries table starts after the original length value (offset 4), and each entry
+            // has two u32 values, making them 8 bytes long.
+            //
+            // Therefore, the `i`th entry starts at offset `(i*8)+4`. The first u32 is at that
+            // address, and the second u32 follows 4 bytes later.
+            let string_offset: u32 = buffer.pread_with(i * 8 + 4, scroll::LE)?;
+            let archive_member: u32 =  buffer.pread_with(i * 8 + 8, scroll::LE)?;
+
+            let string = match strtab.get(string_offset as usize) {
+                Some(result) => result,
+                None => Err(Error::Malformed(format!("{} entry {} has string offset {}, which is out of bounds", BSD_SYMDEF_NAME, i, string_offset)))
+            }?;
+
+            indexes.push(archive_member);
+            strings.push(string);
+        }
+
+        Ok (Index {
+            size: entries,
+            symbol_indexes: indexes,
+            strtab: strings,
+        })
+    }
+}
+
+/// Member names greater than 16 bytes are indirectly referenced using a `/<idx` schema,
+/// where `idx` is an offset into a newline delimited string table directly following the `//` member
+/// of the archive.
+#[derive(Debug, Default)]
+struct NameIndex<'a> {
+    strtab: strtab::Strtab<'a>
+}
+
+impl<'a> NameIndex<'a> {
+    pub fn parse(buffer: &'a [u8], offset: &mut usize, size: usize) -> Result<NameIndex<'a>> {
+        // This is a total hack, because strtab returns "" if idx == 0, need to change
+        // but previous behavior might rely on this, as ELF strtab's have "" at 0th index...
+        let hacked_size = size + 1;
+        let strtab = strtab::Strtab::parse(buffer, *offset-1, hacked_size, '\n' as u8)?;
+        // precious time was lost when refactoring because strtab::parse doesn't update the mutable seek...
+        *offset += hacked_size - 2;
+        Ok (NameIndex {
+            strtab: strtab
+        })
+    }
+
+    pub fn get(&self, name: &str) -> Result<&'a str> {
+        let idx = name.trim_left_matches('/').trim_right();
+        match usize::from_str_radix(idx, 10) {
+            Ok(idx) => {
+                let name = match self.strtab.get(idx+1) {
+                    Some(result) => result,
+                    None => Err(Error::Malformed(format!("Name {} is out of range in archive NameIndex", name)))
+                }?;
+
+                if name != "" {
+                    Ok(name.trim_right_matches('/'))
+                }  else {
+                    return Err(Error::Malformed(format!("Could not find {:?} in index", name).into()));
+                }
+            },
+            Err (_) => {
+                return Err(Error::Malformed(format!("Bad name index {:?} in index", name).into()));
+            }
+        }
+    }
+}
+
+// TODO: add pretty printer fmt::Display with number of members, and names of members, along with
+// the values of the index symbols once implemented
+#[derive(Debug)]
+/// An in-memory representation of a parsed Unix Archive
+pub struct Archive<'a> {
+    // we can chuck this because the symbol index is a better representation, but we keep for
+    // debugging
+    index: Index<'a>,
+    sysv_name_index: NameIndex<'a>,
+    // the array of members, which are indexed by the members hash and symbol index
+    member_array: Vec<Member<'a>>,
+    members: BTreeMap<&'a str, usize>,
+    // symbol -> member
+    symbol_index: BTreeMap<&'a str, usize>
+}
+
+
+impl<'a> Archive<'a> {
+    pub fn parse(buffer: &'a [u8]) -> Result<Archive<'a>> {
+        let mut magic = [0u8; SIZEOF_MAGIC];
+        let offset = &mut 0usize;
+        buffer.gread_inout(offset, &mut magic)?;
+        if &magic != MAGIC {
+            use scroll::Pread;
+            return Err(Error::BadMagic(magic.pread(0)?).into());
+        }
+        let mut member_array = Vec::new();
+        let mut index = Index::default();
+        let mut sysv_name_index = NameIndex::default();
+        while *offset < buffer.len() {
+            // realign the cursor to a word boundary, if it's not on one already
+            if *offset & 1 == 1 {
+                *offset += 1;
+            }
+
+            let member = Member::parse(buffer, offset)?;
+
+            // advance to the next record
+            *offset = member.offset as usize + member.size() as usize;
+
+            let name = member.raw_name();
+            if name == INDEX_NAME {
+                let data: &[u8] = buffer.pread_with(member.offset as usize, member.size())?;
+                index = Index::parse_sysv_index(data)?;
+
+            } else if member.bsd_name == Some(BSD_SYMDEF_NAME) || member.bsd_name == Some(BSD_SYMDEF_SORTED_NAME) {
+                let data: &[u8] = buffer.pread_with(member.offset as usize, member.size())?;
+                index = Index::parse_bsd_symdef(data)?;
+
+            } else if name == NAME_INDEX_NAME {
+                let mut name_index_offset: usize = member.offset as usize;
+                sysv_name_index = NameIndex::parse(buffer, &mut name_index_offset, member.size())?;
+
+            } else {
+                // record this as an archive member
+                member_array.push(member);
+            }
+        }
+
+        // preprocess member names
+        let mut members = BTreeMap::new();
+        let mut member_index_by_offset: BTreeMap<u32, usize> = BTreeMap::new();
+        for (i, member) in member_array.iter_mut().enumerate() {
+            // copy in any SysV extended names
+            if let Ok(sysv_name) = sysv_name_index.get(member.raw_name()) {
+                member.sysv_name = Some(sysv_name);
+            }
+
+            // build a hashmap by extended name
+            let key = member.extended_name();
+            members.insert(key, i);
+
+            // build a hashmap translating archive offset into member index
+            member_index_by_offset.insert(member.header_offset as u32, i);
+        }
+
+        // build the symbol index, translating symbol names into member indexes
+        let mut symbol_index: BTreeMap<&str, usize> = BTreeMap::new();
+        for (member_offset, name) in index.symbol_indexes.iter().zip(index.strtab.iter()) {
+            let name = name.clone();
+            let member_index = member_index_by_offset[member_offset];
+            symbol_index.insert(name, member_index);
+        }
+
+        let archive = Archive {
+            index: index,
+            member_array: member_array,
+            sysv_name_index: sysv_name_index,
+            members: members,
+            symbol_index: symbol_index,
+        };
+
+        Ok(archive)
+    }
+
+    /// Get the member named `member` in this archive, if any
+    pub fn get (&self, member: &str) -> Option<&Member> {
+        if let Some(idx) = self.members.get(member) {
+            Some(&self.member_array[*idx])
+        } else {
+            None
+        }
+    }
+
+    /// Returns a slice of the raw bytes for the given `member` in the scrollable `buffer`
+    pub fn extract<'b>(&self, member: &str, buffer: &'b [u8]) -> Result<&'b [u8]> {
+        if let Some(member) = self.get(member) {
+            let bytes = buffer.pread_with(member.offset as usize, member.size())?;
+            Ok(bytes)
+        } else {
+            Err(Error::Malformed(format!("Cannot extract member {:?}", member).into()))
+        }
+    }
+
+    /// Gets a summary of this archive, returning a list of membername, the member, and the list of symbols the member contains
+    pub fn summarize(&self) -> Vec<(&str, &Member, Vec<&'a str>)> {
+        // build a result array, with indexes matching the member indexes
+        let mut result = self.member_array.iter()
+            .map(|ref member| {
+                 (member.extended_name(), *member, Vec::new())
+            })
+            .collect::<Vec<_>>();
+
+        // walk the symbol index once, adding each symbol to the appropriate result Vec
+        for (symbol_name, member_index) in self.symbol_index.iter() {
+            result[*member_index].2.push(*symbol_name);
+        }
+
+        result
+    }
+
+    /// Get the list of member names in this archive
+    pub fn members(&self) -> Vec<&'a str> {
+        self.members.keys().map(|s| *s).collect()
+    }
+
+    /// Returns the member's name which contains the given `symbol`, if it is in the archive
+    pub fn member_of_symbol (&self, symbol: &str) -> Option<&'a str> {
+        if let Some(idx) = self.symbol_index.get(symbol) {
+            Some(self.member_array[*idx].extended_name())
+        } else {
+            None
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_member_bsd_filename_length() {
+        // non-BSD names should fall through
+        assert_eq!(Member::bsd_filename_length(""), None);
+        assert_eq!(Member::bsd_filename_length("123"), None);
+        assert_eq!(Member::bsd_filename_length("#1"), None);
+        assert_eq!(Member::bsd_filename_length("#1/"), None);
+        assert_eq!(Member::bsd_filename_length("#2/1"), None);
+        assert_eq!(Member::bsd_filename_length(INDEX_NAME), None);
+        assert_eq!(Member::bsd_filename_length(NAME_INDEX_NAME), None);
+
+        // #1/<len> should be parsed as Some(len), with or without whitespace
+        assert_eq!(Member::bsd_filename_length("#1/1"), Some(1));
+        assert_eq!(Member::bsd_filename_length("#1/22"), Some(22));
+        assert_eq!(Member::bsd_filename_length("#1/333"), Some(333));
+        assert_eq!(Member::bsd_filename_length("#1/1          "), Some(1));
+        assert_eq!(Member::bsd_filename_length("#1/22         "), Some(22));
+        assert_eq!(Member::bsd_filename_length("#1/333      "), Some(333));
+
+        // #!/<len><trailing garbage> should be None
+        assert_eq!(Member::bsd_filename_length("#1/1A"), None);
+        assert_eq!(Member::bsd_filename_length("#1/1 A"), None);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/compression_header.rs
@@ -0,0 +1,275 @@
+macro_rules! elf_compression_header {
+    () => {
+        use plain;
+        // Declare that this is a plain type.
+        unsafe impl plain::Plain for CompressionHeader {}
+
+        impl ::core::fmt::Debug for CompressionHeader {
+            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+                write!(f,
+                       "ch_type: {} ch_size: 0x{} ch_addralign: 0x{:x}",
+                       self.ch_type,
+                       self.ch_size,
+                       self.ch_addralign)
+            }
+        }
+    }
+}
+
+/// ZLIB/DEFLATE algorithm.
+pub const ELFCOMPRESS_ZLIB: u32 = 1;
+/// Start of OS-specific.
+pub const ELFCOMPRESS_LOOS: u32 = 0x60000000;
+/// End of OS-specific.
+pub const ELFCOMPRESS_HIOS: u32 = 0x6fffffff;
+/// Start of processor-specific.
+pub const ELFCOMPRESS_LOPROC: u32 = 0x70000000;
+/// End of processor-specific.
+pub const ELFCOMPRESS_HIPROC: u32 = 0x7fffffff;
+
+macro_rules! elf_compression_header_std_impl { ($size:ty) => {
+
+    #[cfg(test)]
+    mod test {
+        use super::*;
+        #[test]
+        fn size_of() {
+            assert_eq!(::std::mem::size_of::<CompressionHeader>(), SIZEOF_CHDR);
+        }
+    }
+
+    if_alloc! {
+        use elf::compression_header::CompressionHeader as ElfCompressionHeader;
+
+        use plain::Plain;
+
+        if_std! {
+            use error::Result;
+
+            use std::fs::File;
+            use std::io::{Read, Seek};
+            use std::io::SeekFrom::Start;
+        }
+
+        impl From<CompressionHeader> for ElfCompressionHeader {
+            fn from(ch: CompressionHeader) -> Self {
+                ElfCompressionHeader {
+                    ch_type: ch.ch_type,
+                    ch_size: ch.ch_size as u64,
+                    ch_addralign: ch.ch_addralign as u64,
+                }
+            }
+        }
+
+        impl CompressionHeader {
+            pub fn from_bytes(bytes: &[u8]) -> CompressionHeader {
+                let mut chdr = CompressionHeader::default();
+                chdr.copy_from_bytes(bytes).expect("buffer is too short for header");
+                chdr
+            }
+
+            #[cfg(feature = "std")]
+            pub fn from_fd(fd: &mut File, offset: u64) -> Result<CompressionHeader> {
+                let mut chdr = CompressionHeader::default();
+                try!(fd.seek(Start(offset)));
+                unsafe {
+                    try!(fd.read(plain::as_mut_bytes(&mut chdr)));
+                }
+                Ok(chdr)
+            }
+        }
+    } // end if_alloc
+};}
+
+
+pub mod compression_header32 {
+    pub use elf::compression_header::*;
+
+    #[repr(C)]
+    #[derive(Copy, Clone, Eq, PartialEq, Default)]
+    #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+    /// The compression header is used at the start of SHF_COMPRESSED sections
+    pub struct CompressionHeader {
+        /// Compression format
+        pub ch_type: u32,
+        /// Uncompressed data size
+        pub ch_size: u32,
+        /// Uncompressed data alignment
+        pub ch_addralign: u32,
+    }
+
+    elf_compression_header!();
+
+    pub const SIZEOF_CHDR: usize = 12;
+
+    elf_compression_header_std_impl!(u32);
+
+    if_alloc! {
+        impl From<ElfCompressionHeader> for CompressionHeader {
+            fn from(ch: ElfCompressionHeader) -> Self {
+                CompressionHeader {
+                    ch_type: ch.ch_type,
+                    ch_size: ch.ch_size as u32,
+                    ch_addralign: ch.ch_addralign as u32,
+                }
+            }
+        }
+    }
+}
+
+
+pub mod compression_header64 {
+    pub use elf::compression_header::*;
+
+    #[repr(C)]
+    #[derive(Copy, Clone, Eq, PartialEq, Default)]
+    #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+    /// The compression header is used at the start of SHF_COMPRESSED sections
+    pub struct CompressionHeader {
+        /// Compression format
+        pub ch_type: u32,
+        pub ch_reserved: u32,
+        /// Uncompressed data size
+        pub ch_size: u64,
+        /// Uncompressed data alignment
+        pub ch_addralign: u64,
+    }
+
+    elf_compression_header!();
+
+    pub const SIZEOF_CHDR: usize = 24;
+
+    elf_compression_header_std_impl!(u64);
+
+    if_alloc! {
+        impl From<ElfCompressionHeader> for CompressionHeader {
+            fn from(ch: ElfCompressionHeader) -> Self {
+                CompressionHeader {
+                    ch_type: ch.ch_type,
+                    ch_reserved: 0,
+                    ch_size: ch.ch_size as u64,
+                    ch_addralign: ch.ch_addralign as u64,
+                }
+            }
+        }
+    }
+}
+
+///////////////////////////////
+// Std/analysis/Unified Structs
+///////////////////////////////
+
+if_alloc! {
+    use error;
+    use core::fmt;
+    use core::result;
+    use scroll::ctx;
+    use container::{Container, Ctx};
+
+    #[derive(Default, PartialEq, Clone)]
+    /// A unified CompressionHeader - convertable to and from 32-bit and 64-bit variants
+    pub struct CompressionHeader {
+        /// Compression format
+        pub ch_type: u32,
+        /// Uncompressed data size
+        pub ch_size: u64,
+        /// Uncompressed data alignment
+        pub ch_addralign: u64,
+    }
+
+    impl CompressionHeader {
+        /// Return the size of the underlying compression header, given a `container`
+        #[inline]
+        pub fn size(ctx: &Ctx) -> usize {
+            use scroll::ctx::SizeWith;
+            Self::size_with(ctx)
+        }
+        pub fn new() -> Self {
+            CompressionHeader {
+                ch_type: 0,
+                ch_size: 0,
+                ch_addralign: 2 << 8,
+            }
+        }
+        /// Parse a compression header from `bytes` at `offset`, using the given `ctx`
+        #[cfg(feature = "endian_fd")]
+        pub fn parse(bytes: &[u8], mut offset: usize, ctx: Ctx) -> error::Result<CompressionHeader> {
+            use scroll::Pread;
+            bytes.gread_with(&mut offset, ctx)
+        }
+    }
+
+    impl fmt::Debug for CompressionHeader {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f,
+                   "ch_type: {} ch_size: 0x{} ch_addralign: 0x{:x}",
+                   self.ch_type,
+                   self.ch_size,
+                   self.ch_addralign)
+        }
+    }
+
+    impl ctx::SizeWith<Ctx> for CompressionHeader {
+        type Units = usize;
+        fn size_with( &Ctx { container, .. }: &Ctx) -> Self::Units {
+            match container {
+                Container::Little => {
+                    compression_header32::SIZEOF_CHDR
+                },
+                Container::Big => {
+                    compression_header64::SIZEOF_CHDR
+                },
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, Ctx> for CompressionHeader {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], Ctx {container, le}: Ctx) -> result::Result<(Self, Self::Size), Self::Error> {
+            use scroll::Pread;
+            let res = match container {
+                Container::Little => {
+                    (bytes.pread_with::<compression_header32::CompressionHeader>(0, le)?.into(), compression_header32::SIZEOF_CHDR)
+                },
+                Container::Big => {
+                    (bytes.pread_with::<compression_header64::CompressionHeader>(0, le)?.into(), compression_header64::SIZEOF_CHDR)
+                }
+            };
+            Ok(res)
+        }
+    }
+
+    impl ctx::TryIntoCtx<Ctx> for CompressionHeader {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) -> result::Result<Self::Size, Self::Error> {
+            use scroll::Pwrite;
+            match container {
+                Container::Little => {
+                    let chdr: compression_header32::CompressionHeader = self.into();
+                    Ok(bytes.pwrite_with(chdr, 0, le)?)
+                },
+                Container::Big => {
+                    let chdr: compression_header64::CompressionHeader = self.into();
+                    Ok(bytes.pwrite_with(chdr, 0, le)?)
+                }
+            }
+        }
+    }
+    impl ctx::IntoCtx<Ctx> for CompressionHeader {
+        fn into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) {
+            use scroll::Pwrite;
+            match container {
+                Container::Little => {
+                    let chdr: compression_header32::CompressionHeader = self.into();
+                    bytes.pwrite_with(chdr, 0, le).unwrap();
+                },
+                Container::Big => {
+                    let chdr: compression_header64::CompressionHeader = self.into();
+                    bytes.pwrite_with(chdr, 0, le).unwrap();
+                }
+            }
+        }
+    }
+} // end if_alloc
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/constants_header.rs
@@ -0,0 +1,558 @@
+// sweet emacs regexp
+// pub const \([[:word:]|_]*\)[[:space:]]*\([[:digit:]]+\)[[:space:]]*/\*\(.*\) \*/
+// \\\\3 C-q C-j pub const \1: u32 = \2;
+
+/// TODO: use Enum with explicit discriminant and get debug printer for free?
+
+/// No machine
+pub const EM_NONE: u16 = 0;
+/// AT&T WE 32100
+pub const EM_M32: u16 = 1;
+/// SUN SPARC
+pub const EM_SPARC: u16 = 2;
+/// Intel 80386
+pub const EM_386: u16 = 3;
+/// Motorola m68k family
+pub const EM_68K: u16 = 4;
+/// Motorola m88k family
+pub const EM_88K: u16 = 5;
+/// Intel MCU
+pub const EM_IAMCU: u16 = 6;
+/// Intel 80860
+pub const EM_860: u16 = 7;
+/// MIPS R3000 big-endian
+pub const EM_MIPS: u16 = 8;
+/// IBM System/370
+pub const EM_S370: u16 = 9;
+/// MIPS R3000 little-endian
+pub const EM_MIPS_RS3_LE: u16 = 10;
+// reserved 11-14
+/// HPPA
+pub const EM_PARISC: u16 = 15;
+// reserved 16
+/// Fujitsu VPP500
+pub const EM_VPP500: u16 = 17;
+/// Sun's "v8plus"
+pub const EM_SPARC32PLUS: u16 = 18;
+/// Intel 80960
+pub const EM_960: u16 = 19;
+/// PowerPC
+pub const EM_PPC: u16 = 20;
+/// PowerPC 64-bit
+pub const EM_PPC64: u16 = 21;
+/// IBM S390
+pub const EM_S390: u16 = 22;
+/// IBM SPU/SPC
+pub const EM_SPU: u16 = 23;
+// reserved 24-35
+/// NEC V800 series
+pub const EM_V800: u16 = 36;
+/// Fujitsu FR20
+pub const EM_FR20: u16 = 37;
+/// TRW RH-32
+pub const EM_RH32: u16 = 38;
+/// Motorola RCE
+pub const EM_RCE: u16 = 39;
+/// ARM
+pub const EM_ARM: u16 = 40;
+/// Digital Alpha
+pub const EM_FAKE_ALPHA: u16 = 41;
+/// Hitachi SH
+pub const EM_SH: u16 = 42;
+/// SPARC v9 64-bit
+pub const EM_SPARCV9: u16 = 43;
+/// Siemens Tricore
+pub const EM_TRICORE: u16 = 44;
+/// Argonaut RISC Core
+pub const EM_ARC: u16 = 45;
+/// Hitachi H8/300
+pub const EM_H8_300: u16 = 46;
+/// Hitachi H8/300H
+pub const EM_H8_300H: u16 = 47;
+/// Hitachi H8S
+pub const EM_H8S: u16 = 48;
+/// Hitachi H8/500
+pub const EM_H8_500: u16 = 49;
+/// Intel Merced
+pub const EM_IA_64: u16 = 50;
+/// Stanford MIPS-X
+pub const EM_MIPS_X: u16 = 51;
+/// Motorola Coldfire
+pub const EM_COLDFIRE: u16 = 52;
+/// Motorola M68HC12
+pub const EM_68HC12: u16 = 53;
+/// Fujitsu MMA Multimedia Accelerator
+pub const EM_MMA: u16 = 54;
+/// Siemens PCP
+pub const EM_PCP: u16 = 55;
+/// Sony nCPU embeeded RISC
+pub const EM_NCPU: u16 = 56;
+/// Denso NDR1 microprocessor
+pub const EM_NDR1: u16 = 57;
+/// Motorola Start*Core processor
+pub const EM_STARCORE: u16 = 58;
+/// Toyota ME16 processor
+pub const EM_ME16: u16 = 59;
+/// STMicroelectronic ST100 processor
+pub const EM_ST100: u16 = 60;
+/// Advanced Logic Corp. Tinyj emb.fam
+pub const EM_TINYJ: u16 = 61;
+/// AMD x86-64 architecture
+pub const EM_X86_64: u16 = 62;
+/// Sony DSP Processor
+pub const EM_PDSP: u16 = 63;
+/// Digital PDP-10
+pub const EM_PDP10: u16 = 64;
+/// Digital PDP-11
+pub const EM_PDP11: u16 = 65;
+/// Siemens FX66 microcontroller
+pub const EM_FX66: u16 = 66;
+/// STMicroelectronics ST9+ 8/16 mc
+pub const EM_ST9PLUS: u16 = 67;
+/// STmicroelectronics ST7 8 bit mc
+pub const EM_ST7: u16 = 68;
+/// Motorola MC68HC16 microcontroller
+pub const EM_68HC16: u16 = 69;
+/// Motorola MC68HC11 microcontroller
+pub const EM_68HC11: u16 = 70;
+/// Motorola MC68HC08 microcontroller
+pub const EM_68HC08: u16 = 71;
+/// Motorola MC68HC05 microcontroller
+pub const EM_68HC05: u16 = 72;
+/// Silicon Graphics SVx
+pub const EM_SVX: u16 = 73;
+/// STMicroelectronics ST19 8 bit mc
+pub const EM_ST19: u16 = 74;
+/// Digital VAX
+pub const EM_VAX: u16 = 75;
+/// Axis Communications 32-bit emb.proc
+pub const EM_CRIS: u16 = 76;
+/// Infineon Technologies 32-bit emb.proc
+pub const EM_JAVELIN: u16 = 77;
+/// Element 14 64-bit DSP Processor
+pub const EM_FIREPATH: u16 = 78;
+/// LSI Logic 16-bit DSP Processor
+pub const EM_ZSP: u16 = 79;
+/// Donald Knuth's educational 64-bit proc
+pub const EM_MMIX: u16 = 80;
+/// Harvard University machine-independent object files
+pub const EM_HUANY: u16 = 81;
+/// SiTera Prism
+pub const EM_PRISM: u16 = 82;
+/// Atmel AVR 8-bit microcontroller
+pub const EM_AVR: u16 = 83;
+/// Fujitsu FR30
+pub const EM_FR30: u16 = 84;
+/// Mitsubishi D10V
+pub const EM_D10V: u16 = 85;
+/// Mitsubishi D30V
+pub const EM_D30V: u16 = 86;
+/// NEC v850
+pub const EM_V850: u16 = 87;
+/// Mitsubishi M32R
+pub const EM_M32R: u16 = 88;
+/// Matsushita MN10300
+pub const EM_MN10300: u16 = 89;
+/// Matsushita MN10200
+pub const EM_MN10200: u16 = 90;
+/// picoJava
+pub const EM_PJ: u16 = 91;
+/// OpenRISC 32-bit embedded processor
+pub const EM_OPENRISC: u16 = 92;
+/// ARC International ARCompact
+pub const EM_ARC_COMPACT: u16 = 93;
+/// Tensilica Xtensa Architecture
+pub const EM_XTENSA: u16 = 94;
+/// Alphamosaic VideoCore
+pub const EM_VIDEOCORE: u16 = 95;
+/// Thompson Multimedia General Purpose Proc
+pub const EM_TMM_GPP: u16 = 96;
+/// National Semi. 32000
+pub const EM_NS32K: u16 = 97;
+/// Tenor Network TPC
+pub const EM_TPC: u16 = 98;
+/// Trebia SNP 1000
+pub const EM_SNP1K: u16 = 99;
+/// STMicroelectronics ST200
+pub const EM_ST200: u16 = 100;
+/// Ubicom IP2xxx
+pub const EM_IP2K: u16 = 101;
+/// MAX processor
+pub const EM_MAX: u16 = 102;
+/// National Semi. CompactRISC
+pub const EM_CR: u16 = 103;
+/// Fujitsu F2MC16
+pub const EM_F2MC16: u16 = 104;
+/// Texas Instruments msp430
+pub const EM_MSP430: u16 = 105;
+/// Analog Devices Blackfin DSP
+pub const EM_BLACKFIN: u16 = 106;
+/// Seiko Epson S1C33 family
+pub const EM_SE_C33: u16 = 107;
+/// Sharp embedded microprocessor
+pub const EM_SEP: u16 = 108;
+/// Arca RISC
+pub const EM_ARCA: u16 = 109;
+/// PKU-Unity & MPRC Peking Uni. mc series
+pub const EM_UNICORE: u16 = 110;
+/// eXcess configurable cpu
+pub const EM_EXCESS: u16 = 111;
+/// Icera Semi. Deep Execution Processor
+pub const EM_DXP: u16 = 112;
+/// Altera Nios II
+pub const EM_ALTERA_NIOS2: u16 = 113;
+/// National Semi. CompactRISC CRX
+pub const EM_CRX: u16 = 114;
+/// Motorola XGATE
+pub const EM_XGATE: u16 = 115;
+/// Infineon C16x/XC16x
+pub const EM_C166: u16 = 116;
+/// Renesas M16C
+pub const EM_M16C: u16 = 117;
+/// Microchip Technology dsPIC30F
+pub const EM_DSPIC30F: u16 = 118;
+/// Freescale Communication Engine RISC
+pub const EM_CE: u16 = 119;
+/// Renesas M32C
+pub const EM_M32C: u16 = 120;
+// reserved 121-130
+/// Altium TSK3000
+pub const EM_TSK3000: u16 = 131;
+/// Freescale RS08
+pub const EM_RS08: u16 = 132;
+/// Analog Devices SHARC family
+pub const EM_SHARC: u16 = 133;
+/// Cyan Technology eCOG2
+pub const EM_ECOG2: u16 = 134;
+/// Sunplus S+core7 RISC
+pub const EM_SCORE7: u16 = 135;
+/// New Japan Radio (NJR) 24-bit DSP
+pub const EM_DSP24: u16 = 136;
+/// Broadcom VideoCore III
+pub const EM_VIDEOCORE3: u16 = 137;
+/// RISC for Lattice FPGA
+pub const EM_LATTICEMICO32: u16 = 138;
+/// Seiko Epson C17
+pub const EM_SE_C17: u16 = 139;
+/// Texas Instruments TMS320C6000 DSP
+pub const EM_TI_C6000: u16 = 140;
+/// Texas Instruments TMS320C2000 DSP
+pub const EM_TI_C2000: u16 = 141;
+/// Texas Instruments TMS320C55x DSP
+pub const EM_TI_C5500: u16 = 142;
+/// Texas Instruments App. Specific RISC
+pub const EM_TI_ARP32: u16 = 143;
+/// Texas Instruments Prog. Realtime Unit
+pub const EM_TI_PRU: u16 = 144;
+// reserved 145-159
+/// STMicroelectronics 64bit VLIW DSP
+pub const EM_MMDSP_PLUS: u16 = 160;
+/// Cypress M8C
+pub const EM_CYPRESS_M8C: u16 = 161;
+/// Renesas R32C
+pub const EM_R32C: u16 = 162;
+/// NXP Semi. TriMedia
+pub const EM_TRIMEDIA: u16 = 163;
+/// QUALCOMM DSP6
+pub const EM_QDSP6: u16 = 164;
+/// Intel 8051 and variants
+pub const EM_8051: u16 = 165;
+/// STMicroelectronics STxP7x
+pub const EM_STXP7X: u16 = 166;
+/// Andes Tech. compact code emb. RISC
+pub const EM_NDS32: u16 = 167;
+/// Cyan Technology eCOG1X
+pub const EM_ECOG1X: u16 = 168;
+/// Dallas Semi. MAXQ30 mc
+pub const EM_MAXQ30: u16 = 169;
+/// New Japan Radio (NJR) 16-bit DSP
+pub const EM_XIMO16: u16 = 170;
+/// M2000 Reconfigurable RISC
+pub const EM_MANIK: u16 = 171;
+/// Cray NV2 vector architecture
+pub const EM_CRAYNV2: u16 = 172;
+/// Renesas RX
+pub const EM_RX: u16 = 173;
+/// Imagination Tech. META
+pub const EM_METAG: u16 = 174;
+/// MCST Elbrus
+pub const EM_MCST_ELBRUS: u16 = 175;
+/// Cyan Technology eCOG16
+pub const EM_ECOG16: u16 = 176;
+/// National Semi. CompactRISC CR16
+pub const EM_CR16: u16 = 177;
+/// Freescale Extended Time Processing Unit
+pub const EM_ETPU: u16 = 178;
+/// Infineon Tech. SLE9X
+pub const EM_SLE9X: u16 = 179;
+/// Intel L10M
+pub const EM_L10M: u16 = 180;
+/// Intel K10M
+pub const EM_K10M: u16 = 181;
+// reserved 182
+/// ARM AARCH64
+pub const EM_AARCH64: u16 = 183;
+// reserved 184
+/// Amtel 32-bit microprocessor
+pub const EM_AVR32: u16 = 185;
+/// STMicroelectronics STM8
+pub const EM_STM8: u16 = 186;
+/// Tileta TILE64
+pub const EM_TILE64: u16 = 187;
+/// Tilera TILEPro
+pub const EM_TILEPRO: u16 = 188;
+/// Xilinx MicroBlaze
+pub const EM_MICROBLAZE: u16 = 189;
+/// NVIDIA CUDA
+pub const EM_CUDA: u16 = 190;
+/// Tilera TILE-Gx
+pub const EM_TILEGX: u16 = 191;
+/// CloudShield
+pub const EM_CLOUDSHIELD: u16 = 192;
+/// KIPO-KAIST Core-A 1st gen.
+pub const EM_COREA_1ST: u16 = 193;
+/// KIPO-KAIST Core-A 2nd gen.
+pub const EM_COREA_2ND: u16 = 194;
+/// Synopsys ARCompact V2
+pub const EM_ARC_COMPACT2: u16 = 195;
+/// Open8 RISC
+pub const EM_OPEN8: u16 = 196;
+/// Renesas RL78
+pub const EM_RL78: u16 = 197;
+/// Broadcom VideoCore V
+pub const EM_VIDEOCORE5: u16 = 198;
+/// Renesas 78KOR
+pub const EM_78KOR: u16 = 199;
+/// Freescale 56800EX DSC
+pub const EM_56800EX: u16 = 200;
+/// Beyond BA1
+pub const EM_BA1: u16 = 201;
+/// Beyond BA2
+pub const EM_BA2: u16 = 202;
+/// XMOS xCORE
+pub const EM_XCORE: u16 = 203;
+/// Microchip 8-bit PIC(r)
+pub const EM_MCHP_PIC: u16 = 204;
+// reserved 205-209
+/// KM211 KM32
+pub const EM_KM32: u16 = 210;
+/// KM211 KMX32
+pub const EM_KMX32: u16 = 211;
+/// KM211 KMX16
+pub const EM_EMX16: u16 = 212;
+/// KM211 KMX8
+pub const EM_EMX8: u16 = 213;
+/// KM211 KVARC
+pub const EM_KVARC: u16 = 214;
+/// Paneve CDP
+pub const EM_CDP: u16 = 215;
+/// Cognitive Smart Memory Processor
+pub const EM_COGE: u16 = 216;
+/// Bluechip CoolEngine
+pub const EM_COOL: u16 = 217;
+/// Nanoradio Optimized RISC
+pub const EM_NORC: u16 = 218;
+/// CSR Kalimba
+pub const EM_CSR_KALIMBA: u16 = 219;
+/// Zilog Z80
+pub const EM_Z80: u16 = 220;
+/// Controls and Data Services VISIUMcore
+pub const EM_VISIUM: u16 = 221;
+/// FTDI Chip FT32
+pub const EM_FT32: u16 = 222;
+/// Moxie processor
+pub const EM_MOXIE: u16 = 223;
+/// AMD GPU
+pub const EM_AMDGPU: u16 = 224;
+// reserved 225-242
+/// RISC-V
+pub const EM_RISCV: u16 = 243;
+
+/// Linux BPF -- in-kernel virtual machine
+pub const EM_BPF: u16 = 247;
+
+pub const EM_NUM: u16 = 248;
+
+/// Convert machine to str representation
+pub fn machine_to_str (machine: u16) -> &'static str {
+    match machine {
+        EM_M32 => "M32",
+        EM_SPARC => "SPARC",
+        EM_386 => "386",
+        EM_68K => "68K",
+        EM_88K => "88K",
+        EM_IAMCU => "IAMCU",
+        EM_860 => "860",
+        EM_MIPS => "MIPS",
+        EM_S370 => "S370",
+        EM_MIPS_RS3_LE => "MIPS_RS3_LE",
+        EM_PARISC => "PARISC",
+        EM_VPP500 => "VPP500",
+        EM_SPARC32PLUS => "SPARC32PLUS",
+        EM_960 => "960",
+        EM_PPC => "PPC",
+        EM_PPC64 => "PPC64",
+        EM_S390 => "S390",
+        EM_SPU => "SPU",
+        EM_V800 => "V800",
+        EM_FR20 => "FR20",
+        EM_RH32 => "RH32",
+        EM_RCE => "RCE",
+        EM_ARM => "ARM",
+        EM_FAKE_ALPHA => "FAKE_ALPHA",
+        EM_SH => "SH",
+        EM_SPARCV9 => "SPARCV9",
+        EM_TRICORE => "TRICORE",
+        EM_ARC => "ARC",
+        EM_H8_300 => "H8_300",
+        EM_H8_300H => "H8_300H",
+        EM_H8S => "H8S",
+        EM_H8_500 => "H8_500",
+        EM_IA_64 => "IA_64",
+        EM_MIPS_X => "MIPS_X",
+        EM_COLDFIRE => "COLDFIRE",
+        EM_68HC12 => "68HC12",
+        EM_MMA => "MMA",
+        EM_PCP => "PCP",
+        EM_NCPU => "NCPU",
+        EM_NDR1 => "NDR1",
+        EM_STARCORE => "STARCORE",
+        EM_ME16 => "ME16",
+        EM_ST100 => "ST100",
+        EM_TINYJ => "TINYJ",
+        EM_X86_64 => "X86_64",
+        EM_PDSP => "PDSP",
+        EM_PDP10 => "PDP10",
+        EM_PDP11 => "PDP11",
+        EM_FX66 => "FX66",
+        EM_ST9PLUS => "ST9PLUS",
+        EM_ST7 => "ST7",
+        EM_68HC16 => "68HC16",
+        EM_68HC11 => "68HC11",
+        EM_68HC08 => "68HC08",
+        EM_68HC05 => "68HC05",
+        EM_SVX => "SVX",
+        EM_ST19 => "ST19",
+        EM_VAX => "VAX",
+        EM_CRIS => "CRIS",
+        EM_JAVELIN => "JAVELIN",
+        EM_FIREPATH => "FIREPATH",
+        EM_ZSP => "ZSP",
+        EM_MMIX => "MMIX",
+        EM_HUANY => "HUANY",
+        EM_PRISM => "PRISM",
+        EM_AVR => "AVR",
+        EM_FR30 => "FR30",
+        EM_D10V => "D10V",
+        EM_D30V => "D30V",
+        EM_V850 => "V850",
+        EM_M32R => "M32R",
+        EM_MN10300 => "MN10300",
+        EM_MN10200 => "MN10200",
+        EM_PJ => "PJ",
+        EM_OPENRISC => "OPENRISC",
+        EM_ARC_COMPACT => "ARC_COMPACT",
+        EM_XTENSA => "XTENSA",
+        EM_VIDEOCORE => "VIDEOCORE",
+        EM_TMM_GPP => "TMM_GPP",
+        EM_NS32K => "NS32K",
+        EM_TPC => "TPC",
+        EM_SNP1K => "SNP1K",
+        EM_ST200 => "ST200",
+        EM_IP2K => "IP2K",
+        EM_MAX => "MAX",
+        EM_CR => "CR",
+        EM_F2MC16 => "F2MC16",
+        EM_MSP430 => "MSP430",
+        EM_BLACKFIN => "BLACKFIN",
+        EM_SE_C33 => "SE_C33",
+        EM_SEP => "SEP",
+        EM_ARCA => "ARCA",
+        EM_UNICORE => "UNICORE",
+        EM_EXCESS => "EXCESS",
+        EM_DXP => "DXP",
+        EM_ALTERA_NIOS2 => "ALTERA_NIOS2",
+        EM_CRX => "CRX",
+        EM_XGATE => "XGATE",
+        EM_C166 => "C166",
+        EM_M16C => "M16C",
+        EM_DSPIC30F => "DSPIC30F",
+        EM_CE => "CE",
+        EM_M32C => "M32C",
+        EM_TSK3000 => "TSK3000",
+        EM_RS08 => "RS08",
+        EM_SHARC => "SHARC",
+        EM_ECOG2 => "ECOG2",
+        EM_SCORE7 => "SCORE7",
+        EM_DSP24 => "DSP24",
+        EM_VIDEOCORE3 => "VIDEOCORE3",
+        EM_LATTICEMICO32 => "LATTICEMICO32",
+        EM_SE_C17 => "SE_C17",
+        EM_TI_C6000 => "TI_C6000",
+        EM_TI_C2000 => "TI_C2000",
+        EM_TI_C5500 => "TI_C5500",
+        EM_TI_ARP32 => "TI_ARP32",
+        EM_TI_PRU => "TI_PRU",
+        EM_MMDSP_PLUS => "MMDSP_PLUS",
+        EM_CYPRESS_M8C => "CYPRESS_M8C",
+        EM_R32C => "R32C",
+        EM_TRIMEDIA => "TRIMEDIA",
+        EM_QDSP6 => "QDSP6",
+        EM_8051 => "8051",
+        EM_STXP7X => "STXP7X",
+        EM_NDS32 => "NDS32",
+        EM_ECOG1X => "ECOG1X",
+        EM_MAXQ30 => "MAXQ30",
+        EM_XIMO16 => "XIMO16",
+        EM_MANIK => "MANIK",
+        EM_CRAYNV2 => "CRAYNV2",
+        EM_RX => "RX",
+        EM_METAG => "METAG",
+        EM_MCST_ELBRUS => "MCST_ELBRUS",
+        EM_ECOG16 => "ECOG16",
+        EM_CR16 => "CR16",
+        EM_ETPU => "ETPU",
+        EM_SLE9X => "SLE9X",
+        EM_L10M => "L10M",
+        EM_K10M => "K10M",
+        EM_AARCH64 => "AARCH64",
+        EM_AVR32 => "AVR32",
+        EM_STM8 => "STM8",
+        EM_TILE64 => "TILE64",
+        EM_TILEPRO => "TILEPRO",
+        EM_MICROBLAZE => "MICROBLAZE",
+        EM_CUDA => "CUDA",
+        EM_TILEGX => "TILEGX",
+        EM_CLOUDSHIELD => "CLOUDSHIELD",
+        EM_COREA_1ST => "COREA_1ST",
+        EM_COREA_2ND => "COREA_2ND",
+        EM_ARC_COMPACT2 => "ARC_COMPACT2",
+        EM_OPEN8 => "OPEN8",
+        EM_RL78 => "RL78",
+        EM_VIDEOCORE5 => "VIDEOCORE5",
+        EM_78KOR => "78KOR",
+        EM_56800EX => "56800EX",
+        EM_BA1 => "BA1",
+        EM_BA2 => "BA2",
+        EM_XCORE => "XCORE",
+        EM_MCHP_PIC => "MCHP_PIC",
+        EM_KM32 => "KM32",
+        EM_KMX32 => "KMX32",
+        EM_EMX16 => "EMX16",
+        EM_EMX8 => "EMX8",
+        EM_KVARC => "KVARC",
+        EM_CDP => "CDP",
+        EM_COGE => "COGE",
+        EM_COOL => "COOL",
+        EM_NORC => "NORC",
+        EM_CSR_KALIMBA => "CSR_KALIMBA",
+        EM_Z80 => "Z80",
+        EM_VISIUM => "VISIUM",
+        EM_FT32 => "FT32",
+        EM_MOXIE => "MOXIE",
+        EM_AMDGPU => "AMDGPU",
+        EM_RISCV => "RISCV",
+        EM_BPF => "BPF",
+        _val => "EM_UNKNOWN",
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/constants_relocation.rs
@@ -0,0 +1,1248 @@
+// x86_64 relocations
+/// No reloc.
+pub const R_X86_64_NONE: u32 = 0;
+/// Direct 64 bit.
+pub const R_X86_64_64: u32 = 1;
+/// PC relative 32 bit signed.
+pub const R_X86_64_PC32: u32 = 2;
+/// 32 bit GOT entry.
+pub const R_X86_64_GOT32: u32 = 3;
+/// 32 bit PLT address.
+pub const R_X86_64_PLT32: u32 = 4;
+/// Copy symbol at runtime.
+pub const R_X86_64_COPY: u32 = 5;
+/// Create GOT entry.
+pub const R_X86_64_GLOB_DAT: u32 = 6;
+/// Create PLT entry.
+pub const R_X86_64_JUMP_SLOT: u32 = 7;
+/// Adjust by program base.
+pub const R_X86_64_RELATIVE: u32 = 8;
+/// 32 bit signed PC relative offset to GOT.
+pub const R_X86_64_GOTPCREL: u32 = 9;
+/// Direct 32 bit zero extended.
+pub const R_X86_64_32: u32 = 10;
+/// Direct 32 bit sign extended.
+pub const R_X86_64_32S: u32 = 11;
+/// Direct 16 bit zero extended.
+pub const R_X86_64_16: u32 = 12;
+/// 16 bit sign extended pc relative.
+pub const R_X86_64_PC16: u32 = 13;
+/// Direct 8 bit sign extended.
+pub const R_X86_64_8: u32 = 14;
+/// 8 bit sign extended pc relative.
+pub const R_X86_64_PC8: u32 = 15;
+/// ID of module containing symbol.
+pub const R_X86_64_DTPMOD64: u32 = 16;
+/// Offset in module's TLS block.
+pub const R_X86_64_DTPOFF64: u32 = 17;
+/// Offset in initial TLS block.
+pub const R_X86_64_TPOFF64: u32 = 18;
+/// 32 bit signed PC relative offset to two GOT entries for GD symbol.
+pub const R_X86_64_TLSGD: u32 = 19;
+/// 32 bit signed PC relative offset to two GOT entries for LD symbol.
+pub const R_X86_64_TLSLD: u32 = 20;
+/// Offset in TLS block.
+pub const R_X86_64_DTPOFF32: u32 = 21;
+/// 32 bit signed PC relative offset to GOT entry for IE symbol.
+pub const R_X86_64_GOTTPOFF: u32 = 22;
+/// Offset in initial TLS block.
+pub const R_X86_64_TPOFF32: u32 = 23;
+/// PC relative 64 bit.
+pub const R_X86_64_PC64: u32 = 24;
+/// 64 bit offset to GOT.
+pub const R_X86_64_GOTOFF64: u32 = 25;
+/// 32 bit signed pc relative offset to GOT.
+pub const R_X86_64_GOTPC32: u32 = 26;
+/// 64-bit GOT entry offset.
+pub const R_X86_64_GOT64: u32 = 27;
+/// 64-bit PC relative offset to GOT entry.
+pub const R_X86_64_GOTPCREL64: u32 = 28;
+/// 64-bit PC relative offset to GOT.
+pub const R_X86_64_GOTPC64: u32 = 29;
+/// like GOT64, says PLT entry needed.
+pub const R_X86_64_GOTPLT64: u32 = 30;
+/// 64-bit GOT relative offset to PLT entry.
+pub const R_X86_64_PLTOFF64: u32 = 31;
+/// Size of symbol plus 32-bit addend.
+pub const R_X86_64_SIZE32: u32 = 32;
+/// Size of symbol plus 64-bit addend.
+pub const R_X86_64_SIZE64: u32 = 33;
+/// GOT offset for TLS descriptor..
+pub const R_X86_64_GOTPC32_TLSDESC: u32 = 34;
+/// Marker for call through TLS descriptor..
+pub const R_X86_64_TLSDESC_CALL: u32 = 35;
+/// TLS descriptor..
+pub const R_X86_64_TLSDESC: u32 = 36;
+/// Adjust indirectly by program base.
+pub const R_X86_64_IRELATIVE: u32 = 37;
+/// 64-bit adjust by program base.
+pub const R_X86_64_RELATIVE64: u32 = 38;
+///Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable.
+pub const R_X86_64_GOTPCRELX: u32 = 41;
+/// Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable.
+pub const R_X86_64_REX_GOTPCRELX: u32 = 42;
+pub const R_X86_64_NUM: u32 = 43;
+
+// Intel 80386 specific definitions
+
+// i386 relocs
+/// No reloc
+pub const R_386_NONE: u32 = 0;
+/// Direct 32 bit
+pub const R_386_32: u32 = 1;
+/// PC relative 32 bit
+pub const R_386_PC32: u32 = 2;
+/// 32 bit GOT entry
+pub const R_386_GOT32: u32 = 3;
+/// 32 bit PLT address
+pub const R_386_PLT32: u32 = 4;
+/// Copy symbol at runtime
+pub const R_386_COPY: u32 = 5;
+/// Create GOT entry
+pub const R_386_GLOB_DAT: u32 = 6;
+/// Create PLT entry
+pub const R_386_JMP_SLOT: u32 = 7;
+/// Adjust by program base
+pub const R_386_RELATIVE: u32 = 8;
+/// 32 bit offset to GOT
+pub const R_386_GOTOFF: u32 = 9;
+/// 32 bit PC relative offset to GOT
+pub const R_386_GOTPC: u32 = 10;
+pub const R_386_32PLT: u32 = 11;
+/// Offset in static TLS block
+pub const R_386_TLS_TPOFF: u32 = 14;
+/// Address of GOT entry for static TLS block offset
+pub const R_386_TLS_IE: u32 = 15;
+/// GOT entry for static TLS block offset
+pub const R_386_TLS_GOTIE: u32 = 16;
+/// Offset relative to static TLS block
+pub const R_386_TLS_LE: u32 = 17;
+/// Direct 32 bit for GNU version of general dynamic thread local data
+pub const R_386_TLS_GD: u32 = 18;
+/// Direct 32 bit for GNU version of local dynamic thread local data in LE code
+pub const R_386_TLS_LDM: u32 = 19;
+pub const R_386_16: u32 = 20;
+pub const R_386_PC16: u32 = 21;
+pub const R_386_8: u32 = 22;
+pub const R_386_PC8: u32 = 23;
+/// Direct 32 bit for general dynamic thread local data
+pub const R_386_TLS_GD_32: u32 = 24;
+/// Tag for pushl in GD TLS code
+pub const R_386_TLS_GD_PUSH: u32 = 25;
+/// Relocation for call to __tls_get_addr()
+pub const R_386_TLS_GD_CALL: u32 = 26;
+/// Tag for popl in GD TLS code
+pub const R_386_TLS_GD_POP: u32 = 27;
+/// Direct 32 bit for local dynamic thread local data in LE code
+pub const R_386_TLS_LDM_32: u32 = 28;
+/// Tag for pushl in LDM TLS code
+pub const R_386_TLS_LDM_PUSH: u32 = 29;
+/// Relocation for call to __tls_get_addr() in LDM code
+pub const R_386_TLS_LDM_CALL: u32 = 30;
+/// Tag for popl in LDM TLS code
+pub const R_386_TLS_LDM_POP: u32 = 31;
+/// Offset relative to TLS block
+pub const R_386_TLS_LDO_32: u32 = 32;
+/// GOT entry for negated static TLS block offset
+pub const R_386_TLS_IE_32: u32 = 33;
+/// Negated offset relative to static TLS block
+pub const R_386_TLS_LE_32: u32 = 34;
+/// ID of module containing symbol
+pub const R_386_TLS_DTPMOD32: u32 = 35;
+/// Offset in TLS block
+pub const R_386_TLS_DTPOFF32: u32 = 36;
+/// Negated offset in static TLS block
+pub const R_386_TLS_TPOFF32: u32 = 37;
+/// 32-bit symbol size
+pub const R_386_SIZE32: u32 = 38;
+/// GOT offset for TLS descriptor.
+pub const R_386_TLS_GOTDESC: u32 = 39;
+/// Marker of call through TLS descriptor for relaxation
+pub const R_386_TLS_DESC_CALL: u32 = 40;
+/// TLS descriptor containing pointer to code and to argument, returning the TLS offset for the symbol
+pub const R_386_TLS_DESC: u32 = 41;
+/// Adjust indirectly by program base
+pub const R_386_IRELATIVE: u32 = 42;
+/// Load from 32 bit GOT entry, relaxable
+pub const R_386_GOT32X: u32 = 43;
+/// Keep this the last entry
+pub const R_386_NUM: u32 = 44;
+
+// AArch64 relocs
+/// No relocation
+pub const R_AARCH64_NONE: u32 = 0;
+
+// ILP32 AArch64 relocs
+/// Direct 32 bit
+pub const R_AARCH64_P32_ABS32: u32 = 1;
+/// Copy symbol at runtime
+pub const R_AARCH64_P32_COPY: u32 = 180;
+/// Create GOT entry
+pub const R_AARCH64_P32_GLOB_DAT: u32 = 181;
+/// Create PLT entry
+pub const R_AARCH64_P32_JUMP_SLOT: u32 = 182;
+/// Adjust by program base
+pub const R_AARCH64_P32_RELATIVE: u32 = 183;
+/// Module number, 32 bit
+pub const R_AARCH64_P32_TLS_DTPMOD: u32 = 184;
+/// Module-relative offset, 32 bit
+pub const R_AARCH64_P32_TLS_DTPREL: u32 = 185;
+/// TP-relative offset, 32 bit
+pub const R_AARCH64_P32_TLS_TPREL: u32 = 186;
+/// TLS Descriptor
+pub const R_AARCH64_P32_TLSDESC: u32 = 187;
+/// STT_GNU_IFUNC relocation
+pub const R_AARCH64_P32_IRELATIVE: u32 = 188;
+
+// LP64 AArch64 relocs
+/// Direct 64 bit
+pub const R_AARCH64_ABS64: u32 = 257;
+/// Direct 32 bit
+pub const R_AARCH64_ABS32: u32 = 258;
+/// Direct 16-bit
+pub const R_AARCH64_ABS16: u32 = 259;
+/// PC-relative 64-bit
+pub const R_AARCH64_PREL64: u32 = 260;
+/// PC-relative 32-bit
+pub const R_AARCH64_PREL32: u32 = 261;
+/// PC-relative 16-bit
+pub const R_AARCH64_PREL16: u32 = 262;
+/// Dir. MOVZ imm. from bits 15:0
+pub const R_AARCH64_MOVW_UABS_G0: u32 = 263;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_UABS_G0_NC: u32 = 264;
+/// Dir. MOVZ imm. from bits 31:16
+pub const R_AARCH64_MOVW_UABS_G1: u32 = 265;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_UABS_G1_NC: u32 = 266;
+/// Dir. MOVZ imm. from bits 47:32
+pub const R_AARCH64_MOVW_UABS_G2: u32 = 267;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_UABS_G2_NC: u32 = 268;
+/// Dir. MOV{K,Z} imm. from 63:48
+pub const R_AARCH64_MOVW_UABS_G3: u32 = 269;
+/// Dir. MOV{N,Z} imm. from 15:0
+pub const R_AARCH64_MOVW_SABS_G0: u32 = 270;
+/// Dir. MOV{N,Z} imm. from 31:16
+pub const R_AARCH64_MOVW_SABS_G1: u32 = 271;
+/// Dir. MOV{N,Z} imm. from 47:32
+pub const R_AARCH64_MOVW_SABS_G2: u32 = 272;
+/// PC-rel. LD imm. from bits 20:2
+pub const R_AARCH64_LD_PREL_LO19: u32 = 273;
+/// PC-rel. ADR imm. from bits 20:0
+pub const R_AARCH64_ADR_PREL_LO21: u32 = 274;
+/// Page-rel. ADRP imm. from 32:12
+pub const R_AARCH64_ADR_PREL_PG_HI21: u32 = 275;
+/// Likewise; no overflow check
+pub const R_AARCH64_ADR_PREL_PG_HI21_NC: u32 = 276;
+/// Dir. ADD imm. from bits 11:0
+pub const R_AARCH64_ADD_ABS_LO12_NC: u32 = 277;
+/// Likewise for LD/ST; no check.
+pub const R_AARCH64_LDST8_ABS_LO12_NC: u32 = 278;
+/// PC-rel. TBZ/TBNZ imm. from 15:2
+pub const R_AARCH64_TSTBR14: u32 = 279;
+/// PC-rel. cond. br. imm. from 20:2.
+pub const R_AARCH64_CONDBR19: u32 = 280;
+/// PC-rel. B imm. from bits 27:2
+pub const R_AARCH64_JUMP26: u32 = 282;
+/// Likewise for CALL
+pub const R_AARCH64_CALL26: u32 = 283;
+/// Dir. ADD imm. from bits 11:1
+pub const R_AARCH64_LDST16_ABS_LO12_NC: u32 = 284;
+/// Likewise for bits 11:2
+pub const R_AARCH64_LDST32_ABS_LO12_NC: u32 = 285;
+/// Likewise for bits 11:3
+pub const R_AARCH64_LDST64_ABS_LO12_NC: u32 = 286;
+/// PC-rel. MOV{N,Z} imm. from 15:0
+pub const R_AARCH64_MOVW_PREL_G0: u32 = 287;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_PREL_G0_NC: u32 = 288;
+/// PC-rel. MOV{N,Z} imm. from 31:16.
+pub const R_AARCH64_MOVW_PREL_G1: u32 = 289;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_PREL_G1_NC: u32 = 290;
+/// PC-rel. MOV{N,Z} imm. from 47:32.
+pub const R_AARCH64_MOVW_PREL_G2: u32 = 291;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_PREL_G2_NC: u32 = 292;
+/// PC-rel. MOV{N,Z} imm. from 63:48.
+pub const R_AARCH64_MOVW_PREL_G3: u32 = 293;
+/// Dir. ADD imm. from bits 11:4
+pub const R_AARCH64_LDST128_ABS_LO12_NC: u32 = 299;
+/// GOT-rel. off. MOV{N,Z} imm. 15:0.
+pub const R_AARCH64_MOVW_GOTOFF_G0: u32 = 300;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_GOTOFF_G0_NC: u32 = 301;
+/// GOT-rel. o. MOV{N,Z} imm. 31:16
+pub const R_AARCH64_MOVW_GOTOFF_G1: u32 = 302;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_GOTOFF_G1_NC: u32 = 303;
+/// GOT-rel. o. MOV{N,Z} imm. 47:32
+pub const R_AARCH64_MOVW_GOTOFF_G2: u32 = 304;
+/// Likewise for MOVK; no check
+pub const R_AARCH64_MOVW_GOTOFF_G2_NC: u32 = 305;
+/// GOT-rel. o. MOV{N,Z} imm. 63:48
+pub const R_AARCH64_MOVW_GOTOFF_G3: u32 = 306;
+/// GOT-relative 64-bit
+pub const R_AARCH64_GOTREL64: u32 = 307;
+/// GOT-relative 32-bit
+pub const R_AARCH64_GOTREL32: u32 = 308;
+/// PC-rel. GOT off. load imm. 20:2
+pub const R_AARCH64_GOT_LD_PREL19: u32 = 309;
+/// GOT-rel. off. LD/ST imm. 14:3
+pub const R_AARCH64_LD64_GOTOFF_LO15: u32 = 310;
+/// P-page-rel. GOT off. ADRP 32:12
+pub const R_AARCH64_ADR_GOT_PAGE: u32 = 311;
+/// Dir. GOT off. LD/ST imm. 11:3
+pub const R_AARCH64_LD64_GOT_LO12_NC: u32 = 312;
+/// GOT-page-rel. GOT off. LD/ST 14:3
+pub const R_AARCH64_LD64_GOTPAGE_LO15: u32 = 313;
+/// PC-relative ADR imm. 20:0
+pub const R_AARCH64_TLSGD_ADR_PREL21: u32 = 512;
+/// page-rel. ADRP imm. 32:12
+pub const R_AARCH64_TLSGD_ADR_PAGE21: u32 = 513;
+/// direct ADD imm. from 11:0
+pub const R_AARCH64_TLSGD_ADD_LO12_NC: u32 = 514;
+/// GOT-rel. MOV{N,Z} 31:16
+pub const R_AARCH64_TLSGD_MOVW_G1: u32 = 515;
+/// GOT-rel. MOVK imm. 15:0
+pub const R_AARCH64_TLSGD_MOVW_G0_NC: u32 = 516;
+/// Like 512; local dynamic model
+pub const R_AARCH64_TLSLD_ADR_PREL21: u32 = 517;
+/// Like 513; local dynamic model
+pub const R_AARCH64_TLSLD_ADR_PAGE21: u32 = 518;
+/// Like 514; local dynamic model
+pub const R_AARCH64_TLSLD_ADD_LO12_NC: u32 = 519;
+/// Like 515; local dynamic model
+pub const R_AARCH64_TLSLD_MOVW_G1: u32 = 520;
+/// Like 516; local dynamic model
+pub const R_AARCH64_TLSLD_MOVW_G0_NC: u32 = 521;
+/// TLS PC-rel. load imm. 20:2
+pub const R_AARCH64_TLSLD_LD_PREL19: u32 = 522;
+/// TLS DTP-rel. MOV{N,Z} 47:32
+pub const R_AARCH64_TLSLD_MOVW_DTPREL_G2: u32 = 523;
+/// TLS DTP-rel. MOV{N,Z} 31:16
+pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1: u32 = 524;
+/// Likewise; MOVK; no check
+pub const R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: u32 = 525;
+/// TLS DTP-rel. MOV{N,Z} 15:0
+pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0: u32 = 526;
+/// Likewise; MOVK; no check
+pub const R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: u32 = 527;
+/// DTP-rel. ADD imm. from 23:12.
+pub const R_AARCH64_TLSLD_ADD_DTPREL_HI12: u32 = 528;
+/// DTP-rel. ADD imm. from 11:0
+pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12: u32 = 529;
+/// Likewise; no ovfl. check
+pub const R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: u32 = 530;
+/// DTP-rel. LD/ST imm. 11:0
+pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12: u32 = 531;
+/// Likewise; no check
+pub const R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: u32 = 532;
+/// DTP-rel. LD/ST imm. 11:1
+pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12: u32 = 533;
+/// Likewise; no check
+pub const R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: u32 = 534;
+/// DTP-rel. LD/ST imm. 11:2
+pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12: u32 = 535;
+/// Likewise; no check
+pub const R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: u32 = 536;
+/// DTP-rel. LD/ST imm. 11:3
+pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12: u32 = 537;
+/// Likewise; no check
+pub const R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: u32 = 538;
+/// GOT-rel. MOV{N,Z} 31:16
+pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1: u32 = 539;
+/// GOT-rel. MOVK 15:0
+pub const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: u32 = 540;
+/// Page-rel. ADRP 32:12
+pub const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: u32 = 541;
+/// Direct LD off. 11:3
+pub const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: u32 = 542;
+/// PC-rel. load imm. 20:2
+pub const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19: u32 = 543;
+/// TLS TP-rel. MOV{N,Z} 47:32
+pub const R_AARCH64_TLSLE_MOVW_TPREL_G2: u32 = 544;
+/// TLS TP-rel. MOV{N,Z} 31:16
+pub const R_AARCH64_TLSLE_MOVW_TPREL_G1: u32 = 545;
+/// Likewise; MOVK; no check
+pub const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: u32 = 546;
+/// TLS TP-rel. MOV{N,Z} 15:0
+pub const R_AARCH64_TLSLE_MOVW_TPREL_G0: u32 = 547;
+/// Likewise; MOVK; no check
+pub const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: u32 = 548;
+/// TP-rel. ADD imm. 23:12
+pub const R_AARCH64_TLSLE_ADD_TPREL_HI12: u32 = 549;
+/// TP-rel. ADD imm. 11:0
+pub const R_AARCH64_TLSLE_ADD_TPREL_LO12: u32 = 550;
+/// Likewise; no ovfl. check
+pub const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: u32 = 551;
+/// TP-rel. LD/ST off. 11:0
+pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12: u32 = 552;
+/// Likewise; no ovfl. check.
+pub const R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: u32 = 553;
+/// TP-rel. LD/ST off. 11:1
+pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12: u32 = 554;
+/// Likewise; no check
+pub const R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: u32 = 555;
+/// TP-rel. LD/ST off. 11:2
+pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12: u32 = 556;
+/// Likewise; no check
+pub const R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: u32 = 557;
+/// TP-rel. LD/ST off. 11:3
+pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12: u32 = 558;
+/// Likewise; no check
+pub const R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: u32 = 559;
+/// PC-rel. load immediate 20:2
+pub const R_AARCH64_TLSDESC_LD_PREL19: u32 = 560;
+/// PC-rel. ADR immediate 20:0
+pub const R_AARCH64_TLSDESC_ADR_PREL21: u32 = 561;
+/// Page-rel. ADRP imm. 32:12
+pub const R_AARCH64_TLSDESC_ADR_PAGE21: u32 = 562;
+/// Direct LD off. from 11:3
+pub const R_AARCH64_TLSDESC_LD64_LO12: u32 = 563;
+/// Direct ADD imm. from 11:0
+pub const R_AARCH64_TLSDESC_ADD_LO12: u32 = 564;
+/// GOT-rel. MOV{N,Z} imm. 31:16
+pub const R_AARCH64_TLSDESC_OFF_G1: u32 = 565;
+/// GOT-rel. MOVK imm. 15:0; no ck
+pub const R_AARCH64_TLSDESC_OFF_G0_NC: u32 = 566;
+/// Relax LDR
+pub const R_AARCH64_TLSDESC_LDR: u32 = 567;
+/// Relax ADD
+pub const R_AARCH64_TLSDESC_ADD: u32 = 568;
+/// Relax BLR
+pub const R_AARCH64_TLSDESC_CALL: u32 = 569;
+/// TP-rel. LD/ST off. 11:4
+pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12: u32 = 570;
+/// Likewise; no check
+pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: u32 = 571;
+/// DTP-rel. LD/ST imm. 11:4.
+pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12: u32 = 572;
+/// Likewise; no check
+pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: u32 = 573;
+/// Copy symbol at runtime
+pub const R_AARCH64_COPY: u32 = 1024;
+/// Create GOT entry
+pub const R_AARCH64_GLOB_DAT: u32 = 1025;
+/// Create PLT entry
+pub const R_AARCH64_JUMP_SLOT: u32 = 1026;
+/// Adjust by program base
+pub const R_AARCH64_RELATIVE: u32 = 1027;
+/// Module number, 64 bit
+pub const R_AARCH64_TLS_DTPMOD: u32 = 1028;
+/// Module-relative offset, 64 bit
+pub const R_AARCH64_TLS_DTPREL: u32 = 1029;
+/// TP-relative offset, 64 bit
+pub const R_AARCH64_TLS_TPREL: u32 = 1030;
+/// TLS Descriptor
+pub const R_AARCH64_TLSDESC: u32 = 1031;
+/// STT_GNU_IFUNC relocation
+pub const R_AARCH64_IRELATIVE: u32 = 1032;
+
+// ARM relocs
+/// No reloc
+pub const R_ARM_NONE: u32 = 0;
+/// Deprecated PC relative 26 bit branch
+pub const R_ARM_PC24: u32 = 1;
+/// Direct 32 bit
+pub const R_ARM_ABS32: u32 = 2;
+/// PC relative 32 bit
+pub const R_ARM_REL32: u32 = 3;
+pub const R_ARM_PC13: u32 = 4;
+/// Direct 16 bit
+pub const R_ARM_ABS16: u32 = 5;
+/// Direct 12 bit
+pub const R_ARM_ABS12: u32 = 6;
+/// Direct & 0x7C (LDR, STR)
+pub const R_ARM_THM_ABS5: u32 = 7;
+/// Direct 8 bit
+pub const R_ARM_ABS8: u32 = 8;
+pub const R_ARM_SBREL32: u32 = 9;
+/// PC relative 24 bit (Thumb32 BL)
+pub const R_ARM_THM_PC22: u32 = 10;
+/// PC relative & 0x3FC(Thumb16 LDR, ADD, ADR).
+pub const R_ARM_THM_PC8: u32 = 11;
+pub const R_ARM_AMP_VCALL9: u32 = 12;
+/// Obsolete static relocation
+pub const R_ARM_SWI24: u32 = 13;
+/// Dynamic relocation
+pub const R_ARM_TLS_DESC: u32 = 13;
+/// Reserved
+pub const R_ARM_THM_SWI8: u32 = 14;
+/// Reserved
+pub const R_ARM_XPC25: u32 = 15;
+/// Reserved
+pub const R_ARM_THM_XPC22: u32 = 16;
+/// ID of module containing symbol
+pub const R_ARM_TLS_DTPMOD32: u32 = 17;
+/// Offset in TLS block
+pub const R_ARM_TLS_DTPOFF32: u32 = 18;
+/// Offset in static TLS block
+pub const R_ARM_TLS_TPOFF32: u32 = 19;
+/// Copy symbol at runtime
+pub const R_ARM_COPY: u32 = 20;
+/// Create GOT entry
+pub const R_ARM_GLOB_DAT: u32 = 21;
+/// Create PLT entry
+pub const R_ARM_JUMP_SLOT: u32 = 22;
+/// Adjust by program base
+pub const R_ARM_RELATIVE: u32 = 23;
+/// 32 bit offset to GOT
+pub const R_ARM_GOTOFF: u32 = 24;
+/// 32 bit PC relative offset to GOT
+pub const R_ARM_GOTPC: u32 = 25;
+/// 32 bit GOT entry
+pub const R_ARM_GOT32: u32 = 26;
+/// Deprecated, 32 bit PLT address
+pub const R_ARM_PLT32: u32 = 27;
+/// PC relative 24 bit (BL, BLX)
+pub const R_ARM_CALL: u32 = 28;
+/// PC relative 24 bit (B, BL<cond>)
+pub const R_ARM_JUMP24: u32 = 29;
+/// PC relative 24 bit (Thumb32 B.W)
+pub const R_ARM_THM_JUMP24: u32 = 30;
+/// Adjust by program base
+pub const R_ARM_BASE_ABS: u32 = 31;
+/// Obsolete
+pub const R_ARM_ALU_PCREL_7_0: u32 = 32;
+/// Obsolete
+pub const R_ARM_ALU_PCREL_15_8: u32 = 33;
+/// Obsolete
+pub const R_ARM_ALU_PCREL_23_15: u32 = 34;
+/// Deprecated, prog. base relative
+pub const R_ARM_LDR_SBREL_11_0: u32 = 35;
+/// Deprecated, prog. base relative
+pub const R_ARM_ALU_SBREL_19_12: u32 = 36;
+/// Deprecated, prog. base relative
+pub const R_ARM_ALU_SBREL_27_20: u32 = 37;
+pub const R_ARM_TARGET1: u32 = 38;
+/// Program base relative
+pub const R_ARM_SBREL31: u32 = 39;
+pub const R_ARM_V4BX: u32 = 40;
+pub const R_ARM_TARGET2: u32 = 41;
+/// 32 bit PC relative
+pub const R_ARM_PREL31: u32 = 42;
+/// Direct 16-bit (MOVW)
+pub const R_ARM_MOVW_ABS_NC: u32 = 43;
+/// Direct high 16-bit (MOVT)
+pub const R_ARM_MOVT_ABS: u32 = 44;
+/// PC relative 16-bit (MOVW)
+pub const R_ARM_MOVW_PREL_NC: u32 = 45;
+/// PC relative (MOVT)
+pub const R_ARM_MOVT_PREL: u32 = 46;
+/// Direct 16 bit (Thumb32 MOVW)
+pub const R_ARM_THM_MOVW_ABS_NC: u32 = 47;
+/// Direct high 16 bit (Thumb32 MOVT)
+pub const R_ARM_THM_MOVT_ABS: u32 = 48;
+/// PC relative 16 bit (Thumb32 MOVW)
+pub const R_ARM_THM_MOVW_PREL_NC: u32 = 49;
+/// PC relative high 16 bit (Thumb32 MOVT)
+pub const R_ARM_THM_MOVT_PREL: u32 = 50;
+/// PC relative 20 bit (Thumb32 B<cond>.W)
+pub const R_ARM_THM_JUMP19: u32 = 51;
+/// PC relative X & 0x7E (Thumb16 CBZ, CBNZ)
+pub const R_ARM_THM_JUMP6: u32 = 52;
+/// PC relative 12 bit (Thumb32 ADR.W)
+pub const R_ARM_THM_ALU_PREL_11_0: u32 = 53;
+/// PC relative 12 bit (Thumb32 LDR{D,SB,H,SH})
+pub const R_ARM_THM_PC12: u32 = 54;
+/// Direct 32-bit
+pub const R_ARM_ABS32_NOI: u32 = 55;
+/// PC relative 32-bit
+pub const R_ARM_REL32_NOI: u32 = 56;
+/// PC relative (ADD, SUB)
+pub const R_ARM_ALU_PC_G0_NC: u32 = 57;
+/// PC relative (ADD, SUB)
+pub const R_ARM_ALU_PC_G0: u32 = 58;
+/// PC relative (ADD, SUB)
+pub const R_ARM_ALU_PC_G1_NC: u32 = 59;
+/// PC relative (ADD, SUB)
+pub const R_ARM_ALU_PC_G1: u32 = 60;
+/// PC relative (ADD, SUB)
+pub const R_ARM_ALU_PC_G2: u32 = 61;
+/// PC relative (LDR,STR,LDRB,STRB)
+pub const R_ARM_LDR_PC_G1: u32 = 62;
+/// PC relative (LDR,STR,LDRB,STRB)
+pub const R_ARM_LDR_PC_G2: u32 = 63;
+/// PC relative (STR{D,H},LDR{D,SB,H,SH})
+pub const R_ARM_LDRS_PC_G0: u32 = 64;
+/// PC relative (STR{D,H},LDR{D,SB,H,SH})
+pub const R_ARM_LDRS_PC_G1: u32 = 65;
+/// PC relative (STR{D,H},LDR{D,SB,H,SH})
+pub const R_ARM_LDRS_PC_G2: u32 = 66;
+/// PC relative (LDC, STC)
+pub const R_ARM_LDC_PC_G0: u32 = 67;
+/// PC relative (LDC, STC)
+pub const R_ARM_LDC_PC_G1: u32 = 68;
+/// PC relative (LDC, STC)
+pub const R_ARM_LDC_PC_G2: u32 = 69;
+/// Program base relative (ADD,SUB)
+pub const R_ARM_ALU_SB_G0_NC: u32 = 70;
+/// Program base relative (ADD,SUB)
+pub const R_ARM_ALU_SB_G0: u32 = 71;
+/// Program base relative (ADD,SUB)
+pub const R_ARM_ALU_SB_G1_NC: u32 = 72;
+/// Program base relative (ADD,SUB)
+pub const R_ARM_ALU_SB_G1: u32 = 73;
+/// Program base relative (ADD,SUB)
+pub const R_ARM_ALU_SB_G2: u32 = 74;
+/// Program base relative (LDR,STR, LDRB, STRB)
+pub const R_ARM_LDR_SB_G0: u32 = 75;
+/// Program base relative (LDR, STR, LDRB, STRB)
+pub const R_ARM_LDR_SB_G1: u32 = 76;
+/// Program base relative (LDR, STR, LDRB, STRB)
+pub const R_ARM_LDR_SB_G2: u32 = 77;
+/// Program base relative (LDR, STR, LDRB, STRB)
+pub const R_ARM_LDRS_SB_G0: u32 = 78;
+/// Program base relative (LDR, STR, LDRB, STRB)
+pub const R_ARM_LDRS_SB_G1: u32 = 79;
+/// Program base relative (LDR, STR, LDRB, STRB)
+pub const R_ARM_LDRS_SB_G2: u32 = 80;
+/// Program base relative (LDC,STC)
+pub const R_ARM_LDC_SB_G0: u32 = 81;
+/// Program base relative (LDC,STC)
+pub const R_ARM_LDC_SB_G1: u32 = 82;
+/// Program base relative (LDC,STC)
+pub const R_ARM_LDC_SB_G2: u32 = 83;
+/// Program base relative 16 bit (MOVW)
+pub const R_ARM_MOVW_BREL_NC: u32 = 84;
+/// Program base relative high 16 bit (MOVT)
+pub const R_ARM_MOVT_BREL: u32 = 85;
+/// Program base relative 16 bit (MOVW)
+pub const R_ARM_MOVW_BREL: u32 = 86;
+/// Program base relative 16 bit (Thumb32 MOVW)
+pub const R_ARM_THM_MOVW_BREL_NC: u32 = 87;
+/// Program base relative high 16 bit (Thumb32 MOVT)
+pub const R_ARM_THM_MOVT_BREL: u32 = 88;
+/// Program base relative 16 bit (Thumb32 MOVW)
+pub const R_ARM_THM_MOVW_BREL: u32 = 89;
+pub const R_ARM_TLS_GOTDESC: u32 = 90;
+pub const R_ARM_TLS_CALL: u32 = 91;
+/// TLS relaxation
+pub const R_ARM_TLS_DESCSEQ: u32 = 92;
+pub const R_ARM_THM_TLS_CALL: u32 = 93;
+pub const R_ARM_PLT32_ABS: u32 = 94;
+/// GOT entry
+pub const R_ARM_GOT_ABS: u32 = 95;
+/// PC relative GOT entry
+pub const R_ARM_GOT_PREL: u32 = 96;
+/// GOT entry relative to GOT origin (LDR)
+pub const R_ARM_GOT_BREL12: u32 = 97;
+/// 12 bit, GOT entry relative to GOT origin (LDR, STR)
+pub const R_ARM_GOTOFF12: u32 = 98;
+pub const R_ARM_GOTRELAX: u32 = 99;
+pub const R_ARM_GNU_VTENTRY: u32 = 100;
+pub const R_ARM_GNU_VTINHERIT: u32 = 101;
+/// PC relative & 0xFFE (Thumb16 B)
+pub const R_ARM_THM_PC11: u32 = 102;
+/// PC relative & 0x1FE (Thumb16 B/B<cond>)
+pub const R_ARM_THM_PC9: u32 = 103;
+/// PC-rel 32 bit for global dynamic thread local data
+pub const R_ARM_TLS_GD32: u32 = 104;
+/// PC-rel 32 bit for local dynamic thread local data
+pub const R_ARM_TLS_LDM32: u32 = 105;
+/// 32 bit offset relative to TLS block
+pub const R_ARM_TLS_LDO32: u32 = 106;
+/// PC-rel 32 bit for GOT entry of static TLS block offset
+pub const R_ARM_TLS_IE32: u32 = 107;
+/// 32 bit offset relative to static TLS block
+pub const R_ARM_TLS_LE32: u32 = 108;
+/// 12 bit relative to TLS block (LDR, STR)
+pub const R_ARM_TLS_LDO12: u32 = 109;
+/// 12 bit relative to static TLS block (LDR, STR)
+pub const R_ARM_TLS_LE12: u32 = 110;
+/// 12 bit GOT entry relative to GOT origin (LDR)
+pub const R_ARM_TLS_IE12GP: u32 = 111;
+/// Obsolete
+pub const R_ARM_ME_TOO: u32 = 128;
+pub const R_ARM_THM_TLS_DESCSEQ: u32 = 129;
+pub const R_ARM_THM_TLS_DESCSEQ16: u32 = 129;
+pub const R_ARM_THM_TLS_DESCSEQ32: u32 = 130;
+/// GOT entry relative to GOT origin, 12 bit (Thumb32 LDR)
+pub const R_ARM_THM_GOT_BREL12: u32 = 131;
+pub const R_ARM_IRELATIVE: u32 = 160;
+pub const R_ARM_RXPC25: u32 = 249;
+pub const R_ARM_RSBREL32: u32 = 250;
+pub const R_ARM_THM_RPC22: u32 = 251;
+pub const R_ARM_RREL32: u32 = 252;
+pub const R_ARM_RABS22: u32 = 253;
+pub const R_ARM_RPC24: u32 = 254;
+pub const R_ARM_RBASE: u32 = 255;
+/// Keep this the last entry
+pub const R_ARM_NUM: u32 = 256;
+
+///////////////////
+// OpenRisc
+///////////////////
+pub const R_OR1K_NONE: u32 = 0;
+pub const R_OR1K_32: u32 = 1;
+pub const R_OR1K_16: u32 = 2;
+pub const R_OR1K_8: u32 = 3;
+pub const R_OR1K_LO_16_IN_INSN: u32 = 4;
+pub const R_OR1K_HI_16_IN_INSN: u32 = 5;
+pub const R_OR1K_INSN_REL_26: u32 = 6;
+pub const R_OR1K_GNU_VTENTRY: u32 = 7;
+pub const R_OR1K_GNU_VTINHERIT: u32 = 8;
+pub const R_OR1K_32_PCREL: u32 = 9;
+pub const R_OR1K_16_PCREL: u32 = 10;
+pub const R_OR1K_8_PCREL: u32 = 11;
+pub const R_OR1K_GOTPC_HI16: u32 = 12;
+pub const R_OR1K_GOTPC_LO16: u32 = 13;
+pub const R_OR1K_GOT16: u32 = 14;
+pub const R_OR1K_PLT26: u32 = 15;
+pub const R_OR1K_GOTOFF_HI16: u32 = 16;
+pub const R_OR1K_GOTOFF_LO16: u32 = 17;
+pub const R_OR1K_COPY: u32 = 18;
+pub const R_OR1K_GLOB_DAT: u32 = 19;
+pub const R_OR1K_JMP_SLOT: u32 = 20;
+pub const R_OR1K_RELATIVE: u32 = 21;
+pub const R_OR1K_TLS_GD_HI16: u32 = 22;
+pub const R_OR1K_TLS_GD_LO16: u32 = 23;
+pub const R_OR1K_TLS_LDM_HI16: u32 = 24;
+pub const R_OR1K_TLS_LDM_LO16: u32 = 25;
+pub const R_OR1K_TLS_LDO_HI16: u32 = 26;
+pub const R_OR1K_TLS_LDO_LO16: u32 = 27;
+pub const R_OR1K_TLS_IE_HI16: u32 = 28;
+pub const R_OR1K_TLS_IE_LO16: u32 = 29;
+pub const R_OR1K_TLS_LE_HI16: u32 = 30;
+pub const R_OR1K_TLS_LE_LO16: u32 = 31;
+pub const R_OR1K_TLS_TPOFF: u32 = 32;
+pub const R_OR1K_TLS_DTPOFF: u32 = 33;
+pub const R_OR1K_TLS_DTPMOD: u32 = 34;
+pub const R_OR1K_NUM: u32 = 35;
+
+/////////////////////
+// MIPS
+/////////////////////
+/// No reloc
+pub const R_MIPS_NONE: u32 = 0;
+/// Direct 16 bit
+pub const R_MIPS_16: u32 = 1;
+/// Direct 32 bit
+pub const R_MIPS_32: u32 = 2;
+/// PC relative 32 bit
+pub const R_MIPS_REL32: u32 = 3;
+/// Direct 26 bit shifted
+pub const R_MIPS_26: u32 = 4;
+/// High 16 bit
+pub const R_MIPS_HI16: u32 = 5;
+/// Low 16 bit
+pub const R_MIPS_LO16: u32 = 6;
+/// GP relative 16 bit
+pub const R_MIPS_GPREL16: u32 = 7;
+/// 16 bit literal entry
+pub const R_MIPS_LITERAL: u32 = 8;
+/// 16 bit GOT entry
+pub const R_MIPS_GOT16: u32 = 9;
+/// PC relative 16 bit
+pub const R_MIPS_PC16: u32 = 10;
+/// 16 bit GOT entry for function
+pub const R_MIPS_CALL16: u32 = 11;
+/// GP relative 32 bit
+pub const R_MIPS_GPREL32: u32 = 12;
+pub const R_MIPS_SHIFT5: u32 = 16;
+pub const R_MIPS_SHIFT6: u32 = 17;
+pub const R_MIPS_64: u32 = 18;
+pub const R_MIPS_GOT_DISP: u32 = 19;
+pub const R_MIPS_GOT_PAGE: u32 = 20;
+pub const R_MIPS_GOT_OFST: u32 = 21;
+pub const R_MIPS_GOT_HI16: u32 = 22;
+pub const R_MIPS_GOT_LO16: u32 = 23;
+pub const R_MIPS_SUB: u32 = 24;
+pub const R_MIPS_INSERT_A: u32 = 25;
+pub const R_MIPS_INSERT_B: u32 = 26;
+pub const R_MIPS_DELETE: u32 = 27;
+pub const R_MIPS_HIGHER: u32 = 28;
+pub const R_MIPS_HIGHEST: u32 = 29;
+pub const R_MIPS_CALL_HI16: u32 = 30;
+pub const R_MIPS_CALL_LO16: u32 = 31;
+pub const R_MIPS_SCN_DISP: u32 = 32;
+pub const R_MIPS_REL16: u32 = 33;
+pub const R_MIPS_ADD_IMMEDIATE: u32 = 34;
+pub const R_MIPS_PJUMP: u32 = 35;
+pub const R_MIPS_RELGOT: u32 = 36;
+pub const R_MIPS_JALR: u32 = 37;
+/// Module number 32 bit
+pub const R_MIPS_TLS_DTPMOD32: u32 = 38;
+/// Module-relative offset 32 bit
+pub const R_MIPS_TLS_DTPREL32: u32 = 39;
+/// Module number 64 bit
+pub const R_MIPS_TLS_DTPMOD64: u32 = 40;
+/// Module-relative offset 64 bit
+pub const R_MIPS_TLS_DTPREL64: u32 = 41;
+/// 16 bit GOT offset for GD
+pub const R_MIPS_TLS_GD: u32 = 42;
+/// 16 bit GOT offset for LDM
+pub const R_MIPS_TLS_LDM: u32 = 43;
+/// Module-relative offset, high 16 bits
+pub const R_MIPS_TLS_DTPREL_HI16: u32 = 44;
+/// Module-relative offset, low 16 bits
+pub const R_MIPS_TLS_DTPREL_LO16: u32 = 45;
+/// 16 bit GOT offset for IE
+pub const R_MIPS_TLS_GOTTPREL: u32 = 46;
+/// TP-relative offset, 32 bit6
+pub const R_MIPS_TLS_TPREL32: u32 = 47;
+/// TP-relative offset, 64 bit
+pub const R_MIPS_TLS_TPREL64: u32 = 48;
+/// TP-relative offset, high 16 bits
+pub const R_MIPS_TLS_TPREL_HI16: u32 = 49;
+/// TP-relative offset, low 16 bits
+pub const R_MIPS_TLS_TPREL_LO16: u32 = 50;
+pub const R_MIPS_GLOB_DAT: u32 = 51;
+pub const R_MIPS_COPY: u32 = 126;
+pub const R_MIPS_JUMP_SLOT: u32 = 127;
+pub const R_MIPS_NUM: u32 = 128;
+
+#[inline]
+pub fn r_to_str(typ: u32, machine: u16) -> &'static str {
+    use elf::header::*;
+    match machine {
+        // x86
+        EM_386 => { match typ {
+        R_386_NONE => "386_NONE",
+        R_386_32 => "386_32",
+        R_386_PC32 => "386_PC32",
+        R_386_GOT32 => "386_GOT32",
+        R_386_PLT32 => "386_PLT32",
+        R_386_COPY => "386_COPY",
+        R_386_GLOB_DAT => "386_GLOB_DAT",
+        R_386_JMP_SLOT => "386_JMP_SLOT",
+        R_386_RELATIVE => "386_RELATIVE",
+        R_386_GOTOFF => "386_GOTOFF",
+        R_386_GOTPC => "386_GOTPC",
+        R_386_32PLT => "386_32PLT",
+        R_386_TLS_TPOFF => "386_TLS_TPOFF",
+        R_386_TLS_IE => "386_TLS_IE",
+        R_386_TLS_GOTIE => "386_TLS_GOTIE",
+        R_386_TLS_LE => "386_TLS_LE",
+        R_386_TLS_GD => "386_TLS_GD",
+        R_386_TLS_LDM => "386_TLS_LDM",
+        R_386_16 => "386_16",
+        R_386_PC16 => "386_PC16",
+        R_386_8 => "386_8",
+        R_386_PC8 => "386_PC8",
+        R_386_TLS_GD_32 => "386_TLS_GD_32",
+        R_386_TLS_GD_PUSH => "386_TLS_GD_PUSH",
+        R_386_TLS_GD_CALL => "386_TLS_GD_CALL",
+        R_386_TLS_GD_POP => "386_TLS_GD_POP",
+        R_386_TLS_LDM_32 => "386_TLS_LDM_32",
+        R_386_TLS_LDM_PUSH => "386_TLS_LDM_PUSH",
+        R_386_TLS_LDM_CALL => "386_TLS_LDM_CALL",
+        R_386_TLS_LDM_POP => "386_TLS_LDM_POP",
+        R_386_TLS_LDO_32 => "386_TLS_LDO_32",
+        R_386_TLS_IE_32 => "386_TLS_IE_32",
+        R_386_TLS_LE_32 => "386_TLS_LE_32",
+        R_386_TLS_DTPMOD32 => "386_TLS_DTPMOD32",
+        R_386_TLS_DTPOFF32 => "386_TLS_DTPOFF32",
+        R_386_TLS_TPOFF32 => "386_TLS_TPOFF32",
+        R_386_SIZE32 => "386_SIZE32",
+        R_386_TLS_GOTDESC => "386_TLS_GOTDESC",
+        R_386_TLS_DESC_CALL => "386_TLS_DESC_CALL",
+        R_386_TLS_DESC => "386_TLS_DESC",
+        R_386_IRELATIVE => "386_IRELATIVE",
+        R_386_GOT32X => "386_GOT32X",
+        _ => "R_UNKNOWN_386",
+        }},
+        EM_X86_64 => { match typ {
+        R_X86_64_64 => "X86_64_64",
+        R_X86_64_PC32 => "X86_64_PC32",
+        R_X86_64_GOT32 => "X86_64_GOT32",
+        R_X86_64_PLT32 => "X86_64_PLT32",
+        R_X86_64_COPY => "X86_64_COPY",
+        R_X86_64_GLOB_DAT => "X86_64_GLOB_DAT",
+        R_X86_64_JUMP_SLOT => "X86_64_JUMP_SLOT",
+        R_X86_64_RELATIVE => "X86_64_RELATIVE",
+        R_X86_64_GOTPCREL => "X86_64_GOTPCREL",
+        R_X86_64_32 => "X86_64_32",
+        R_X86_64_32S => "X86_64_32S",
+        R_X86_64_16 => "X86_64_16",
+        R_X86_64_PC16 => "X86_64_PC16",
+        R_X86_64_8 => "X86_64_8",
+        R_X86_64_PC8 => "X86_64_PC8",
+        R_X86_64_DTPMOD64 => "X86_64_DTPMOD64",
+        R_X86_64_DTPOFF64 => "X86_64_DTPOFF64",
+        R_X86_64_TPOFF64 => "X86_64_TPOFF64",
+        R_X86_64_TLSGD => "X86_64_TLSGD",
+        R_X86_64_TLSLD => "X86_64_TLSLD",
+        R_X86_64_DTPOFF32 => "X86_64_DTPOFF32",
+        R_X86_64_GOTTPOFF => "X86_64_GOTTPOFF",
+        R_X86_64_TPOFF32 => "X86_64_TPOFF32",
+        R_X86_64_PC64 => "X86_64_PC64",
+        R_X86_64_GOTOFF64 => "X86_64_GOTOFF64",
+        R_X86_64_GOTPC32 => "X86_64_GOTPC32",
+        R_X86_64_GOT64 => "X86_64_GOT64",
+        R_X86_64_GOTPCREL64 => "X86_64_GOTPCREL64",
+        R_X86_64_GOTPC64 => "X86_64_GOTPC64",
+        R_X86_64_GOTPLT64 => "X86_64_GOTPLT64",
+        R_X86_64_PLTOFF64 => "X86_64_PLTOFF64",
+        R_X86_64_SIZE32 => "X86_64_SIZE32",
+        R_X86_64_SIZE64 => "X86_64_SIZE64",
+        R_X86_64_GOTPC32_TLSDESC => "X86_64_GOTPC32_TLSDESC",
+        R_X86_64_TLSDESC_CALL => "X86_64_TLSDESC_CALL",
+        R_X86_64_TLSDESC => "X86_64_TLSDESC",
+        R_X86_64_IRELATIVE => "X86_64_IRELATIVE",
+        R_X86_64_RELATIVE64 => "X86_64_RELATIVE64",
+        R_X86_64_GOTPCRELX => "R_X86_64_GOTPCRELX",
+        R_X86_64_REX_GOTPCRELX => "R_X86_64_REX_GOTPCRELX",
+        _ => "R_UNKNOWN_X86_64",
+        }},
+        // openrisc
+        EM_OPENRISC => { match typ {
+        R_OR1K_NONE => "OR1K_NONE",
+        R_OR1K_32 => "OR1K_32",
+        R_OR1K_16 => "OR1K_16",
+        R_OR1K_8 => "OR1K_8",
+        R_OR1K_LO_16_IN_INSN => "OR1K_LO_16_IN_INSN",
+        R_OR1K_HI_16_IN_INSN => "OR1K_HI_16_IN_INSN",
+        R_OR1K_INSN_REL_26 => "OR1K_INSN_REL_26",
+        R_OR1K_GNU_VTENTRY => "OR1K_GNU_VTENTRY",
+        R_OR1K_GNU_VTINHERIT => "OR1K_GNU_VTINHERIT",
+        R_OR1K_32_PCREL => "OR1K_32_PCREL",
+        R_OR1K_16_PCREL => "OR1K_16_PCREL",
+        R_OR1K_8_PCREL => "OR1K_8_PCREL",
+        R_OR1K_GOTPC_HI16 => "OR1K_GOTPC_HI16",
+        R_OR1K_GOTPC_LO16 => "OR1K_GOTPC_LO16",
+        R_OR1K_GOT16 => "OR1K_GOT16",
+        R_OR1K_PLT26 => "OR1K_PLT26",
+        R_OR1K_GOTOFF_HI16 => "OR1K_GOTOFF_HI16",
+        R_OR1K_GOTOFF_LO16 => "OR1K_GOTOFF_LO16",
+        R_OR1K_COPY => "OR1K_COPY",
+        R_OR1K_GLOB_DAT => "OR1K_GLOB_DAT",
+        R_OR1K_JMP_SLOT => "OR1K_JMP_SLOT",
+        R_OR1K_RELATIVE => "OR1K_RELATIVE",
+        R_OR1K_TLS_GD_HI16 => "OR1K_TLS_GD_HI16",
+        R_OR1K_TLS_GD_LO16 => "OR1K_TLS_GD_LO16",
+        R_OR1K_TLS_LDM_HI16 => "OR1K_TLS_LDM_HI16",
+        R_OR1K_TLS_LDM_LO16 => "OR1K_TLS_LDM_LO16",
+        R_OR1K_TLS_LDO_HI16 => "OR1K_TLS_LDO_HI16",
+        R_OR1K_TLS_LDO_LO16 => "OR1K_TLS_LDO_LO16",
+        R_OR1K_TLS_IE_HI16 => "OR1K_TLS_IE_HI16",
+        R_OR1K_TLS_IE_LO16 => "OR1K_TLS_IE_LO16",
+        R_OR1K_TLS_LE_HI16 => "OR1K_TLS_LE_HI16",
+        R_OR1K_TLS_LE_LO16 => "OR1K_TLS_LE_LO16",
+        R_OR1K_TLS_TPOFF => "OR1K_TLS_TPOFF",
+        R_OR1K_TLS_DTPOFF => "OR1K_TLS_DTPOFF",
+        R_OR1K_TLS_DTPMOD => "OR1K_TLS_DTPMOD",
+        _ => "R_UNKNOWN_OR1K",
+        }},
+        // arm64
+        EM_AARCH64 => { match typ {
+        R_AARCH64_P32_ABS32 => "AARCH64_P32_ABS32",
+        R_AARCH64_P32_COPY => "AARCH64_P32_COPY",
+        R_AARCH64_P32_GLOB_DAT => "AARCH64_P32_GLOB_DAT",
+        R_AARCH64_P32_JUMP_SLOT => "AARCH64_P32_JUMP_SLOT",
+        R_AARCH64_P32_RELATIVE => "AARCH64_P32_RELATIVE",
+        R_AARCH64_P32_TLS_DTPMOD => "AARCH64_P32_TLS_DTPMOD",
+        R_AARCH64_P32_TLS_DTPREL => "AARCH64_P32_TLS_DTPREL",
+        R_AARCH64_P32_TLS_TPREL => "AARCH64_P32_TLS_TPREL",
+        R_AARCH64_P32_TLSDESC => "AARCH64_P32_TLSDESC",
+        R_AARCH64_P32_IRELATIVE => "AARCH64_P32_IRELATIVE",
+        R_AARCH64_ABS64 => "AARCH64_ABS64",
+        R_AARCH64_ABS32 => "AARCH64_ABS32",
+        R_AARCH64_ABS16 => "AARCH64_ABS16",
+        R_AARCH64_PREL64 => "AARCH64_PREL64",
+        R_AARCH64_PREL32 => "AARCH64_PREL32",
+        R_AARCH64_PREL16 => "AARCH64_PREL16",
+        R_AARCH64_MOVW_UABS_G0 => "AARCH64_MOVW_UABS_G0",
+        R_AARCH64_MOVW_UABS_G0_NC => "AARCH64_MOVW_UABS_G0_NC",
+        R_AARCH64_MOVW_UABS_G1 => "AARCH64_MOVW_UABS_G1",
+        R_AARCH64_MOVW_UABS_G1_NC => "AARCH64_MOVW_UABS_G1_NC",
+        R_AARCH64_MOVW_UABS_G2 => "AARCH64_MOVW_UABS_G2",
+        R_AARCH64_MOVW_UABS_G2_NC => "AARCH64_MOVW_UABS_G2_NC",
+        R_AARCH64_MOVW_UABS_G3 => "AARCH64_MOVW_UABS_G3",
+        R_AARCH64_MOVW_SABS_G0 => "AARCH64_MOVW_SABS_G0",
+        R_AARCH64_MOVW_SABS_G1 => "AARCH64_MOVW_SABS_G1",
+        R_AARCH64_MOVW_SABS_G2 => "AARCH64_MOVW_SABS_G2",
+        R_AARCH64_LD_PREL_LO19 => "AARCH64_LD_PREL_LO19",
+        R_AARCH64_ADR_PREL_LO21 => "AARCH64_ADR_PREL_LO21",
+        R_AARCH64_ADR_PREL_PG_HI21 => "AARCH64_ADR_PREL_PG_HI21",
+        R_AARCH64_ADR_PREL_PG_HI21_NC => "AARCH64_ADR_PREL_PG_HI21_NC",
+        R_AARCH64_ADD_ABS_LO12_NC => "AARCH64_ADD_ABS_LO12_NC",
+        R_AARCH64_LDST8_ABS_LO12_NC => "AARCH64_LDST8_ABS_LO12_NC",
+        R_AARCH64_TSTBR14 => "AARCH64_TSTBR14",
+        R_AARCH64_CONDBR19 => "AARCH64_CONDBR19",
+        R_AARCH64_JUMP26 => "AARCH64_JUMP26",
+        R_AARCH64_CALL26 => "AARCH64_CALL26",
+        R_AARCH64_LDST16_ABS_LO12_NC => "AARCH64_LDST16_ABS_LO12_NC",
+        R_AARCH64_LDST32_ABS_LO12_NC => "AARCH64_LDST32_ABS_LO12_NC",
+        R_AARCH64_LDST64_ABS_LO12_NC => "AARCH64_LDST64_ABS_LO12_NC",
+        R_AARCH64_MOVW_PREL_G0 => "AARCH64_MOVW_PREL_G0",
+        R_AARCH64_MOVW_PREL_G0_NC => "AARCH64_MOVW_PREL_G0_NC",
+        R_AARCH64_MOVW_PREL_G1 => "AARCH64_MOVW_PREL_G1",
+        R_AARCH64_MOVW_PREL_G1_NC => "AARCH64_MOVW_PREL_G1_NC",
+        R_AARCH64_MOVW_PREL_G2 => "AARCH64_MOVW_PREL_G2",
+        R_AARCH64_MOVW_PREL_G2_NC => "AARCH64_MOVW_PREL_G2_NC",
+        R_AARCH64_MOVW_PREL_G3 => "AARCH64_MOVW_PREL_G3",
+        R_AARCH64_LDST128_ABS_LO12_NC => "AARCH64_LDST128_ABS_LO12_NC",
+        R_AARCH64_MOVW_GOTOFF_G0 => "AARCH64_MOVW_GOTOFF_G0",
+        R_AARCH64_MOVW_GOTOFF_G0_NC => "AARCH64_MOVW_GOTOFF_G0_NC",
+        R_AARCH64_MOVW_GOTOFF_G1 => "AARCH64_MOVW_GOTOFF_G1",
+        R_AARCH64_MOVW_GOTOFF_G1_NC => "AARCH64_MOVW_GOTOFF_G1_NC",
+        R_AARCH64_MOVW_GOTOFF_G2 => "AARCH64_MOVW_GOTOFF_G2",
+        R_AARCH64_MOVW_GOTOFF_G2_NC => "AARCH64_MOVW_GOTOFF_G2_NC",
+        R_AARCH64_MOVW_GOTOFF_G3 => "AARCH64_MOVW_GOTOFF_G3",
+        R_AARCH64_GOTREL64 => "AARCH64_GOTREL64",
+        R_AARCH64_GOTREL32 => "AARCH64_GOTREL32",
+        R_AARCH64_GOT_LD_PREL19 => "AARCH64_GOT_LD_PREL19",
+        R_AARCH64_LD64_GOTOFF_LO15 => "AARCH64_LD64_GOTOFF_LO15",
+        R_AARCH64_ADR_GOT_PAGE => "AARCH64_ADR_GOT_PAGE",
+        R_AARCH64_LD64_GOT_LO12_NC => "AARCH64_LD64_GOT_LO12_NC",
+        R_AARCH64_LD64_GOTPAGE_LO15 => "AARCH64_LD64_GOTPAGE_LO15",
+        R_AARCH64_TLSGD_ADR_PREL21 => "AARCH64_TLSGD_ADR_PREL21",
+        R_AARCH64_TLSGD_ADR_PAGE21 => "AARCH64_TLSGD_ADR_PAGE21",
+        R_AARCH64_TLSGD_ADD_LO12_NC => "AARCH64_TLSGD_ADD_LO12_NC",
+        R_AARCH64_TLSGD_MOVW_G1 => "AARCH64_TLSGD_MOVW_G1",
+        R_AARCH64_TLSGD_MOVW_G0_NC => "AARCH64_TLSGD_MOVW_G0_NC",
+        R_AARCH64_TLSLD_ADR_PREL21 => "AARCH64_TLSLD_ADR_PREL21",
+        R_AARCH64_TLSLD_ADR_PAGE21 => "AARCH64_TLSLD_ADR_PAGE21",
+        R_AARCH64_TLSLD_ADD_LO12_NC => "AARCH64_TLSLD_ADD_LO12_NC",
+        R_AARCH64_TLSLD_MOVW_G1 => "AARCH64_TLSLD_MOVW_G1",
+        R_AARCH64_TLSLD_MOVW_G0_NC => "AARCH64_TLSLD_MOVW_G0_NC",
+        R_AARCH64_TLSLD_LD_PREL19 => "AARCH64_TLSLD_LD_PREL19",
+        R_AARCH64_TLSLD_MOVW_DTPREL_G2 => "AARCH64_TLSLD_MOVW_DTPREL_G2",
+        R_AARCH64_TLSLD_MOVW_DTPREL_G1 => "AARCH64_TLSLD_MOVW_DTPREL_G1",
+        R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC => "AARCH64_TLSLD_MOVW_DTPREL_G1_NC",
+        R_AARCH64_TLSLD_MOVW_DTPREL_G0 => "AARCH64_TLSLD_MOVW_DTPREL_G0",
+        R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC => "AARCH64_TLSLD_MOVW_DTPREL_G0_NC",
+        R_AARCH64_TLSLD_ADD_DTPREL_HI12 => "AARCH64_TLSLD_ADD_DTPREL_HI12",
+        R_AARCH64_TLSLD_ADD_DTPREL_LO12 => "AARCH64_TLSLD_ADD_DTPREL_LO12",
+        R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC => "AARCH64_TLSLD_ADD_DTPREL_LO12_NC",
+        R_AARCH64_TLSLD_LDST8_DTPREL_LO12 => "AARCH64_TLSLD_LDST8_DTPREL_LO12",
+        R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC => "AARCH64_TLSLD_LDST8_DTPREL_LO12_NC",
+        R_AARCH64_TLSLD_LDST16_DTPREL_LO12 => "AARCH64_TLSLD_LDST16_DTPREL_LO12",
+        R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC => "AARCH64_TLSLD_LDST16_DTPREL_LO12_NC",
+        R_AARCH64_TLSLD_LDST32_DTPREL_LO12 => "AARCH64_TLSLD_LDST32_DTPREL_LO12",
+        R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC => "AARCH64_TLSLD_LDST32_DTPREL_LO12_NC",
+        R_AARCH64_TLSLD_LDST64_DTPREL_LO12 => "AARCH64_TLSLD_LDST64_DTPREL_LO12",
+        R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC => "AARCH64_TLSLD_LDST64_DTPREL_LO12_NC",
+        R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 => "AARCH64_TLSIE_MOVW_GOTTPREL_G1",
+        R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC => "AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC",
+        R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 => "AARCH64_TLSIE_ADR_GOTTPREL_PAGE21",
+        R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC => "AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC",
+        R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 => "AARCH64_TLSIE_LD_GOTTPREL_PREL19",
+        R_AARCH64_TLSLE_MOVW_TPREL_G2 => "AARCH64_TLSLE_MOVW_TPREL_G2",
+        R_AARCH64_TLSLE_MOVW_TPREL_G1 => "AARCH64_TLSLE_MOVW_TPREL_G1",
+        R_AARCH64_TLSLE_MOVW_TPREL_G1_NC => "AARCH64_TLSLE_MOVW_TPREL_G1_NC",
+        R_AARCH64_TLSLE_MOVW_TPREL_G0 => "AARCH64_TLSLE_MOVW_TPREL_G0",
+        R_AARCH64_TLSLE_MOVW_TPREL_G0_NC => "AARCH64_TLSLE_MOVW_TPREL_G0_NC",
+        R_AARCH64_TLSLE_ADD_TPREL_HI12 => "AARCH64_TLSLE_ADD_TPREL_HI12",
+        R_AARCH64_TLSLE_ADD_TPREL_LO12 => "AARCH64_TLSLE_ADD_TPREL_LO12",
+        R_AARCH64_TLSLE_ADD_TPREL_LO12_NC => "AARCH64_TLSLE_ADD_TPREL_LO12_NC",
+        R_AARCH64_TLSLE_LDST8_TPREL_LO12 => "AARCH64_TLSLE_LDST8_TPREL_LO12",
+        R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC => "AARCH64_TLSLE_LDST8_TPREL_LO12_NC",
+        R_AARCH64_TLSLE_LDST16_TPREL_LO12 => "AARCH64_TLSLE_LDST16_TPREL_LO12",
+        R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC => "AARCH64_TLSLE_LDST16_TPREL_LO12_NC",
+        R_AARCH64_TLSLE_LDST32_TPREL_LO12 => "AARCH64_TLSLE_LDST32_TPREL_LO12",
+        R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC => "AARCH64_TLSLE_LDST32_TPREL_LO12_NC",
+        R_AARCH64_TLSLE_LDST64_TPREL_LO12 => "AARCH64_TLSLE_LDST64_TPREL_LO12",
+        R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC => "AARCH64_TLSLE_LDST64_TPREL_LO12_NC",
+        R_AARCH64_TLSDESC_LD_PREL19 => "AARCH64_TLSDESC_LD_PREL19",
+        R_AARCH64_TLSDESC_ADR_PREL21 => "AARCH64_TLSDESC_ADR_PREL21",
+        R_AARCH64_TLSDESC_ADR_PAGE21 => "AARCH64_TLSDESC_ADR_PAGE21",
+        R_AARCH64_TLSDESC_LD64_LO12 => "AARCH64_TLSDESC_LD64_LO12",
+        R_AARCH64_TLSDESC_ADD_LO12 => "AARCH64_TLSDESC_ADD_LO12",
+        R_AARCH64_TLSDESC_OFF_G1 => "AARCH64_TLSDESC_OFF_G1",
+        R_AARCH64_TLSDESC_OFF_G0_NC => "AARCH64_TLSDESC_OFF_G0_NC",
+        R_AARCH64_TLSDESC_LDR => "AARCH64_TLSDESC_LDR",
+        R_AARCH64_TLSDESC_ADD => "AARCH64_TLSDESC_ADD",
+        R_AARCH64_TLSDESC_CALL => "AARCH64_TLSDESC_CALL",
+        R_AARCH64_TLSLE_LDST128_TPREL_LO12 => "AARCH64_TLSLE_LDST128_TPREL_LO12",
+        R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC => "AARCH64_TLSLE_LDST128_TPREL_LO12_NC",
+        R_AARCH64_TLSLD_LDST128_DTPREL_LO12 => "AARCH64_TLSLD_LDST128_DTPREL_LO12",
+        R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC => "AARCH64_TLSLD_LDST128_DTPREL_LO12_NC",
+        R_AARCH64_COPY => "AARCH64_COPY",
+        R_AARCH64_GLOB_DAT => "AARCH64_GLOB_DAT",
+        R_AARCH64_JUMP_SLOT => "AARCH64_JUMP_SLOT",
+        R_AARCH64_RELATIVE => "AARCH64_RELATIVE",
+        R_AARCH64_TLS_DTPMOD => "AARCH64_TLS_DTPMOD",
+        R_AARCH64_TLS_DTPREL => "AARCH64_TLS_DTPREL",
+        R_AARCH64_TLS_TPREL => "AARCH64_TLS_TPREL",
+        R_AARCH64_TLSDESC => "AARCH64_TLSDESC",
+        R_AARCH64_IRELATIVE => "AARCH64_IRELATIVE",
+         _ => "R_UNKNOWN_AARCH64",
+        }},
+        // arm
+        EM_ARM => { match typ {
+        R_ARM_PC24 => "ARM_PC24",
+        R_ARM_ABS32 => "ARM_ABS32",
+        R_ARM_REL32 => "ARM_REL32",
+        R_ARM_PC13 => "ARM_PC13",
+        R_ARM_ABS16 => "ARM_ABS16",
+        R_ARM_ABS12 => "ARM_ABS12",
+        R_ARM_THM_ABS5 => "ARM_THM_ABS5",
+        R_ARM_ABS8 => "ARM_ABS8",
+        R_ARM_SBREL32 => "ARM_SBREL32",
+        R_ARM_THM_PC22 => "ARM_THM_PC22",
+        R_ARM_THM_PC8 => "ARM_THM_PC8",
+        R_ARM_AMP_VCALL9 => "ARM_AMP_VCALL9",
+        R_ARM_TLS_DESC => "ARM_TLS_DESC",
+        R_ARM_THM_SWI8 => "ARM_THM_SWI8",
+        R_ARM_XPC25 => "ARM_XPC25",
+        R_ARM_THM_XPC22 => "ARM_THM_XPC22",
+        R_ARM_TLS_DTPMOD32 => "ARM_TLS_DTPMOD32",
+        R_ARM_TLS_DTPOFF32 => "ARM_TLS_DTPOFF32",
+        R_ARM_TLS_TPOFF32 => "ARM_TLS_TPOFF32",
+        R_ARM_COPY => "ARM_COPY",
+        R_ARM_GLOB_DAT => "ARM_GLOB_DAT",
+        R_ARM_JUMP_SLOT => "ARM_JUMP_SLOT",
+        R_ARM_RELATIVE => "ARM_RELATIVE",
+        R_ARM_GOTOFF => "ARM_GOTOFF",
+        R_ARM_GOTPC => "ARM_GOTPC",
+        R_ARM_GOT32 => "ARM_GOT32",
+        R_ARM_PLT32 => "ARM_PLT32",
+        R_ARM_CALL => "ARM_CALL",
+        R_ARM_JUMP24 => "ARM_JUMP24",
+        R_ARM_THM_JUMP24 => "ARM_THM_JUMP24",
+        R_ARM_BASE_ABS => "ARM_BASE_ABS",
+        R_ARM_ALU_PCREL_7_0 => "ARM_ALU_PCREL_7_0",
+        R_ARM_ALU_PCREL_15_8 => "ARM_ALU_PCREL_15_8",
+        R_ARM_ALU_PCREL_23_15 => "ARM_ALU_PCREL_23_15",
+        R_ARM_LDR_SBREL_11_0 => "ARM_LDR_SBREL_11_0",
+        R_ARM_ALU_SBREL_19_12 => "ARM_ALU_SBREL_19_12",
+        R_ARM_ALU_SBREL_27_20 => "ARM_ALU_SBREL_27_20",
+        R_ARM_TARGET1 => "ARM_TARGET1",
+        R_ARM_SBREL31 => "ARM_SBREL31",
+        R_ARM_V4BX => "ARM_V4BX",
+        R_ARM_TARGET2 => "ARM_TARGET2",
+        R_ARM_PREL31 => "ARM_PREL31",
+        R_ARM_MOVW_ABS_NC => "ARM_MOVW_ABS_NC",
+        R_ARM_MOVT_ABS => "ARM_MOVT_ABS",
+        R_ARM_MOVW_PREL_NC => "ARM_MOVW_PREL_NC",
+        R_ARM_MOVT_PREL => "ARM_MOVT_PREL",
+        R_ARM_THM_MOVW_ABS_NC => "ARM_THM_MOVW_ABS_NC",
+        R_ARM_THM_MOVT_ABS => "ARM_THM_MOVT_ABS",
+        R_ARM_THM_MOVW_PREL_NC => "ARM_THM_MOVW_PREL_NC",
+        R_ARM_THM_MOVT_PREL => "ARM_THM_MOVT_PREL",
+        R_ARM_THM_JUMP19 => "ARM_THM_JUMP19",
+        R_ARM_THM_JUMP6 => "ARM_THM_JUMP6",
+        R_ARM_THM_ALU_PREL_11_0 => "ARM_THM_ALU_PREL_11_0",
+        R_ARM_THM_PC12 => "ARM_THM_PC12",
+        R_ARM_ABS32_NOI => "ARM_ABS32_NOI",
+        R_ARM_REL32_NOI => "ARM_REL32_NOI",
+        R_ARM_ALU_PC_G0_NC => "ARM_ALU_PC_G0_NC",
+        R_ARM_ALU_PC_G0 => "ARM_ALU_PC_G0",
+        R_ARM_ALU_PC_G1_NC => "ARM_ALU_PC_G1_NC",
+        R_ARM_ALU_PC_G1 => "ARM_ALU_PC_G1",
+        R_ARM_ALU_PC_G2 => "ARM_ALU_PC_G2",
+        R_ARM_LDR_PC_G1 => "ARM_LDR_PC_G1",
+        R_ARM_LDR_PC_G2 => "ARM_LDR_PC_G2",
+        R_ARM_LDRS_PC_G0 => "ARM_LDRS_PC_G0",
+        R_ARM_LDRS_PC_G1 => "ARM_LDRS_PC_G1",
+        R_ARM_LDRS_PC_G2 => "ARM_LDRS_PC_G2",
+        R_ARM_LDC_PC_G0 => "ARM_LDC_PC_G0",
+        R_ARM_LDC_PC_G1 => "ARM_LDC_PC_G1",
+        R_ARM_LDC_PC_G2 => "ARM_LDC_PC_G2",
+        R_ARM_ALU_SB_G0_NC => "ARM_ALU_SB_G0_NC",
+        R_ARM_ALU_SB_G0 => "ARM_ALU_SB_G0",
+        R_ARM_ALU_SB_G1_NC => "ARM_ALU_SB_G1_NC",
+        R_ARM_ALU_SB_G1 => "ARM_ALU_SB_G1",
+        R_ARM_ALU_SB_G2 => "ARM_ALU_SB_G2",
+        R_ARM_LDR_SB_G0 => "ARM_LDR_SB_G0",
+        R_ARM_LDR_SB_G1 => "ARM_LDR_SB_G1",
+        R_ARM_LDR_SB_G2 => "ARM_LDR_SB_G2",
+        R_ARM_LDRS_SB_G0 => "ARM_LDRS_SB_G0",
+        R_ARM_LDRS_SB_G1 => "ARM_LDRS_SB_G1",
+        R_ARM_LDRS_SB_G2 => "ARM_LDRS_SB_G2",
+        R_ARM_LDC_SB_G0 => "ARM_LDC_SB_G0",
+        R_ARM_LDC_SB_G1 => "ARM_LDC_SB_G1",
+        R_ARM_LDC_SB_G2 => "ARM_LDC_SB_G2",
+        R_ARM_MOVW_BREL_NC => "ARM_MOVW_BREL_NC",
+        R_ARM_MOVT_BREL => "ARM_MOVT_BREL",
+        R_ARM_MOVW_BREL => "ARM_MOVW_BREL",
+        R_ARM_THM_MOVW_BREL_NC => "ARM_THM_MOVW_BREL_NC",
+        R_ARM_THM_MOVT_BREL => "ARM_THM_MOVT_BREL",
+        R_ARM_THM_MOVW_BREL => "ARM_THM_MOVW_BREL",
+        R_ARM_TLS_GOTDESC => "ARM_TLS_GOTDESC",
+        R_ARM_TLS_CALL => "ARM_TLS_CALL",
+        R_ARM_TLS_DESCSEQ => "ARM_TLS_DESCSEQ",
+        R_ARM_THM_TLS_CALL => "ARM_THM_TLS_CALL",
+        R_ARM_PLT32_ABS => "ARM_PLT32_ABS",
+        R_ARM_GOT_ABS => "ARM_GOT_ABS",
+        R_ARM_GOT_PREL => "ARM_GOT_PREL",
+        R_ARM_GOT_BREL12 => "ARM_GOT_BREL12",
+        R_ARM_GOTOFF12 => "ARM_GOTOFF12",
+        R_ARM_GOTRELAX => "ARM_GOTRELAX",
+        R_ARM_GNU_VTENTRY => "ARM_GNU_VTENTRY",
+        R_ARM_GNU_VTINHERIT => "ARM_GNU_VTINHERIT",
+        R_ARM_THM_PC11 => "ARM_THM_PC11",
+        R_ARM_THM_PC9 => "ARM_THM_PC9",
+        R_ARM_TLS_GD32 => "ARM_TLS_GD32",
+        R_ARM_TLS_LDM32 => "ARM_TLS_LDM32",
+        R_ARM_TLS_LDO32 => "ARM_TLS_LDO32",
+        R_ARM_TLS_IE32 => "ARM_TLS_IE32",
+        R_ARM_TLS_LE32 => "ARM_TLS_LE32",
+        R_ARM_TLS_LDO12 => "ARM_TLS_LDO12",
+        R_ARM_TLS_LE12 => "ARM_TLS_LE12",
+        R_ARM_TLS_IE12GP => "ARM_TLS_IE12GP",
+        R_ARM_ME_TOO => "ARM_ME_TOO",
+        R_ARM_THM_TLS_DESCSEQ16 => "ARM_THM_TLS_DESCSEQ16",
+        R_ARM_THM_TLS_DESCSEQ32 => "ARM_THM_TLS_DESCSEQ32",
+        R_ARM_THM_GOT_BREL12 => "ARM_THM_GOT_BREL12",
+        R_ARM_IRELATIVE => "ARM_IRELATIVE",
+        R_ARM_RXPC25 => "ARM_RXPC25",
+        R_ARM_RSBREL32 => "ARM_RSBREL32",
+        R_ARM_THM_RPC22 => "ARM_THM_RPC22",
+        R_ARM_RREL32 => "ARM_RREL32",
+        R_ARM_RABS22 => "ARM_RABS22",
+        R_ARM_RPC24 => "ARM_RPC24",
+        R_ARM_RBASE => "ARM_RBASE",
+         _ => "R_UNKNOWN_ARM",
+        }},
+        // MIPS
+        EM_MIPS | EM_MIPS_RS3_LE | EM_MIPS_X => { match typ {
+        R_MIPS_NONE => "R_MIPS_NONE",
+        R_MIPS_16 => "R_MIPS_16",
+        R_MIPS_32 => "R_MIPS_32",
+        R_MIPS_REL32 => "R_MIPS_REL32",
+        R_MIPS_26 => "R_MIPS_26",
+        R_MIPS_HI16 => "R_MIPS_HI16",
+        R_MIPS_LO16 => "R_MIPS_LO16",
+        R_MIPS_GPREL16 => "R_MIPS_GPREL16",
+        R_MIPS_LITERAL => "R_MIPS_LITERAL",
+        R_MIPS_GOT16 => "R_MIPS_GOT16",
+        R_MIPS_PC16 => "R_MIPS_PC16",
+        R_MIPS_CALL16 => "R_MIPS_CALL16",
+        R_MIPS_GPREL32 => "R_MIPS_GPREL32",
+        R_MIPS_SHIFT5 => "R_MIPS_SHIFT5",
+        R_MIPS_SHIFT6 => "R_MIPS_SHIFT6",
+        R_MIPS_64 => "R_MIPS_64",
+        R_MIPS_GOT_DISP => "R_MIPS_GOT_DISP",
+        R_MIPS_GOT_PAGE => "R_MIPS_GOT_PAGE",
+        R_MIPS_GOT_OFST => "R_MIPS_GOT_OFST",
+        R_MIPS_GOT_HI16 => "R_MIPS_GOT_HI16",
+        R_MIPS_GOT_LO16 => "R_MIPS_GOT_LO16",
+        R_MIPS_SUB => "R_MIPS_SUB",
+        R_MIPS_INSERT_A => "R_MIPS_INSERT_A",
+        R_MIPS_INSERT_B => "R_MIPS_INSERT_B",
+        R_MIPS_DELETE => "R_MIPS_DELETE",
+        R_MIPS_HIGHER => "R_MIPS_HIGHER",
+        R_MIPS_HIGHEST => "R_MIPS_HIGHEST",
+        R_MIPS_CALL_HI16 => "R_MIPS_CALL_HI16",
+        R_MIPS_CALL_LO16 => "R_MIPS_CALL_LO16",
+        R_MIPS_SCN_DISP => "R_MIPS_SCN_DISP",
+        R_MIPS_REL16 => "R_MIPS_REL16",
+        R_MIPS_ADD_IMMEDIATE => "R_MIPS_ADD_IMMEDIATE",
+        R_MIPS_PJUMP => "R_MIPS_PJUMP",
+        R_MIPS_RELGOT => "R_MIPS_RELGOT",
+        R_MIPS_JALR => "R_MIPS_JALR",
+        R_MIPS_TLS_DTPMOD32 => "R_MIPS_TLS_DTPMOD32",
+        R_MIPS_TLS_DTPREL32 => "R_MIPS_TLS_DTPREL32",
+        R_MIPS_TLS_DTPMOD64 => "R_MIPS_TLS_DTPMOD64",
+        R_MIPS_TLS_DTPREL64 => "R_MIPS_TLS_DTPREL64",
+        R_MIPS_TLS_GD => "R_MIPS_TLS_GD",
+        R_MIPS_TLS_LDM => "R_MIPS_TLS_LDM",
+        R_MIPS_TLS_DTPREL_HI16 => "R_MIPS_TLS_DTPREL_HI16",
+        R_MIPS_TLS_DTPREL_LO16 => "R_MIPS_TLS_DTPREL_LO16",
+        R_MIPS_TLS_GOTTPREL => "R_MIPS_TLS_GOTTPREL",
+        R_MIPS_TLS_TPREL32 => "R_MIPS_TLS_TPREL32",
+        R_MIPS_TLS_TPREL64 => "R_MIPS_TLS_TPREL64",
+        R_MIPS_TLS_TPREL_HI16 => "R_MIPS_TLS_TPREL_HI16",
+        R_MIPS_TLS_TPREL_LO16 => "R_MIPS_TLS_TPREL_LO16",
+        R_MIPS_GLOB_DAT => "R_MIPS_GLOB_DAT",
+        R_MIPS_COPY => "R_MIPS_COPY",
+        R_MIPS_JUMP_SLOT => "R_MIPS_JUMP_SLOT",
+        _ => "R_UNKNOWN_MIPS",
+        }} _ => "R_UNKNOWN"
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/dyn.rs
@@ -0,0 +1,659 @@
+
+macro_rules! elf_dyn {
+    ($size:ty) => {
+        #[repr(C)]
+        #[derive(Copy, Clone, PartialEq, Default)]
+        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+        /// An entry in the dynamic array
+        pub struct Dyn {
+            /// Dynamic entry type
+            pub d_tag: $size,
+            /// Integer value
+            pub d_val: $size,
+        }
+
+        use plain;
+        unsafe impl plain::Plain for Dyn {}
+    }
+}
+
+// TODO: figure out what's the best, most friendly + safe API choice here - u32s or u64s
+// remember that DT_TAG is "pointer sized"/used as address sometimes Original rationale: I
+// decided to use u64 instead of u32 due to pattern matching use case seems safer to cast the
+// elf32's d_tag from u32 -> u64 at runtime instead of casting the elf64's d_tag from u64 ->
+// u32 at runtime
+
+/// Marks end of dynamic section
+pub const DT_NULL: u64 = 0;
+/// Name of needed library
+pub const DT_NEEDED: u64 = 1;
+/// Size in bytes of PLT relocs
+pub const DT_PLTRELSZ: u64 = 2;
+/// Processor defined value
+pub const DT_PLTGOT: u64 = 3;
+/// Address of symbol hash table
+pub const DT_HASH: u64 = 4;
+/// Address of string table
+pub const DT_STRTAB: u64 = 5;
+/// Address of symbol table
+pub const DT_SYMTAB: u64 = 6;
+/// Address of Rela relocs
+pub const DT_RELA: u64 = 7;
+/// Total size of Rela relocs
+pub const DT_RELASZ: u64 = 8;
+/// Size of one Rela reloc
+pub const DT_RELAENT: u64 = 9;
+/// Size of string table
+pub const DT_STRSZ: u64 = 10;
+/// Size of one symbol table entry
+pub const DT_SYMENT: u64 = 11;
+/// Address of init function
+pub const DT_INIT: u64 = 12;
+/// Address of termination function
+pub const DT_FINI: u64 = 13;
+/// Name of shared object
+pub const DT_SONAME: u64 = 14;
+/// Library search path (deprecated)
+pub const DT_RPATH: u64 = 15;
+/// Start symbol search here
+pub const DT_SYMBOLIC: u64 = 16;
+/// Address of Rel relocs
+pub const DT_REL: u64 = 17;
+/// Total size of Rel relocs
+pub const DT_RELSZ: u64 = 18;
+/// Size of one Rel reloc
+pub const DT_RELENT: u64 = 19;
+/// Type of reloc in PLT
+pub const DT_PLTREL: u64 = 20;
+/// For debugging; unspecified
+pub const DT_DEBUG: u64 = 21;
+/// Reloc might modify .text
+pub const DT_TEXTREL: u64 = 22;
+/// Address of PLT relocs
+pub const DT_JMPREL: u64 = 23;
+/// Process relocations of object
+pub const DT_BIND_NOW: u64 = 24;
+/// Array with addresses of init fct
+pub const DT_INIT_ARRAY: u64 = 25;
+/// Array with addresses of fini fct
+pub const DT_FINI_ARRAY: u64 = 26;
+/// Size in bytes of DT_INIT_ARRAY
+pub const DT_INIT_ARRAYSZ: u64 = 27;
+/// Size in bytes of DT_FINI_ARRAY
+pub const DT_FINI_ARRAYSZ: u64 = 28;
+/// Library search path
+pub const DT_RUNPATH: u64 = 29;
+/// Flags for the object being loaded
+pub const DT_FLAGS: u64 = 30;
+/// Start of encoded range
+pub const DT_ENCODING: u64 = 32;
+/// Array with addresses of preinit fct
+pub const DT_PREINIT_ARRAY: u64 = 32;
+/// size in bytes of DT_PREINIT_ARRAY
+pub const DT_PREINIT_ARRAYSZ: u64 = 33;
+/// Number used
+pub const DT_NUM: u64 = 34;
+/// Start of OS-specific
+pub const DT_LOOS: u64 = 0x6000000d;
+/// End of OS-specific
+pub const DT_HIOS: u64 = 0x6ffff000;
+/// Start of processor-specific
+pub const DT_LOPROC: u64 = 0x70000000;
+/// End of processor-specific
+pub const DT_HIPROC: u64 = 0x7fffffff;
+// Most used by any processor
+// pub const DT_PROCNUM: u64 = DT_MIPS_NUM;
+
+/// DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+/// Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+///
+/// If any adjustment is made to the ELF object after it has been
+/// built these entries will need to be adjusted.
+pub const DT_ADDRRNGLO: u64 = 0x6ffffe00;
+/// GNU-style hash table
+pub const DT_GNU_HASH: u64 = 0x6ffffef5;
+///
+pub const DT_TLSDESC_PLT: u64 = 0x6ffffef6;
+///
+pub const DT_TLSDESC_GOT: u64 = 0x6ffffef7;
+/// Start of conflict section
+pub const DT_GNU_CONFLICT: u64 = 0x6ffffef8;
+/// Library list
+pub const DT_GNU_LIBLIST: u64 = 0x6ffffef9;
+/// Configuration information
+pub const DT_CONFIG: u64 = 0x6ffffefa;
+/// Dependency auditing
+pub const DT_DEPAUDIT: u64 = 0x6ffffefb;
+/// Object auditing
+pub const DT_AUDIT: u64 = 0x6ffffefc;
+/// PLT padding
+pub const DT_PLTPAD: u64 = 0x6ffffefd;
+/// Move table
+pub const DT_MOVETAB: u64 = 0x6ffffefe;
+/// Syminfo table
+pub const DT_SYMINFO: u64 = 0x6ffffeff;
+///
+pub const DT_ADDRRNGHI: u64 = 0x6ffffeff;
+
+//DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+pub const DT_ADDRNUM: u64 = 11;
+
+/// The versioning entry types. The next are defined as part of the GNU extension
+pub const DT_VERSYM: u64 = 0x6ffffff0;
+pub const DT_RELACOUNT: u64 = 0x6ffffff9;
+pub const DT_RELCOUNT: u64 = 0x6ffffffa;
+/// State flags, see DF_1_* below
+pub const DT_FLAGS_1: u64 = 0x6ffffffb;
+/// Address of version definition table
+pub const DT_VERDEF: u64 = 0x6ffffffc;
+/// Number of version definitions
+pub const DT_VERDEFNUM: u64 = 0x6ffffffd;
+/// Address of table with needed versions
+pub const DT_VERNEED: u64 = 0x6ffffffe;
+/// Number of needed versions
+pub const DT_VERNEEDNUM: u64 = 0x6fffffff;
+
+/// Converts a tag to its string representation.
+#[inline]
+pub fn tag_to_str(tag: u64) -> &'static str {
+    match tag {
+        DT_NULL => "DT_NULL",
+        DT_NEEDED => "DT_NEEDED",
+        DT_PLTRELSZ => "DT_PLTRELSZ",
+        DT_PLTGOT => "DT_PLTGOT",
+        DT_HASH => "DT_HASH",
+        DT_STRTAB => "DT_STRTAB",
+        DT_SYMTAB => "DT_SYMTAB",
+        DT_RELA => "DT_RELA",
+        DT_RELASZ => "DT_RELASZ",
+        DT_RELAENT => "DT_RELAENT",
+        DT_STRSZ => "DT_STRSZ",
+        DT_SYMENT => "DT_SYMENT",
+        DT_INIT => "DT_INIT",
+        DT_FINI => "DT_FINI",
+        DT_SONAME => "DT_SONAME",
+        DT_RPATH => "DT_RPATH",
+        DT_SYMBOLIC => "DT_SYMBOLIC",
+        DT_REL => "DT_REL",
+        DT_RELSZ => "DT_RELSZ",
+        DT_RELENT => "DT_RELENT",
+        DT_PLTREL => "DT_PLTREL",
+        DT_DEBUG => "DT_DEBUG",
+        DT_TEXTREL => "DT_TEXTREL",
+        DT_JMPREL => "DT_JMPREL",
+        DT_BIND_NOW => "DT_BIND_NOW",
+        DT_INIT_ARRAY => "DT_INIT_ARRAY",
+        DT_FINI_ARRAY => "DT_FINI_ARRAY",
+        DT_INIT_ARRAYSZ => "DT_INIT_ARRAYSZ",
+        DT_FINI_ARRAYSZ => "DT_FINI_ARRAYSZ",
+        DT_RUNPATH => "DT_RUNPATH",
+        DT_FLAGS => "DT_FLAGS",
+        DT_PREINIT_ARRAY => "DT_PREINIT_ARRAY",
+        DT_PREINIT_ARRAYSZ => "DT_PREINIT_ARRAYSZ",
+        DT_NUM => "DT_NUM",
+        DT_LOOS => "DT_LOOS",
+        DT_HIOS => "DT_HIOS",
+        DT_LOPROC => "DT_LOPROC",
+        DT_HIPROC => "DT_HIPROC",
+        DT_VERSYM => "DT_VERSYM",
+        DT_RELACOUNT => "DT_RELACOUNT",
+        DT_RELCOUNT => "DT_RELCOUNT",
+        DT_GNU_HASH => "DT_GNU_HASH",
+        DT_VERDEF => "DT_VERDEF",
+        DT_VERDEFNUM => "DT_VERDEFNUM",
+        DT_VERNEED => "DT_VERNEED",
+        DT_VERNEEDNUM => "DT_VERNEEDNUM",
+        DT_FLAGS_1 => "DT_FLAGS_1",
+        _ => "UNKNOWN_TAG",
+    }
+}
+
+// Values of `d_un.d_val` in the DT_FLAGS entry
+/// Object may use DF_ORIGIN.
+pub const DF_ORIGIN: u64 = 0x00000001;
+/// Symbol resolutions starts here.
+pub const DF_SYMBOLIC: u64 = 0x00000002;
+/// Object contains text relocations.
+pub const DF_TEXTREL: u64 = 0x00000004;
+/// No lazy binding for this object.
+pub const DF_BIND_NOW: u64 = 0x00000008;
+/// Module uses the static TLS model.
+pub const DF_STATIC_TLS: u64 = 0x00000010;
+
+/// === State flags ===
+/// selectable in the `d_un.d_val` element of the DT_FLAGS_1 entry in the dynamic section.
+///
+/// Set RTLD_NOW for this object.
+pub const DF_1_NOW: u64 = 0x00000001;
+/// Set RTLD_GLOBAL for this object.
+pub const DF_1_GLOBAL: u64 = 0x00000002;
+/// Set RTLD_GROUP for this object.
+pub const DF_1_GROUP: u64 = 0x00000004;
+/// Set RTLD_NODELETE for this object.
+pub const DF_1_NODELETE: u64 = 0x00000008;
+/// Trigger filtee loading at runtime.
+pub const DF_1_LOADFLTR: u64 = 0x00000010;
+/// Set RTLD_INITFIRST for this object.
+pub const DF_1_INITFIRST: u64 = 0x00000020;
+/// Set RTLD_NOOPEN for this object.
+pub const DF_1_NOOPEN: u64 = 0x00000040;
+/// $ORIGIN must be handled.
+pub const DF_1_ORIGIN: u64 = 0x00000080;
+/// Direct binding enabled.
+pub const DF_1_DIRECT: u64 = 0x00000100;
+pub const DF_1_TRANS: u64 = 0x00000200;
+/// Object is used to interpose.
+pub const DF_1_INTERPOSE: u64 = 0x00000400;
+/// Ignore default lib search path.
+pub const DF_1_NODEFLIB: u64 = 0x00000800;
+/// Object can't be dldump'ed.
+pub const DF_1_NODUMP: u64 = 0x00001000;
+/// Configuration alternative created.
+pub const DF_1_CONFALT: u64 = 0x00002000;
+/// Filtee terminates filters search.
+pub const DF_1_ENDFILTEE: u64 = 0x00004000;
+/// Disp reloc applied at build time.
+pub const DF_1_DISPRELDNE: u64 = 0x00008000;
+/// Disp reloc applied at run-time.
+pub const DF_1_DISPRELPND: u64 = 0x00010000;
+/// Object has no-direct binding.
+pub const DF_1_NODIRECT: u64 = 0x00020000;
+pub const DF_1_IGNMULDEF: u64 = 0x00040000;
+pub const DF_1_NOKSYMS: u64 = 0x00080000;
+pub const DF_1_NOHDR: u64 = 0x00100000;
+/// Object is modified after built.
+pub const DF_1_EDITED: u64 = 0x00200000;
+pub const DF_1_NORELOC: u64 = 0x00400000;
+/// Object has individual interposers.
+pub const DF_1_SYMINTPOSE: u64 = 0x00800000;
+/// Global auditing required.
+pub const DF_1_GLOBAUDIT: u64 = 0x01000000;
+/// Singleton dyn are used.
+pub const DF_1_SINGLETON: u64 = 0x02000000;
+
+if_alloc! {
+    use core::fmt;
+    use scroll::ctx;
+    use core::result;
+    use container::{Ctx, Container};
+    use strtab::Strtab;
+    use self::dyn32::{DynamicInfo};
+    use alloc::vec::Vec;
+
+    #[derive(Default, PartialEq, Clone)]
+    pub struct Dyn {
+        pub d_tag: u64,
+        pub d_val: u64,
+    }
+
+    impl Dyn {
+        #[inline]
+        pub fn size(container: Container) -> usize {
+            use scroll::ctx::SizeWith;
+            Self::size_with(&Ctx::from(container))
+        }
+    }
+
+    impl fmt::Debug for Dyn {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f,
+                   "d_tag: {} d_val: 0x{:x}",
+                   tag_to_str(self.d_tag as u64),
+                   self.d_val)
+        }
+    }
+
+    impl ctx::SizeWith<Ctx> for Dyn {
+        type Units = usize;
+        fn size_with(&Ctx { container, .. }: &Ctx) -> usize {
+            match container {
+                Container::Little => {
+                    dyn32::SIZEOF_DYN
+                },
+                Container::Big => {
+                    dyn64::SIZEOF_DYN
+                },
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, Ctx> for Dyn {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], Ctx { container, le}: Ctx) -> result::Result<(Self, Self::Size), Self::Error> {
+            use scroll::Pread;
+            let dyn = match container {
+                Container::Little => {
+                    (bytes.pread_with::<dyn32::Dyn>(0, le)?.into(), dyn32::SIZEOF_DYN)
+                },
+                Container::Big => {
+                    (bytes.pread_with::<dyn64::Dyn>(0, le)?.into(), dyn64::SIZEOF_DYN)
+                }
+            };
+            Ok(dyn)
+        }
+    }
+
+    impl ctx::TryIntoCtx<Ctx> for Dyn {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_into_ctx(self, bytes: &mut [u8], Ctx { container, le}: Ctx) -> result::Result<Self::Size, Self::Error> {
+            use scroll::Pwrite;
+            match container {
+                Container::Little => {
+                    let dyn: dyn32::Dyn = self.into();
+                    Ok(bytes.pwrite_with(dyn, 0, le)?)
+                },
+                Container::Big => {
+                    let dyn: dyn64::Dyn = self.into();
+                    Ok(bytes.pwrite_with(dyn, 0, le)?)
+                }
+            }
+        }
+    }
+
+    #[derive(Debug)]
+    pub struct Dynamic {
+        pub dyns: Vec<Dyn>,
+        pub info: DynamicInfo,
+        count: usize,
+    }
+
+    impl Dynamic {
+        #[cfg(feature = "endian_fd")]
+        /// Returns a vector of dynamic entries from the underlying byte `bytes`, with `endianness`, using the provided `phdrs`
+        pub fn parse(bytes: &[u8], phdrs: &[::elf::program_header::ProgramHeader], bias: usize, ctx: Ctx) -> ::error::Result<Option<Self>> {
+            use scroll::ctx::SizeWith;
+            use scroll::Pread;
+            use elf::program_header;
+            for phdr in phdrs {
+                if phdr.p_type == program_header::PT_DYNAMIC {
+                    let filesz = phdr.p_filesz as usize;
+                    let size = Dyn::size_with(&ctx);
+                    let count = filesz / size;
+                    let mut dyns = Vec::with_capacity(count);
+                    let mut offset = phdr.p_offset as usize;
+                    for _ in 0..count {
+                        let dyn = bytes.gread_with::<Dyn>(&mut offset, ctx)?;
+                        let tag = dyn.d_tag;
+                        dyns.push(dyn);
+                        if tag == DT_NULL { break }
+                    }
+                    let mut info = DynamicInfo::default();
+                    for dyn in &dyns {
+                        let dyn: dyn32::Dyn = dyn.clone().into();
+                        info.update(bias, &dyn);
+                    }
+                    let count = dyns.len();
+                    return Ok(Some(Dynamic { dyns: dyns, info: info, count: count }));
+                }
+            }
+            Ok(None)
+        }
+
+        pub fn get_libraries<'a>(&self, strtab: &Strtab<'a>) -> Vec<&'a str> {
+            let count = self.info.needed_count;
+            let mut needed = Vec::with_capacity(count);
+            for dyn in &self.dyns {
+                if dyn.d_tag as u64 == DT_NEEDED {
+                    match strtab.get(dyn.d_val as usize) {
+                        Some(Ok(lib)) => needed.push(lib),
+                        // FIXME: warn! here
+                        _ => (),
+                    }
+                }
+            }
+            needed
+        }
+    }
+}
+
+macro_rules! elf_dyn_std_impl {
+    ($size:ident, $phdr:ty) => {
+
+        #[cfg(test)]
+        mod test {
+            use super::*;
+            #[test]
+            fn size_of() {
+                assert_eq!(::std::mem::size_of::<Dyn>(), SIZEOF_DYN);
+            }
+        }
+
+        if_alloc! {
+            use core::fmt;
+            use core::slice;
+            use alloc::vec::Vec;
+
+            use elf::program_header::{PT_DYNAMIC};
+            use strtab::Strtab;
+
+            use elf::dyn::Dyn as ElfDyn;
+
+            if_std! {
+                use std::fs::File;
+                use std::io::{Read, Seek};
+                use std::io::SeekFrom::Start;
+                use error::Result;
+            }
+
+            impl From<ElfDyn> for Dyn {
+                fn from(dyn: ElfDyn) -> Self {
+                    Dyn {
+                        d_tag: dyn.d_tag as $size,
+                        d_val: dyn.d_val as $size,
+                    }
+                }
+            }
+            impl From<Dyn> for ElfDyn {
+                fn from(dyn: Dyn) -> Self {
+                    ElfDyn {
+                        d_tag: dyn.d_tag as u64,
+                        d_val: dyn.d_val as u64,
+                    }
+                }
+            }
+
+            impl fmt::Debug for Dyn {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    write!(f,
+                           "d_tag: {} d_val: 0x{:x}",
+                           tag_to_str(self.d_tag as u64),
+                           self.d_val)
+                }
+            }
+
+            impl fmt::Debug for DynamicInfo {
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    let gnu_hash = if let Some(addr) = self.gnu_hash { addr } else { 0 };
+                    let hash = if let Some(addr) = self.hash { addr } else { 0 };
+                    let pltgot = if let Some(addr) = self.pltgot { addr } else { 0 };
+                    write!(f, "rela: 0x{:x} relasz: {} relaent: {} relacount: {} gnu_hash: 0x{:x} hash: 0x{:x} strtab: 0x{:x} strsz: {} symtab: 0x{:x} syment: {} pltgot: 0x{:x} pltrelsz: {} pltrel: {} jmprel: 0x{:x} verneed: 0x{:x} verneednum: {} versym: 0x{:x} init: 0x{:x} fini: 0x{:x} needed_count: {}",
+                           self.rela,
+                           self.relasz,
+                           self.relaent,
+                           self.relacount,
+                           gnu_hash,
+                           hash,
+                           self.strtab,
+                           self.strsz,
+                           self.symtab,
+                           self.syment,
+                           pltgot,
+                           self.pltrelsz,
+                           self.pltrel,
+                           self.jmprel,
+                           self.verneed,
+                           self.verneednum,
+                           self.versym,
+                           self.init,
+                           self.fini,
+                           self.needed_count,
+                    )
+                }
+            }
+
+            /// Returns a vector of dynamic entries from the given fd and program headers
+            #[cfg(feature = "std")]
+            pub fn from_fd(mut fd: &File, phdrs: &[$phdr]) -> Result<Option<Vec<Dyn>>> {
+                for phdr in phdrs {
+                    if phdr.p_type == PT_DYNAMIC {
+                        let filesz = phdr.p_filesz as usize;
+                        let dync = filesz / SIZEOF_DYN;
+                        let mut dyns = vec![Dyn::default(); dync];
+                        try!(fd.seek(Start(phdr.p_offset as u64)));
+                        unsafe {
+                            try!(fd.read(plain::as_mut_bytes(&mut *dyns)));
+                        }
+                        dyns.dedup();
+                        return Ok(Some(dyns));
+                    }
+                }
+                Ok(None)
+            }
+
+            /// Given a bias and a memory address (typically for a _correctly_ mmap'd binary in memory), returns the `_DYNAMIC` array as a slice of that memory
+            pub unsafe fn from_raw<'a>(bias: usize, vaddr: usize) -> &'a [Dyn] {
+                let dynp = vaddr.wrapping_add(bias) as *const Dyn;
+                let mut idx = 0;
+                while (*dynp.offset(idx)).d_tag as u64 != DT_NULL {
+                    idx += 1;
+                }
+                slice::from_raw_parts(dynp, idx as usize)
+            }
+
+            // TODO: these bare functions have always seemed awkward, but not sure where they should go...
+            /// Maybe gets and returns the dynamic array with the same lifetime as the [phdrs], using the provided bias with wrapping addition.
+            /// If the bias is wrong, it will either segfault or give you incorrect values, beware
+            pub unsafe fn from_phdrs(bias: usize, phdrs: &[$phdr]) -> Option<&[Dyn]> {
+                for phdr in phdrs {
+                    // FIXME: change to casting to u64 similar to DT_*?
+                    if phdr.p_type as u32 == PT_DYNAMIC {
+                        return Some(from_raw(bias, phdr.p_vaddr as usize));
+                    }
+                }
+                None
+            }
+
+            /// Gets the needed libraries from the `_DYNAMIC` array, with the str slices lifetime tied to the dynamic array/strtab's lifetime(s)
+            pub unsafe fn get_needed<'a>(dyns: &[Dyn], strtab: *const Strtab<'a>, count: usize) -> Vec<&'a str> {
+                let mut needed = Vec::with_capacity(count);
+                for dyn in dyns {
+                    if dyn.d_tag as u64 == DT_NEEDED {
+                        let lib = &(*strtab)[dyn.d_val as usize];
+                        needed.push(lib);
+                    }
+                }
+                needed
+            }
+        }
+
+        /// Important dynamic linking info generated via a single pass through the `_DYNAMIC` array
+        #[derive(Default)]
+        pub struct DynamicInfo {
+            pub rela: usize,
+            pub relasz: usize,
+            pub relaent: $size,
+            pub relacount: usize,
+            pub rel: usize,
+            pub relsz: usize,
+            pub relent: $size,
+            pub relcount: usize,
+            pub gnu_hash: Option<$size>,
+            pub hash: Option<$size>,
+            pub strtab: usize,
+            pub strsz: usize,
+            pub symtab: usize,
+            pub syment: usize,
+            pub pltgot: Option<$size>,
+            pub pltrelsz: usize,
+            pub pltrel: $size,
+            pub jmprel: usize,
+            pub verneed: $size,
+            pub verneednum: $size,
+            pub versym: $size,
+            pub init: $size,
+            pub fini: $size,
+            pub init_array: $size,
+            pub init_arraysz: usize,
+            pub fini_array: $size,
+            pub fini_arraysz: usize,
+            pub needed_count: usize,
+            pub flags: $size,
+            pub flags_1: $size,
+            pub soname: usize,
+            pub textrel: bool,
+        }
+
+        impl DynamicInfo {
+            #[inline]
+            pub fn update(&mut self, bias: usize, dyn: &Dyn) {
+                match dyn.d_tag as u64 {
+                    DT_RELA => self.rela = dyn.d_val.wrapping_add(bias as _) as usize, // .rela.dyn
+                    DT_RELASZ => self.relasz = dyn.d_val as usize,
+                    DT_RELAENT => self.relaent = dyn.d_val as _,
+                    DT_RELACOUNT => self.relacount = dyn.d_val as usize,
+                    DT_REL => self.rel = dyn.d_val.wrapping_add(bias as _) as usize, // .rel.dyn
+                    DT_RELSZ => self.relsz = dyn.d_val as usize,
+                    DT_RELENT => self.relent = dyn.d_val as _,
+                    DT_RELCOUNT => self.relcount = dyn.d_val as usize,
+                    DT_GNU_HASH => self.gnu_hash = Some(dyn.d_val.wrapping_add(bias as _)),
+                    DT_HASH => self.hash = Some(dyn.d_val.wrapping_add(bias as _)) as _,
+                    DT_STRTAB => self.strtab = dyn.d_val.wrapping_add(bias as _) as usize,
+                    DT_STRSZ => self.strsz = dyn.d_val as usize,
+                    DT_SYMTAB => self.symtab = dyn.d_val.wrapping_add(bias as _) as usize,
+                    DT_SYMENT => self.syment = dyn.d_val as usize,
+                    DT_PLTGOT => self.pltgot = Some(dyn.d_val.wrapping_add(bias as _)) as _,
+                    DT_PLTRELSZ => self.pltrelsz = dyn.d_val as usize,
+                    DT_PLTREL => self.pltrel = dyn.d_val as _,
+                    DT_JMPREL => self.jmprel = dyn.d_val.wrapping_add(bias as _) as usize, // .rela.plt
+                    DT_VERNEED => self.verneed = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_VERNEEDNUM => self.verneednum = dyn.d_val as _,
+                    DT_VERSYM => self.versym = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_INIT => self.init = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_FINI => self.fini = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_INIT_ARRAY => self.init_array = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_INIT_ARRAYSZ => self.init_arraysz = dyn.d_val as _,
+                    DT_FINI_ARRAY => self.fini_array = dyn.d_val.wrapping_add(bias as _) as _,
+                    DT_FINI_ARRAYSZ => self.fini_arraysz = dyn.d_val as _,
+                    DT_NEEDED => self.needed_count += 1,
+                    DT_FLAGS => self.flags = dyn.d_val as _,
+                    DT_FLAGS_1 => self.flags_1 = dyn.d_val as _,
+                    DT_SONAME => self.soname = dyn.d_val as _,
+                    DT_TEXTREL => self.textrel = true,
+                    _ => (),
+                }
+            }
+            pub fn new(dynamic: &[Dyn], bias: usize) -> DynamicInfo {
+                let mut info = DynamicInfo::default();
+                for dyn in dynamic {
+                    info.update(bias, &dyn);
+                }
+                info
+            }
+        } // end if_std
+    };
+}
+
+
+pub mod dyn32 {
+    pub use elf::dyn::*;
+
+    elf_dyn!(u32);
+
+    pub const SIZEOF_DYN: usize = 8;
+
+    elf_dyn_std_impl!(u32, ::elf32::program_header::ProgramHeader);
+
+}
+
+
+pub mod dyn64 {
+    pub use elf::dyn::*;
+
+    elf_dyn!(u64);
+
+    pub const SIZEOF_DYN: usize = 16;
+
+    elf_dyn_std_impl!(u64, ::elf64::program_header::ProgramHeader);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/gnu_hash.rs
@@ -0,0 +1,129 @@
+//! A Gnu Hash table as 4 sections:
+//!
+//!   1. Header
+//!   2. Bloom Filter
+//!   3. Hash Buckets
+//!   4. Hash Values
+//!
+//! The header has is an array of four (4) u32s:
+//!
+//!   1. nbuckets
+//!   2. symndx
+//!   3. maskwords
+//!   4. shift2
+//!
+//! See: https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
+
+macro_rules! elf_gnu_hash_impl {
+    ($size:ty) => {
+
+        use core::slice;
+        use core::mem;
+        use strtab::Strtab;
+        use super::sym;
+
+        /// GNU hash function: takes a string and returns the u32 hash of that string
+        pub fn hash(symbol: &str) -> u32 {
+            let bytes = symbol.as_bytes();
+            const HASH_SEED: u32 = 5381;
+            let mut hash = HASH_SEED;
+            for b in bytes {
+                hash = hash.wrapping_mul(32).wrapping_add(*b as u32).wrapping_add(hash);
+            }
+            hash
+        }
+
+        pub struct GnuHash<'process> {
+            nbuckets: u32,
+            symindex: usize,
+            shift2: u32,
+            maskbits: u32,
+            bloomwords: &'process [$size], // either 32 or 64 bit masks, depending on platform
+            maskwords_bitmask: u32,
+            buckets: &'process [u32],
+            hashvalues: &'process [u32],
+            symtab: &'process [sym::Sym],
+        }
+
+        impl<'process> GnuHash<'process> {
+            pub unsafe fn new(hashtab: *const u32, total_dynsyms: usize, symtab: &'process [sym::Sym]) -> GnuHash<'process> {
+                let nbuckets = *hashtab;
+                let symindex = *hashtab.offset(1) as usize;
+                let maskwords = *hashtab.offset(2) as usize; // how many words our bloom filter mask has
+                let shift2 = *hashtab.offset(3);
+                let bloomwords_ptr = hashtab.offset(4) as *const $size;
+                let buckets_ptr = bloomwords_ptr.offset(maskwords as isize) as *const u32;
+                let buckets = slice::from_raw_parts(buckets_ptr, nbuckets as usize);
+                let hashvalues_ptr = buckets_ptr.offset(nbuckets as isize);
+                let hashvalues = slice::from_raw_parts(hashvalues_ptr, total_dynsyms - symindex);
+                let bloomwords = slice::from_raw_parts(bloomwords_ptr, maskwords);
+                GnuHash {
+                    nbuckets: nbuckets,
+                    symindex: symindex,
+                    shift2: shift2,
+                    maskbits: mem::size_of::<usize>() as u32,
+                    bloomwords: bloomwords,
+                    hashvalues: hashvalues,
+                    buckets: buckets,
+                    maskwords_bitmask: ((maskwords as i32) - 1) as u32,
+                    symtab: symtab,
+                }
+            }
+
+            #[inline(always)]
+            fn lookup(&self,
+                      symbol: &str,
+                      hash: u32,
+                      strtab: &Strtab)
+                      -> Option<&sym::Sym> {
+                let mut idx = self.buckets[(hash % self.nbuckets) as usize] as usize;
+                // println!("lookup idx = buckets[hash % nbuckets] = {}", idx);
+                if idx == 0 {
+                    return None;
+                }
+                let mut hash_idx = idx - self.symindex;
+                let hash = hash & !1;
+                // TODO: replace this with an iterator
+                loop {
+                    let symbol_ = &self.symtab[idx];
+                    let h2 = self.hashvalues[hash_idx];
+                    idx += 1;
+                    hash_idx += 1;
+                    let name = &strtab[symbol_.st_name as usize];
+                    // println!("{}: h2 0x{:x} resolves to: {}", i, h2, name);
+                    if hash == (h2 & !1) && name == symbol {
+                        // println!("lookup match for {} at: 0x{:x}", symbol, symbol_.st_value);
+                        return Some(symbol_);
+                    }
+                    if h2 & 1 == 1 {
+                        break;
+                    } // end of chain
+                }
+                None
+            }
+
+            #[inline(always)]
+            fn filter(&self, hash: u32) -> bool {
+                let bloom_idx = (hash / self.maskbits) & self.maskwords_bitmask;
+                let h2 = hash >> self.shift2;
+                let bitmask = (1u64 << (hash % self.maskbits)) | (1u64 << (h2 % self.maskbits));
+                // println!("lookup: maskwords: {} bloom_idx: {} bitmask: {} shift2: {}", self.maskwords, bloom_idx, bitmask, self.shift2);
+                let filter = self.bloomwords[bloom_idx as usize] as usize; // FIXME: verify this is safe ;)
+                filter & (bitmask as usize) != (bitmask as usize) // if true, def _don't have_
+            }
+
+            /// Given a name, a hash of that name, a strtab to cross-reference names, maybe returns a Sym
+            pub fn find(&self,
+                        name: &str,
+                        hash: u32,
+                        strtab: &Strtab)
+                        -> Option<&sym::Sym> {
+                if self.filter(hash) {
+                    None
+                } else {
+                    self.lookup(name, hash, strtab)
+                }
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/header.rs
@@ -0,0 +1,586 @@
+include!("constants_header.rs");
+
+macro_rules! elf_header {
+    ($size:ident) => {
+        use core::fmt;
+
+        #[repr(C)]
+        #[derive(Clone, Copy, Default, PartialEq)]
+        pub struct Header {
+            /// Magic number and other info
+            pub e_ident: [u8; SIZEOF_IDENT],
+            /// Object file type
+            pub e_type: u16,
+            /// Architecture
+            pub e_machine: u16,
+            /// Object file version
+            pub e_version: u32,
+            /// Entry point virtual address
+            pub e_entry: $size,
+            /// Program header table file offset
+            pub e_phoff: $size,
+            /// Section header table file offset
+            pub e_shoff: $size,
+            /// Processor-specific flags
+            pub e_flags: u32,
+            /// ELF header size in bytes
+            pub e_ehsize: u16,
+            /// Program header table entry size
+            pub e_phentsize: u16,
+            /// Program header table entry count
+            pub e_phnum: u16,
+            /// Section header table entry size
+            pub e_shentsize: u16,
+            /// Section header table entry count
+            pub e_shnum: u16,
+            /// Section header string table index
+            pub e_shstrndx: u16,
+        }
+
+        use plain;
+        // Declare that this is a plain type.
+        unsafe impl plain::Plain for Header {}
+
+        impl Header {
+            /// Returns the corresponding ELF header from the given byte array.
+            pub fn from_bytes(bytes: &[u8; SIZEOF_EHDR]) -> &Header {
+                // FIXME: Length is ensured correct because it's encoded in the type,
+                // but it can still panic due to invalid alignment.
+                plain::from_bytes(bytes).unwrap()
+            }
+        }
+        impl fmt::Debug for Header {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                write!(f,
+                       "e_ident: {:?} e_type: {} e_machine: 0x{:x} e_version: 0x{:x} e_entry: 0x{:x} \
+                        e_phoff: 0x{:x} e_shoff: 0x{:x} e_flags: {:x} e_ehsize: {} e_phentsize: {} \
+                        e_phnum: {} e_shentsize: {} e_shnum: {} e_shstrndx: {}",
+                       self.e_ident,
+                       et_to_str(self.e_type),
+                       self.e_machine,
+                       self.e_version,
+                       self.e_entry,
+                       self.e_phoff,
+                       self.e_shoff,
+                       self.e_flags,
+                       self.e_ehsize,
+                       self.e_phentsize,
+                       self.e_phnum,
+                       self.e_shentsize,
+                       self.e_shnum,
+                       self.e_shstrndx)
+            }
+        }
+    }
+}
+
+/// No file type.
+pub const ET_NONE: u16 = 0;
+/// Relocatable file.
+pub const ET_REL: u16 = 1;
+/// Executable file.
+pub const ET_EXEC: u16 = 2;
+/// Shared object file.
+pub const ET_DYN: u16 = 3;
+/// Core file.
+pub const ET_CORE: u16 = 4;
+/// Number of defined types.
+pub const ET_NUM: u16 = 5;
+
+/// The ELF magic number.
+pub const ELFMAG: &'static [u8; 4] = b"\x7FELF";
+/// Sizeof ELF magic number.
+pub const SELFMAG: usize = 4;
+
+/// File class byte index.
+pub const EI_CLASS: usize = 4;
+/// Invalid class.
+pub const ELFCLASSNONE: u8 = 0;
+/// 32-bit objects.
+pub const ELFCLASS32: u8 = 1;
+/// 64-bit objects.
+pub const ELFCLASS64: u8 = 2;
+/// ELF class number.
+pub const ELFCLASSNUM: u8 = 3;
+
+/// Data encoding byte index.
+pub const EI_DATA: usize = 5;
+/// Invalid data encoding.
+pub const ELFDATANONE: u8 = 0;
+/// 2's complement, little endian.
+pub const ELFDATA2LSB: u8 = 1;
+/// 2's complement, big endian.
+pub const ELFDATA2MSB: u8 = 2;
+/// Number of bytes in an identifier.
+pub const SIZEOF_IDENT: usize = 16;
+
+/// Convert a ELF class byte to the associated string.
+#[inline]
+pub fn class_to_str(et: u8) -> &'static str {
+    match et {
+        ELFCLASSNONE => "NONE",
+        ELFCLASS32 => "ELF32",
+        ELFCLASS64 => "ELF64",
+        _ => "UNKNOWN_CLASS",
+    }
+}
+
+/// Convert an ET value to their associated string.
+#[inline]
+pub fn et_to_str(et: u16) -> &'static str {
+    match et {
+        ET_NONE => "NONE",
+        ET_REL => "REL",
+        ET_EXEC => "EXEC",
+        ET_DYN => "DYN",
+        ET_CORE => "CORE",
+        ET_NUM => "NUM",
+        _ => "UNKNOWN_ET",
+    }
+}
+
+if_alloc! {
+    use error::{self};
+    use scroll::{self, ctx, Endian};
+    use core::fmt;
+    use container::{Ctx, Container};
+    use alloc::string::ToString;
+
+    #[derive(Copy, Clone, PartialEq)]
+    /// An ELF header
+    pub struct Header {
+        pub e_ident           : [u8; SIZEOF_IDENT],
+        pub e_type            : u16,
+        pub e_machine         : u16,
+        pub e_version         : u32,
+        pub e_entry           : u64,
+        pub e_phoff           : u64,
+        pub e_shoff           : u64,
+        pub e_flags           : u32,
+        pub e_ehsize          : u16,
+        pub e_phentsize       : u16,
+        pub e_phnum           : u16,
+        pub e_shentsize       : u16,
+        pub e_shnum           : u16,
+        pub e_shstrndx        : u16,
+    }
+
+    impl Header {
+        /// Return the size of the underlying program header, given a `container`
+        #[inline]
+        pub fn size(ctx: &Ctx) -> usize {
+            use scroll::ctx::SizeWith;
+            Self::size_with(ctx)
+        }
+        /// Returns the container type this header specifies
+        pub fn container(&self) -> error::Result<Container> {
+            use error::Error;
+            match self.e_ident[EI_CLASS] {
+                ELFCLASS32 => { Ok(Container::Little) },
+                ELFCLASS64 => { Ok(Container::Big) },
+                class => Err(Error::Malformed(format!("Invalid class in Header: {}", class)))
+            }
+        }
+        /// Returns the byte order this header specifies
+        pub fn endianness(&self) -> error::Result<scroll::Endian> {
+            use error::Error;
+            match self.e_ident[EI_DATA] {
+                ELFDATA2LSB => { Ok(scroll::LE) },
+                ELFDATA2MSB => { Ok(scroll::BE) },
+                class => Err(Error::Malformed(format!("Invalid endianness in Header: {}", class)))
+            }
+        }
+        pub fn new(ctx: Ctx) -> Self {
+            use elf32;
+            use elf64;
+            let (typ, ehsize, phentsize, shentsize) = match ctx.container {
+                Container::Little => {
+                    (ELFCLASS32, header32::SIZEOF_EHDR,
+                     elf32::program_header::SIZEOF_PHDR,
+                     elf32::section_header::SIZEOF_SHDR)
+                },
+                Container::Big => {
+                    (ELFCLASS64, header64::SIZEOF_EHDR,
+                     elf64::program_header::SIZEOF_PHDR,
+                     elf64::section_header::SIZEOF_SHDR)
+                }
+            };
+            let byteorder = match ctx.le { Endian::Little => ELFDATA2LSB, Endian::Big => ELFDATA2MSB };
+            Header {
+                e_ident: [
+                    127,
+                    69,
+                    76,
+                    70,
+                    typ,
+                    byteorder,
+                    1,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0
+                ],
+                e_type: ET_DYN,
+                e_machine: EM_NONE,
+                e_version: 1,
+                e_entry: 0x0,
+                e_phoff: 0x0,
+                e_shoff: 0x0,
+                e_flags: 0,
+                e_ehsize: ehsize as u16,
+                e_phentsize: phentsize as u16,
+                e_phnum: 0,
+                e_shentsize: shentsize as u16,
+                e_shnum: 0,
+                e_shstrndx: 0,
+            }
+        }
+    }
+
+    impl fmt::Debug for Header {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f,
+                   "e_ident: {:?} e_type: {} e_machine: 0x{:x} e_version: 0x{:x} e_entry: 0x{:x} \
+                    e_phoff: 0x{:x} e_shoff: 0x{:x} e_flags: {:x} e_ehsize: {} e_phentsize: {} \
+                    e_phnum: {} e_shentsize: {} e_shnum: {} e_shstrndx: {}",
+                   self.e_ident,
+                   et_to_str(self.e_type),
+                   self.e_machine,
+                   self.e_version,
+                   self.e_entry,
+                   self.e_phoff,
+                   self.e_shoff,
+                   self.e_flags,
+                   self.e_ehsize,
+                   self.e_phentsize,
+                   self.e_phnum,
+                   self.e_shentsize,
+                   self.e_shnum,
+                   self.e_shstrndx)
+        }
+    }
+
+    impl ctx::SizeWith<::container::Ctx> for Header {
+        type Units = usize;
+        fn size_with(ctx: &::container::Ctx) -> usize {
+            match ctx.container {
+                Container::Little => {
+                    header32::SIZEOF_EHDR
+                },
+                Container::Big => {
+                    header64::SIZEOF_EHDR
+                },
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, scroll::Endian> for Header {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], _ctx: scroll::Endian) -> error::Result<(Self, Self::Size)> {
+            use scroll::Pread;
+            if bytes.len() < SIZEOF_IDENT {
+                return Err(error::Error::Malformed("Too small".to_string()));
+            }
+            let ident: &[u8] = &bytes[..SIZEOF_IDENT];
+            if &ident[0..SELFMAG] != ELFMAG {
+                let magic: u64 = ident.pread_with(0, scroll::LE)?;
+                return Err(error::Error::BadMagic(magic).into());
+            }
+            let class = ident[EI_CLASS];
+            match class {
+                ELFCLASS32 => {
+                    Ok((Header::from(bytes.pread::<header32::Header>(0)?), header32::SIZEOF_EHDR))
+                },
+                ELFCLASS64 => {
+                    Ok((Header::from(bytes.pread::<header64::Header>(0)?), header64::SIZEOF_EHDR))
+                },
+                _ => {
+                    Err(error::Error::Malformed(format!("invalid ELF class {:x}", class)).into())
+                }
+            }
+        }
+    }
+
+    // TODO: i think we should remove this forcing of the information in the header, it causes too many conflicts
+    impl ctx::TryIntoCtx<scroll::Endian> for Header {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_into_ctx(self, bytes: &mut [u8], _ctx: scroll::Endian) -> Result<Self::Size, Self::Error> {
+            use scroll::Pwrite;
+            match self.container()? {
+                Container::Little => {
+                    bytes.pwrite(header32::Header::from(self), 0)
+                },
+                Container::Big => {
+                    bytes.pwrite(header64::Header::from(self), 0)
+                }
+            }
+        }
+    }
+    impl ctx::IntoCtx<::container::Ctx> for Header {
+        fn into_ctx(self, bytes: &mut [u8], ctx: ::container::Ctx) -> () {
+            use scroll::Pwrite;
+            match ctx.container {
+                Container::Little => {
+                    bytes.pwrite_with(header32::Header::from(self), 0, ctx.le).unwrap()
+                },
+                Container::Big => {
+                    bytes.pwrite_with(header64::Header::from(self), 0, ctx.le).unwrap()
+                }
+            };
+        }
+    }
+} // end if_alloc
+
+macro_rules! elf_header_std_impl {
+    ($size:expr, $width:ty) => {
+
+        if_alloc! {
+            use elf::header::Header as ElfHeader;
+            use error::Error;
+            #[cfg(any(feature = "std", feature = "endian_fd"))]
+            use error::Result;
+
+            use scroll::{self, ctx, Pread};
+
+            use core::result;
+
+            if_std! {
+                use std::fs::File;
+                use std::io::{Read};
+            }
+
+            impl From<ElfHeader> for Header {
+                fn from(eh: ElfHeader) -> Self {
+                    Header {
+                        e_ident: eh.e_ident,
+                        e_type: eh.e_type,
+                        e_machine: eh.e_machine,
+                        e_version: eh.e_version,
+                        e_entry: eh.e_entry as $width,
+                        e_phoff: eh.e_phoff as $width,
+                        e_shoff: eh.e_shoff as $width,
+                        e_flags: eh.e_flags,
+                        e_ehsize: eh.e_ehsize,
+                        e_phentsize: eh.e_phentsize,
+                        e_phnum: eh.e_phnum,
+                        e_shentsize: eh.e_shentsize,
+                        e_shnum: eh.e_shnum,
+                        e_shstrndx: eh.e_shstrndx,
+                    }
+                }
+            }
+
+            impl From<Header> for ElfHeader {
+                fn from(eh: Header) -> Self {
+                    ElfHeader {
+                        e_ident: eh.e_ident,
+                        e_type: eh.e_type,
+                        e_machine: eh.e_machine,
+                        e_version: eh.e_version,
+                        e_entry: eh.e_entry as u64,
+                        e_phoff: eh.e_phoff as u64,
+                        e_shoff: eh.e_shoff as u64,
+                        e_flags: eh.e_flags,
+                        e_ehsize: eh.e_ehsize,
+                        e_phentsize: eh.e_phentsize,
+                        e_phnum: eh.e_phnum,
+                        e_shentsize: eh.e_shentsize,
+                        e_shnum: eh.e_shnum,
+                        e_shstrndx: eh.e_shstrndx,
+                    }
+                }
+            }
+
+            impl<'a> ctx::TryFromCtx<'a, scroll::Endian> for Header {
+                type Error = ::error::Error;
+                type Size = usize;
+                fn try_from_ctx(bytes: &'a [u8], _: scroll::Endian) -> result::Result<(Self, Self::Size), Self::Error> {
+                    let mut elf_header = Header::default();
+                    let offset = &mut 0;
+                    bytes.gread_inout(offset, &mut elf_header.e_ident)?;
+                    let endianness =
+                        match elf_header.e_ident[EI_DATA] {
+                            ELFDATA2LSB => scroll::LE,
+                            ELFDATA2MSB => scroll::BE,
+                            d => return Err(Error::Malformed(format!("invalid ELF endianness DATA type {:x}", d)).into()),
+                        };
+                    elf_header.e_type =      bytes.gread_with(offset, endianness)?;
+                    elf_header.e_machine =   bytes.gread_with(offset, endianness)?;
+                    elf_header.e_version =   bytes.gread_with(offset, endianness)?;
+                    elf_header.e_entry =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phoff =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shoff =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_flags =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_ehsize =    bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phentsize = bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phnum =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shentsize = bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shnum =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shstrndx =  bytes.gread_with(offset, endianness)?;
+                    Ok((elf_header, SIZEOF_EHDR))
+                }
+            }
+
+            impl ctx::TryIntoCtx<scroll::Endian> for Header {
+                type Error = ::error::Error;
+                type Size = usize;
+                /// a Pwrite impl for Header: **note** we use the endianness value in the header, and not a parameter
+                fn try_into_ctx(self, bytes: &mut [u8], _endianness: scroll::Endian) -> result::Result<Self::Size, Self::Error> {
+                    use scroll::{Pwrite};
+                    let offset = &mut 0;
+                    let endianness =
+                        match self.e_ident[EI_DATA] {
+                            ELFDATA2LSB => scroll::LE,
+                            ELFDATA2MSB => scroll::BE,
+                            d => return Err(Error::Malformed(format!("invalid ELF DATA type {:x}", d)).into()),
+                        };
+                    for i in 0..self.e_ident.len() {
+                        bytes.gwrite(self.e_ident[i], offset)?;
+                    }
+                    bytes.gwrite_with(self.e_type      , offset, endianness)?;
+                    bytes.gwrite_with(self.e_machine   , offset, endianness)?;
+                    bytes.gwrite_with(self.e_version   , offset, endianness)?;
+                    bytes.gwrite_with(self.e_entry     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_phoff     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_shoff     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_flags     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_ehsize    , offset, endianness)?;
+                    bytes.gwrite_with(self.e_phentsize , offset, endianness)?;
+                    bytes.gwrite_with(self.e_phnum     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_shentsize , offset, endianness)?;
+                    bytes.gwrite_with(self.e_shnum     , offset, endianness)?;
+                    bytes.gwrite_with(self.e_shstrndx  , offset, endianness)?;
+                    Ok(SIZEOF_EHDR)
+                }
+            }
+
+            impl Header {
+                /// Load a header from a file. **You must** ensure the seek is at the correct position.
+                #[cfg(feature = "std")]
+                pub fn from_fd(bytes: &mut File) -> Result<Header> {
+                    let mut elf_header = [0; $size];
+                    bytes.read(&mut elf_header)?;
+                    Ok(*Header::from_bytes(&elf_header))
+                }
+
+                #[cfg(feature = "endian_fd")]
+                /// Parses an ELF header from the given bytes
+                pub fn parse(bytes: &[u8]) -> Result<Header> {
+                    use super::{EI_DATA, ELFDATA2LSB, ELFDATA2MSB, SIZEOF_IDENT};
+
+                    let mut elf_header = Header::default();
+                    let mut offset = &mut 0;
+                    for i in 0..SIZEOF_IDENT {
+                        elf_header.e_ident[i] = bytes.gread(&mut offset)?;
+                    }
+                    let endianness =
+                        match elf_header.e_ident[EI_DATA] {
+                            ELFDATA2LSB => scroll::LE,
+                            ELFDATA2MSB => scroll::BE,
+                            d => return Err(Error::Malformed(format!("invalid ELF DATA type {:x}", d)).into()),
+                        };
+                    elf_header.e_type =      bytes.gread_with(offset, endianness)?;
+                    elf_header.e_machine =   bytes.gread_with(offset, endianness)?;
+                    elf_header.e_version =   bytes.gread_with(offset, endianness)?;
+                    elf_header.e_entry =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phoff =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shoff =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_flags =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_ehsize =    bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phentsize = bytes.gread_with(offset, endianness)?;
+                    elf_header.e_phnum =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shentsize = bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shnum =     bytes.gread_with(offset, endianness)?;
+                    elf_header.e_shstrndx =  bytes.gread_with(offset, endianness)?;
+                    Ok(elf_header)
+                }
+            }
+        } // end if_alloc
+    };
+}
+
+// tests
+
+macro_rules! elf_header_test {
+    ($class:expr) => {
+        #[cfg(test)]
+        mod test {
+            use scroll::{Pwrite, Pread};
+            use elf::header::Header as ElfHeader;
+            use super::*;
+            use container::{Ctx, Container};
+            use alloc::vec::Vec;
+            #[test]
+            fn size_of() {
+                assert_eq!(::std::mem::size_of::<Header>(), SIZEOF_EHDR);
+            }
+            #[test]
+            fn header_read_write () {
+                let crt1: Vec<u8> =
+                    if $class == ELFCLASS64 {
+                        include!("../../etc/crt1.rs")
+                    } else {
+                        include!("../../etc/crt132.rs")
+                    };
+                let header: Header = crt1.pread(0).unwrap();
+                assert_eq!(header.e_type, ET_REL);
+                println!("header: {:?}", &header);
+                let mut bytes = [0u8; SIZEOF_EHDR];
+                bytes.pwrite(header, 0).unwrap();
+                let header2: Header = bytes.pread(0).unwrap();
+                assert_eq!(header, header2);
+            }
+            #[test]
+            fn elfheader_read_write () {
+                let (container, crt1): (Container, Vec<u8>) =
+                    if $class == ELFCLASS64 {
+                        (Container::Big, include!("../../etc/crt1.rs"))
+                    } else {
+                        (Container::Little, include!("../../etc/crt132.rs"))
+                    };
+                let header: Header = crt1.pread(0).unwrap();
+                assert_eq!(header.e_type, ET_REL);
+                println!("header: {:?}", &header);
+                let mut bytes = [0u8; SIZEOF_EHDR];
+                let header_ = Header::from(header.clone());
+                bytes.pwrite(header_, 0).unwrap();
+                let header2: Header = bytes.pread(0).unwrap();
+                assert_eq!(header, header2);
+                let header = ElfHeader::new(Ctx::from(container));
+                println!("header: {:?}", &header);
+
+                let mut bytes = vec![0; 100];
+                bytes.pwrite(header, 0).unwrap();
+            }
+        }
+    }
+}
+
+pub mod header32 {
+    pub use super::*;
+
+    pub const SIZEOF_EHDR: usize = 52;
+    pub const ELFCLASS: u8 = ELFCLASS32;
+
+    elf_header!(u32);
+    elf_header_std_impl!(SIZEOF_EHDR, u32);
+    elf_header_test!(ELFCLASS);
+}
+
+pub mod header64 {
+    pub use super::*;
+
+    pub const SIZEOF_EHDR: usize = 64;
+    pub const ELFCLASS: u8 = ELFCLASS64;
+
+    elf_header!(u64);
+    elf_header_std_impl!(SIZEOF_EHDR, u64);
+    elf_header_test!(ELFCLASS);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/mod.rs
@@ -0,0 +1,433 @@
+//! The generic ELF module, which gives access to ELF constants and other helper functions, which are independent of ELF bithood.  Also defines an `Elf` struct which implements a unified parser that returns a wrapped `Elf64` or `Elf32` binary.
+//!
+//! To access the exact 32-bit or 64-bit versions, use [goblin::elf32::Header](header/header32/struct.Header.html)/[goblin::elf64::Header](header/header64/struct.Header.html), etc., for the various 32/64-bit structs.
+//!
+//! # Example
+//!
+//! ```rust
+//! use std::fs::File;
+//!
+//! pub fn read (bytes: &[u8]) {
+//!   match goblin::elf::Elf::parse(&bytes) {
+//!     Ok(binary) => {
+//!       let entry = binary.entry;
+//!       for ph in binary.program_headers {
+//!         if ph.p_type == goblin::elf::program_header::PT_LOAD {
+//!           let mut _buf = vec![0u8; ph.p_filesz as usize];
+//!           // read responsibly
+//!          }
+//!       }
+//!     },
+//!     Err(_) => ()
+//!   }
+//! }
+//! ```
+//!
+//! This will properly access the underlying 32-bit or 64-bit binary automatically. Note that since
+//! 32-bit binaries typically have shorter 32-bit values in some cases (specifically for addresses and pointer
+//! values), these values are upcasted to u64/i64s when appropriate.
+//!
+//! See [goblin::elf::Elf](struct.Elf.html) for more information.
+//!
+//! You are still free to use the specific 32-bit or 64-bit versions by accessing them through `goblin::elf64`, etc., but you will have to parse and/or construct the various components yourself.
+//! In other words, there is no unified 32/64-bit `Elf` struct.
+//!
+//! # Note
+//! To use the automagic ELF datatype union parser, you _must_ enable/opt-in to the  `elf64`, `elf32`, and
+//! `endian_fd` features if you disable `default`.
+
+#[macro_use]
+mod gnu_hash;
+
+// These are shareable values for the 32/64 bit implementations.
+//
+// They are publicly re-exported by the pub-using module
+pub mod header;
+pub mod program_header;
+pub mod section_header;
+pub mod compression_header;
+#[macro_use]
+pub mod sym;
+pub mod dyn;
+#[macro_use]
+pub mod reloc;
+pub mod note;
+
+macro_rules! if_sylvan {
+    ($($i:item)*) => ($(
+        #[cfg(all(feature = "elf32", feature = "elf64", feature = "endian_fd"))]
+        $i
+    )*)
+}
+
+if_sylvan! {
+    use scroll::{self, ctx, Pread, Endian};
+    use strtab::Strtab;
+    use error;
+    use container::{Container, Ctx};
+    use alloc::vec::Vec;
+
+    pub type Header = header::Header;
+    pub type ProgramHeader = program_header::ProgramHeader;
+    pub type SectionHeader = section_header::SectionHeader;
+    pub type Symtab<'a> = sym::Symtab<'a>;
+    pub type Sym = sym::Sym;
+    pub type Dyn = dyn::Dyn;
+    pub type Dynamic = dyn::Dynamic;
+    pub type Reloc = reloc::Reloc;
+
+    pub type ProgramHeaders = Vec<ProgramHeader>;
+    pub type SectionHeaders = Vec<SectionHeader>;
+    pub type ShdrIdx = usize;
+
+    #[derive(Debug)]
+    /// An ELF binary. The underlying data structures are read according to the headers byte order and container size (32 or 64).
+    pub struct Elf<'a> {
+        /// The ELF header, which provides a rudimentary index into the rest of the binary
+        pub header: Header,
+        /// The program headers; they primarily tell the kernel and the dynamic linker
+        /// how to load this binary
+        pub program_headers: ProgramHeaders,
+        /// The sections headers. These are strippable, never count on them being
+        /// here unless you're a static linker!
+        pub section_headers: SectionHeaders,
+        /// The section header string table
+        pub shdr_strtab: Strtab<'a>,
+        /// The string table for the dynamically accessible symbols
+        pub dynstrtab: Strtab<'a>,
+        /// The dynamically accessible symbols, i.e., exports, imports.
+        /// This is what the dynamic linker uses to dynamically load and link your binary,
+        /// or find imported symbols for binaries which dynamically link against your library
+        pub dynsyms: Symtab<'a>,
+        /// The debugging symbol table
+        pub syms: Symtab<'a>,
+        /// The string table for the symbol table
+        pub strtab: Strtab<'a>,
+        /// Contains dynamic linking information, with the _DYNAMIC array + a preprocessed DynamicInfo for that array
+        pub dynamic: Option<Dynamic>,
+        /// The dynamic relocation entries (strings, copy-data, etc.) with an addend
+        pub dynrelas: Vec<Reloc>,
+        /// The dynamic relocation entries without an addend
+        pub dynrels: Vec<Reloc>,
+        /// The plt relocation entries (procedure linkage table). For 32-bit binaries these are usually Rel (no addend)
+        pub pltrelocs: Vec<Reloc>,
+        /// Section relocations by section index (only present if this is a relocatable object file)
+        pub shdr_relocs: Vec<(ShdrIdx, Vec<Reloc>)>,
+        /// The binary's soname, if it has one
+        pub soname: Option<&'a str>,
+        /// The binary's program interpreter (e.g., dynamic linker), if it has one
+        pub interpreter: Option<&'a str>,
+        /// A list of this binary's dynamic libraries it uses, if there are any
+        pub libraries: Vec<&'a str>,
+        pub is_64: bool,
+        /// Whether this is a shared object or not
+        pub is_lib: bool,
+        /// The binaries entry point address, if it has one
+        pub entry: u64,
+        /// The bias used to overflow virtual memory addresses into physical byte offsets into the binary
+        pub bias: u64,
+        /// Whether the binary is little endian or not
+        pub little_endian: bool,
+        ctx: Ctx,
+    }
+
+    impl<'a> Elf<'a> {
+        /// Try to iterate notes in PT_NOTE program headers; returns `None` if there aren't any note headers in this binary
+        pub fn iter_note_headers(&self, data: &'a [u8]) -> Option<note::NoteIterator<'a>> {
+            let mut iters = vec![];
+            for phdr in &self.program_headers {
+                if phdr.p_type == program_header::PT_NOTE {
+                    let offset = phdr.p_offset as usize;
+                    let alignment = phdr.p_align as usize;
+
+                    iters.push(note::NoteDataIterator {
+                        data,
+                        offset,
+                        size: offset + phdr.p_filesz as usize,
+                        ctx: (alignment, self.ctx)
+                    });
+                }
+            }
+
+            if iters.is_empty() {
+                None
+            } else {
+                Some(note::NoteIterator {
+                    iters: iters,
+                    index: 0,
+                })
+            }
+        }
+        /// Try to iterate notes in SHT_NOTE sections; returns `None` if there aren't any note sections in this binary
+        ///
+        /// If a section_name is given, only the section with the according name is iterated.
+        pub fn iter_note_sections(
+            &self,
+            data: &'a [u8],
+            section_name: Option<&str>,
+        ) -> Option<note::NoteIterator<'a>> {
+            let mut iters = vec![];
+            for sect in &self.section_headers {
+                if sect.sh_type != section_header::SHT_NOTE {
+                    continue;
+                }
+
+                if section_name.is_some() && !self.shdr_strtab
+                    .get(sect.sh_name)
+                    .map_or(false, |r| r.ok() == section_name) {
+                    continue;
+                }
+
+                let offset = sect.sh_offset as usize;
+                let alignment = sect.sh_addralign as usize;
+                iters.push(note::NoteDataIterator {
+                    data,
+                    offset,
+                    size: offset + sect.sh_size as usize,
+                    ctx: (alignment, self.ctx)
+                });
+            }
+
+            if iters.is_empty() {
+                None
+            } else {
+                Some(note::NoteIterator {
+                    iters: iters,
+                    index: 0,
+                })
+            }
+        }
+        pub fn is_object_file(&self) -> bool {
+            self.header.e_type == header::ET_REL
+        }
+        /// Parses the contents of the byte stream in `bytes`, and maybe returns a unified binary
+        pub fn parse(bytes: &'a [u8]) -> error::Result<Self> {
+            let header = bytes.pread::<Header>(0)?;
+            let entry = header.e_entry as usize;
+            let is_lib = header.e_type == header::ET_DYN;
+            let is_lsb = header.e_ident[header::EI_DATA] == header::ELFDATA2LSB;
+            let endianness = scroll::Endian::from(is_lsb);
+            let class = header.e_ident[header::EI_CLASS];
+            if class != header::ELFCLASS64 && class != header::ELFCLASS32 {
+                return Err(error::Error::Malformed(format!("Unknown values in ELF ident header: class: {} endianness: {}",
+                                                           class,
+                                                           header.e_ident[header::EI_DATA])).into());
+            }
+            let is_64 = class == header::ELFCLASS64;
+            let container = if is_64 { Container::Big } else { Container::Little };
+            let ctx = Ctx::new(container, endianness);
+
+            let program_headers = ProgramHeader::parse(bytes, header.e_phoff as usize, header.e_phnum as usize, ctx)?;
+
+            let mut bias: usize = 0;
+            for ph in &program_headers {
+                if ph.p_type == program_header::PT_LOAD {
+                    // NB this _only_ works on the first load address, and the GOT values (usually at base + 2000) will be incorrect binary offsets...
+                    // this is an overflow hack that allows us to use virtual memory addresses
+                    // as though they're in the file by generating a fake load bias which is then
+                    // used to overflow the values in the dynamic array, and in a few other places
+                    // (see Dyn::DynamicInfo), to generate actual file offsets; you may have to
+                    // marinate a bit on why this works. i am unsure whether it works in every
+                    // conceivable case. i learned this trick from reading too much dynamic linker
+                    // C code (a whole other class of C code) and having to deal with broken older
+                    // kernels on VMs. enjoi
+                    bias = match container {
+                        Container::Little => (::core::u32::MAX - (ph.p_vaddr as u32)).wrapping_add(1) as usize,
+                        Container::Big    => (::core::u64::MAX - ph.p_vaddr).wrapping_add(1) as usize,
+                    };
+                    // we must grab only the first one, otherwise the bias will be incorrect
+                    break;
+                }
+            }
+
+            let mut interpreter = None;
+            for ph in &program_headers {
+                if ph.p_type == program_header::PT_INTERP && ph.p_filesz != 0 {
+                    let count = (ph.p_filesz - 1) as usize;
+                    let offset = ph.p_offset as usize;
+                    interpreter = Some(bytes.pread_with::<&str>(offset, ::scroll::ctx::StrCtx::Length(count))?);
+                }
+            }
+
+            let section_headers = SectionHeader::parse(bytes, header.e_shoff as usize, header.e_shnum as usize, ctx)?;
+
+            let get_strtab = |section_headers: &[SectionHeader], section_idx: usize| {
+                if section_idx >= section_headers.len() {
+                    // FIXME: warn! here
+                    Ok(Strtab::default())
+                } else {
+                    let shdr = &section_headers[section_idx];
+                    shdr.check_size(bytes.len())?;
+                    Strtab::parse(bytes, shdr.sh_offset as usize, shdr.sh_size as usize, 0x0)
+                }
+            };
+
+            let strtab_idx = header.e_shstrndx as usize;
+            let shdr_strtab = get_strtab(&section_headers, strtab_idx)?;
+
+            let mut syms = Symtab::default();
+            let mut strtab = Strtab::default();
+            for shdr in &section_headers {
+                if shdr.sh_type as u32 == section_header::SHT_SYMTAB {
+                    let size = shdr.sh_entsize;
+                    let count = if size == 0 { 0 } else { shdr.sh_size / size };
+                    syms = Symtab::parse(bytes, shdr.sh_offset as usize, count as usize, ctx)?;
+                    strtab = get_strtab(&section_headers, shdr.sh_link as usize)?;
+                }
+            }
+
+            let mut soname = None;
+            let mut libraries = vec![];
+            let mut dynsyms = Symtab::default();
+            let mut dynrelas = vec![];
+            let mut dynrels = vec![];
+            let mut pltrelocs = vec![];
+            let mut dynstrtab = Strtab::default();
+            let dynamic = Dynamic::parse(bytes, &program_headers, bias, ctx)?;
+            if let Some(ref dynamic) = dynamic {
+                let dyn_info = &dynamic.info;
+                dynstrtab = Strtab::parse(bytes,
+                                          dyn_info.strtab,
+                                          dyn_info.strsz,
+                                          0x0)?;
+
+                if dyn_info.soname != 0 {
+                    // FIXME: warn! here
+                    soname = match dynstrtab.get(dyn_info.soname) { Some(Ok(soname)) => Some(soname), _ => None };
+                }
+                if dyn_info.needed_count > 0 {
+                    libraries = dynamic.get_libraries(&dynstrtab);
+                }
+                let num_syms = if dyn_info.syment == 0 { 0 } else { if dyn_info.strtab <= dyn_info.symtab { 0 } else { (dyn_info.strtab - dyn_info.symtab) / dyn_info.syment }};
+                dynsyms = Symtab::parse(bytes, dyn_info.symtab, num_syms, ctx)?;
+                // parse the dynamic relocations
+                dynrelas = Reloc::parse(bytes, dyn_info.rela, dyn_info.relasz, true, ctx)?;
+                dynrels = Reloc::parse(bytes, dyn_info.rel, dyn_info.relsz, false, ctx)?;
+                let is_rela = dyn_info.pltrel as u64 == dyn::DT_RELA;
+                pltrelocs = Reloc::parse(bytes, dyn_info.jmprel, dyn_info.pltrelsz, is_rela, ctx)?;
+            }
+
+            // iterate through shdrs again iff we're an ET_REL
+            let shdr_relocs = {
+                let mut relocs = vec![];
+                if header.e_type == header::ET_REL {
+                    for (idx, section) in section_headers.iter().enumerate() {
+                        if section.sh_type == section_header::SHT_REL {
+                            section.check_size(bytes.len())?;
+                            let sh_relocs = Reloc::parse(bytes, section.sh_offset as usize, section.sh_size as usize, false, ctx)?;
+                            relocs.push((idx, sh_relocs));
+                        }
+                        if section.sh_type == section_header::SHT_RELA {
+                            section.check_size(bytes.len())?;
+                            let sh_relocs = Reloc::parse(bytes, section.sh_offset as usize, section.sh_size as usize, true, ctx)?;
+                            relocs.push((idx, sh_relocs));
+                        }
+                    }
+                }
+                relocs
+            };
+            Ok(Elf {
+                header: header,
+                program_headers: program_headers,
+                section_headers: section_headers,
+                shdr_strtab: shdr_strtab,
+                dynamic: dynamic,
+                dynsyms: dynsyms,
+                dynstrtab: dynstrtab,
+                syms: syms,
+                strtab: strtab,
+                dynrelas: dynrelas,
+                dynrels: dynrels,
+                pltrelocs: pltrelocs,
+                shdr_relocs: shdr_relocs,
+                soname: soname,
+                interpreter: interpreter,
+                libraries: libraries,
+                is_64: is_64,
+                is_lib: is_lib,
+                entry: entry as u64,
+                bias: bias as u64,
+                little_endian: is_lsb,
+                ctx,
+            })
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, (usize, Endian)> for Elf<'a> {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(src: &'a [u8], (_, _): (usize, Endian)) -> Result<(Elf<'a>, Self::Size), Self::Error> {
+            let elf = Elf::parse(src)?;
+            Ok((elf, src.len()))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn parse_crt1_64bit() {
+        let crt1: Vec<u8> = include!("../../etc/crt1.rs");
+        match Elf::parse(&crt1) {
+            Ok (binary) => {
+                assert!(binary.is_64);
+                assert!(!binary.is_lib);
+                assert_eq!(binary.entry, 0);
+                assert_eq!(binary.bias, 0);
+                assert!(binary.syms.get(1000).is_none());
+                assert!(binary.syms.get(5).is_some());
+                let syms = binary.syms.to_vec();
+                let mut i = 0;
+                assert!(binary.section_headers.len() != 0);
+                for sym in &syms {
+                    if i == 11 {
+                        let symtab = binary.strtab;
+                        println!("sym: {:?}", &sym);
+                        assert_eq!(&symtab[sym.st_name], "_start");
+                        break;
+                    }
+                    i += 1;
+                }
+                assert!(syms.len() != 0);
+             },
+            Err (err) => {
+                println!("failed: {}", err);
+                assert!(false)
+            }
+        }
+    }
+
+    #[test]
+    fn parse_crt1_32bit() {
+        let crt1: Vec<u8> = include!("../../etc/crt132.rs");
+        match Elf::parse(&crt1) {
+            Ok (binary) => {
+                assert!(!binary.is_64);
+                assert!(!binary.is_lib);
+                assert_eq!(binary.entry, 0);
+                assert_eq!(binary.bias, 0);
+                assert!(binary.syms.get(1000).is_none());
+                assert!(binary.syms.get(5).is_some());
+                let syms = binary.syms.to_vec();
+                let mut i = 0;
+                assert!(binary.section_headers.len() != 0);
+                for sym in &syms {
+                    if i == 11 {
+                        let symtab = binary.strtab;
+                        println!("sym: {:?}", &sym);
+                        assert_eq!(&symtab[sym.st_name], "__libc_csu_fini");
+                        break;
+                    }
+                    i += 1;
+                }
+                assert!(syms.len() != 0);
+             },
+            Err (err) => {
+                println!("failed: {}", err);
+                assert!(false)
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/note.rs
@@ -0,0 +1,273 @@
+// Defined note types for GNU systems.
+
+// ABI information.  The descriptor consists of words:
+//    word 0: OS descriptor
+//    word 1: major version of the ABI
+//    word 2: minor version of the ABI
+//    word 3: subminor version of the ABI
+
+pub const NT_GNU_ABI_TAG: u32 = 1;
+// Old name
+pub const ELF_NOTE_ABI: u32 = NT_GNU_ABI_TAG;
+// Known OSes.  These values can appear in word 0 of an
+//    NT_GNU_ABI_TAG note section entry.
+pub const ELF_NOTE_OS_LINUX: u32 = 0;
+pub const ELF_NOTE_OS_GNU: u32 = 1;
+pub const ELF_NOTE_OS_SOLARIS2: u32 = 2;
+pub const ELF_NOTE_OS_FREEBSD: u32 = 3;
+
+// Synthetic hwcap information.  The descriptor begins with two words:
+//    word 0: number of entries
+//    word 1: bitmask of enabled entries
+//    Then follow variable-length entries, one byte followed by a
+//    '\0'-terminated hwcap name string.  The byte gives the bit
+//    number to test if enabled, (1U << bit) & bitmask.
+pub const NT_GNU_HWCAP: u32 = 2;
+
+// Build ID bits as generated by ld --build-id.
+//    The descriptor consists of any nonzero number of bytes.
+pub const NT_GNU_BUILD_ID: u32 = 3;
+
+// Version note generated by GNU gold containing a version string.
+pub const NT_GNU_GOLD_VERSION: u32 = 4;
+
+#[derive(Clone, Copy, Debug)]
+#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
+#[repr(C)]
+/// Note section contents. Each entry in the note section begins with a header of a fixed form.
+pub struct Nhdr32 {
+    /// Length of the note's name (includes the terminator)
+    pub n_namesz: u32,
+    /// Length of the note's descriptor
+    pub n_descsz: u32,
+    /// Type of the note
+    pub n_type: u32,
+}
+
+#[derive(Clone, Copy, Debug)]
+#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
+#[repr(C)]
+/// Note section contents. Each entry in the note section begins with a header of a fixed form.
+pub struct Nhdr64 {
+    /// Length of the note's name (includes the terminator)
+    pub n_namesz: u64,
+    /// Length of the note's descriptor.
+    pub n_descsz: u64,
+    /// Type of the note.
+    pub n_type: u64,
+}
+
+if_alloc! {
+    use error;
+    use container;
+    use scroll::{ctx, Pread};
+    use alloc::vec::Vec;
+
+    /// An iterator over ELF binary notes in a note section or segment
+    pub struct NoteDataIterator<'a> {
+        pub data: &'a [u8],
+        pub size: usize,
+        pub offset: usize,
+        pub ctx: (usize, container::Ctx), // (alignment, ctx)
+    }
+
+    impl<'a> Iterator for NoteDataIterator<'a> {
+        type Item = error::Result<Note<'a>>;
+        fn next(&mut self) -> Option<Self::Item> {
+            if self.offset >= self.size {
+                None
+            } else {
+                debug!("NoteIterator - {:#x}", self.offset);
+                match self.data.gread_with(&mut self.offset, self.ctx) {
+                    Ok(res) => Some(Ok(res)),
+                    Err(e) => Some(Err(e.into()))
+                }
+            }
+        }
+    }
+
+    /// An iterator over ELF binary notes
+    pub struct NoteIterator<'a> {
+        pub iters: Vec<NoteDataIterator<'a>>,
+        pub index: usize,
+    }
+
+    impl<'a> Iterator for NoteIterator<'a> {
+        type Item = error::Result<Note<'a>>;
+        fn next(&mut self) -> Option<Self::Item> {
+            while self.index < self.iters.len() {
+                if let Some(note_result) = self.iters[self.index].next() {
+                    return Some(note_result);
+                }
+
+                self.index += 1;
+            }
+
+            None
+        }
+    }
+
+    #[derive(Debug)]
+    struct NoteHeader {
+        n_namesz: usize,
+        n_descsz: usize,
+        n_type: u32,
+    }
+
+    impl From<Nhdr32> for NoteHeader {
+        fn from(header: Nhdr32) -> Self {
+            NoteHeader {
+                n_namesz: header.n_namesz as usize,
+                n_descsz: header.n_descsz as usize,
+                n_type: header.n_type,
+            }
+        }
+    }
+
+    impl From<Nhdr64> for NoteHeader {
+        fn from(header: Nhdr64) -> Self {
+            NoteHeader {
+                n_namesz: header.n_namesz as usize,
+                n_descsz: header.n_descsz as usize,
+                n_type: header.n_type as u32,
+            }
+        }
+    }
+
+    fn align(alignment: usize, offset: &mut usize) {
+        let diff = *offset % alignment;
+        if diff != 0 {
+            *offset += alignment - diff;
+        }
+    }
+
+    /// A 32/64 bit Note struct, with the name and desc pre-parsed
+    #[derive(Debug)]
+    pub struct Note<'a> {
+        /// The type of this note
+        pub n_type: u32,
+        /// NUL terminated string, where `namesz` includes the terminator
+        pub name: &'a str, // needs padding such that namesz + padding % {wordsize} == 0
+        /// arbitrary data of length `descsz`
+        pub desc: &'a [u8], // needs padding such that descsz + padding % {wordsize} == 0
+    }
+
+    impl<'a> Note<'a> {
+        pub fn type_to_str(&self) -> &'static str {
+            match self.n_type {
+                NT_GNU_ABI_TAG => "NT_GNU_ABI_TAG",
+                NT_GNU_HWCAP => "NT_GNU_HWCAP",
+                NT_GNU_BUILD_ID => "NT_GNU_BUILD_ID",
+                NT_GNU_GOLD_VERSION => "NT_GNU_GOLD_VERSION",
+                _ => "NT_UNKNOWN"
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, (usize, container::Ctx)> for Note<'a> {
+        type Error = error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], (alignment, ctx): (usize, container::Ctx)) -> Result<(Self, Self::Size), Self::Error> {
+            let offset = &mut 0;
+            let mut alignment = alignment;
+            if alignment < 4 {
+                alignment = 4;
+            }
+            let header: NoteHeader = {
+                match alignment {
+                    4|8 => bytes.gread_with::<Nhdr32>(offset, ctx.le)?.into(),
+                    _ => return Err(error::Error::Malformed(format!("Notes has unimplemented alignment requirement: {:#x}", alignment)))
+                }
+            };
+            debug!("{:?} - {:#x}", header, *offset);
+            // -1 because includes \0 terminator
+            let name = bytes.gread_with::<&'a str>(offset, ctx::StrCtx::Length(header.n_namesz - 1))?;
+            *offset += 1;
+            align(alignment, offset);
+            debug!("note name {} - {:#x}", name, *offset);
+            let desc = bytes.gread_with::<&'a [u8]>(offset, header.n_descsz)?;
+            align(alignment, offset);
+            debug!("desc {:?} - {:#x}", desc, *offset);
+            Ok((Note {
+                name,
+                desc,
+                n_type: header.n_type,
+            }, *offset))
+        }
+    }
+
+    #[cfg(test)]
+    mod tests {
+        use super::*;
+
+        static NOTE_DATA: [u8; 68] = [0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+                                     0x01, 0x00, 0x00, 0x00, 0x47, 0x4e, 0x55, 0x00,
+                                     0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+                                     0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+                                     0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+                                     0x03, 0x00, 0x00, 0x00, 0x47, 0x4e, 0x55, 0x00,
+                                     0xbc, 0xfc, 0x66, 0xcd, 0xc7, 0xd5, 0x14, 0x7b,
+                                     0x53, 0xb1, 0x10, 0x11, 0x94, 0x86, 0x8e, 0xf9,
+                                     0x4f, 0xe8, 0xdd, 0xdb];
+
+        static CONTEXT: (usize, container::Ctx) = (4, container::Ctx {
+            container: container::Container::Big,
+            le: ::scroll::Endian::Little,
+        });
+
+        fn make_note_iter(start: usize, end: usize) -> NoteDataIterator<'static> {
+            NoteDataIterator {
+                data: &NOTE_DATA,
+                size: end,
+                offset: start,
+                ctx: CONTEXT,
+            }
+        }
+
+        #[test]
+        fn iter_single_section() {
+            let mut notes = NoteIterator {
+                iters: vec![make_note_iter(0, 68)],
+                index: 0,
+            };
+
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_ABI_TAG);
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_BUILD_ID);
+            assert!(notes.next().is_none());
+        }
+
+        #[test]
+        fn iter_multiple_sections() {
+            let mut notes = NoteIterator {
+                iters: vec![make_note_iter(0, 32), make_note_iter(32, 68)],
+                index: 0,
+            };
+
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_ABI_TAG);
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_BUILD_ID);
+            assert!(notes.next().is_none());
+        }
+
+        #[test]
+        fn skip_empty_sections() {
+            let mut notes = NoteIterator {
+                iters: vec![
+                    make_note_iter(0, 32),
+                    make_note_iter(0, 0),
+                    make_note_iter(32, 68),
+                ],
+                index: 0,
+            };
+
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_ABI_TAG);
+            assert_eq!(notes.next().unwrap().unwrap().n_type, NT_GNU_BUILD_ID);
+            assert!(notes.next().is_none());
+        }
+
+        #[test]
+        fn ignore_no_sections() {
+            let mut notes = NoteIterator { iters: vec![], index: 0 };
+            assert!(notes.next().is_none());
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/program_header.rs
@@ -0,0 +1,409 @@
+/// Program header table entry unused
+pub const PT_NULL: u32 = 0;
+/// Loadable program segment
+pub const PT_LOAD: u32 = 1;
+/// Dynamic linking information
+pub const PT_DYNAMIC: u32 = 2;
+/// Program interpreter
+pub const PT_INTERP: u32 = 3;
+/// Auxiliary information
+pub const PT_NOTE: u32 = 4;
+/// Reserved
+pub const PT_SHLIB: u32 = 5;
+/// Entry for header table itself
+pub const PT_PHDR: u32 = 6;
+/// Thread-local storage segment
+pub const PT_TLS: u32 = 7;
+/// Number of defined types
+pub const PT_NUM: u32 = 8;
+/// Start of OS-specific
+pub const PT_LOOS: u32 = 0x60000000;
+/// GCC .eh_frame_hdr segment
+pub const PT_GNU_EH_FRAME: u32 = 0x6474e550;
+/// Indicates stack executability
+pub const PT_GNU_STACK: u32 = 0x6474e551;
+/// Read-only after relocation
+pub const PT_GNU_RELRO: u32 = 0x6474e552;
+/// Sun Specific segment
+pub const PT_LOSUNW: u32 = 0x6ffffffa;
+/// Sun Specific segment
+pub const PT_SUNWBSS: u32 = 0x6ffffffa;
+/// Stack segment
+pub const PT_SUNWSTACK: u32 = 0x6ffffffb;
+/// End of OS-specific
+pub const PT_HISUNW: u32 = 0x6fffffff;
+/// End of OS-specific
+pub const PT_HIOS: u32 = 0x6fffffff;
+/// Start of processor-specific
+pub const PT_LOPROC: u32 = 0x70000000;
+/// ARM unwind segment
+pub const PT_ARM_EXIDX: u32 = 0x70000001;
+/// End of processor-specific
+pub const PT_HIPROC: u32 = 0x7fffffff;
+
+/// Segment is executable
+pub const PF_X: u32 = 1 << 0;
+
+/// Segment is writable
+pub const PF_W: u32 = 1 << 1;
+
+/// Segment is readable
+pub const PF_R: u32 = 1 << 2;
+
+pub fn pt_to_str(pt: u32) -> &'static str {
+    match pt {
+        PT_NULL => "PT_NULL",
+        PT_LOAD => "PT_LOAD",
+        PT_DYNAMIC => "PT_DYNAMIC",
+        PT_INTERP => "PT_INTERP",
+        PT_NOTE => "PT_NOTE",
+        PT_SHLIB => "PT_SHLIB",
+        PT_PHDR => "PT_PHDR",
+        PT_TLS => "PT_TLS",
+        PT_NUM => "PT_NUM",
+        PT_LOOS => "PT_LOOS",
+        PT_GNU_EH_FRAME => "PT_GNU_EH_FRAME",
+        PT_GNU_STACK => "PT_GNU_STACK",
+        PT_GNU_RELRO => "PT_GNU_RELRO",
+        PT_SUNWBSS => "PT_SUNWBSS",
+        PT_SUNWSTACK => "PT_SUNWSTACK",
+        PT_HIOS => "PT_HIOS",
+        PT_LOPROC => "PT_LOPROC",
+        PT_HIPROC => "PT_HIPROC",
+        PT_ARM_EXIDX => "PT_ARM_EXIDX",
+        _ => "UNKNOWN_PT",
+    }
+}
+
+if_alloc! {
+    use core::fmt;
+    use scroll::ctx;
+    use core::result;
+    use core::ops::Range;
+    use container::{Ctx, Container};
+    use alloc::vec::Vec;
+
+    #[derive(Default, PartialEq, Clone)]
+    /// A unified ProgramHeader - convertable to and from 32-bit and 64-bit variants
+    pub struct ProgramHeader {
+        pub p_type  : u32,
+        pub p_flags : u32,
+        pub p_offset: u64,
+        pub p_vaddr : u64,
+        pub p_paddr : u64,
+        pub p_filesz: u64,
+        pub p_memsz : u64,
+        pub p_align : u64,
+    }
+
+    impl ProgramHeader {
+        /// Return the size of the underlying program header, given a `Ctx`
+        #[inline]
+        pub fn size(ctx: &Ctx) -> usize {
+            use scroll::ctx::SizeWith;
+            Self::size_with(ctx)
+        }
+        /// Create a new `PT_LOAD` ELF program header
+        pub fn new() -> Self {
+            ProgramHeader {
+                p_type  : PT_LOAD,
+                p_flags : 0,
+                p_offset: 0,
+                p_vaddr : 0,
+                p_paddr : 0,
+                p_filesz: 0,
+                p_memsz : 0,
+                //TODO: check if this is true for 32-bit pt_load
+                p_align : 2 << 20,
+            }
+        }
+        /// Returns this program header's file offset range
+        pub fn file_range(&self) -> Range<usize> {
+            (self.p_offset as usize..self.p_offset as usize + self.p_filesz as usize)
+        }
+        /// Returns this program header's virtual memory range
+        pub fn vm_range(&self) -> Range<usize> {
+            (self.p_vaddr as usize..self.p_vaddr as usize + self.p_memsz as usize)
+        }
+        /// Sets the executable flag
+        pub fn executable(&mut self) {
+            self.p_flags |= PF_X;
+        }
+        /// Sets the write flag
+        pub fn write(&mut self) {
+            self.p_flags |= PF_W;
+        }
+        /// Sets the read flag
+        pub fn read(&mut self) {
+            self.p_flags |= PF_R;
+        }
+        /// Whether this program header is executable
+        pub fn is_executable(&self) -> bool {
+            self.p_flags & PF_X != 0
+        }
+        /// Whether this program header is readable
+        pub fn is_read(&self) -> bool {
+            self.p_flags & PF_R != 0
+        }
+        /// Whether this program header is writable
+        pub fn is_write(&self) -> bool {
+            self.p_flags & PF_W != 0
+        }
+        #[cfg(feature = "endian_fd")]
+        pub fn parse(bytes: &[u8], mut offset: usize, count: usize, ctx: Ctx) -> ::error::Result<Vec<ProgramHeader>> {
+            use scroll::Pread;
+            let mut program_headers = Vec::with_capacity(count);
+            for _ in 0..count {
+                let phdr = bytes.gread_with(&mut offset, ctx)?;
+                program_headers.push(phdr);
+            }
+            Ok(program_headers)
+        }
+    }
+
+    impl fmt::Debug for ProgramHeader {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            write!(f,
+                   "p_type: {} p_flags 0x{:x} p_offset: 0x{:x} p_vaddr: 0x{:x} p_paddr: 0x{:x} \
+                    p_filesz: 0x{:x} p_memsz: 0x{:x} p_align: {}",
+                   pt_to_str(self.p_type),
+                   self.p_flags,
+                   self.p_offset,
+                   self.p_vaddr,
+                   self.p_paddr,
+                   self.p_filesz,
+                   self.p_memsz,
+                   self.p_align)
+        }
+    }
+
+    impl ctx::SizeWith<Ctx> for ProgramHeader {
+        type Units = usize;
+        fn size_with(ctx: &Ctx) -> usize {
+            match ctx.container {
+                Container::Little => {
+                    program_header32::SIZEOF_PHDR
+                },
+                Container::Big => {
+                    program_header64::SIZEOF_PHDR
+                },
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, Ctx> for ProgramHeader {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], Ctx { container, le}: Ctx) -> result::Result<(Self, Self::Size), Self::Error> {
+            use scroll::Pread;
+            let res = match container {
+                Container::Little => {
+                    (bytes.pread_with::<program_header32::ProgramHeader>(0, le)?.into(), program_header32::SIZEOF_PHDR)
+                },
+                Container::Big => {
+                    (bytes.pread_with::<program_header64::ProgramHeader>(0, le)?.into(), program_header64::SIZEOF_PHDR)
+                }
+            };
+            Ok(res)
+        }
+    }
+
+    impl ctx::TryIntoCtx<Ctx> for ProgramHeader {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_into_ctx(self, bytes: &mut [u8], Ctx {container, le}: Ctx) -> result::Result<Self::Size, Self::Error> {
+            use scroll::Pwrite;
+            match container {
+                Container::Little => {
+                    let phdr: program_header32::ProgramHeader = self.into();
+                    Ok(bytes.pwrite_with(phdr, 0, le)?)
+                },
+                Container::Big => {
+                    let phdr: program_header64::ProgramHeader = self.into();
+                    Ok(bytes.pwrite_with(phdr, 0, le)?)
+                }
+            }
+        }
+    }
+} // end if_alloc
+
+macro_rules! elf_program_header_std_impl { ($size:ty) => {
+
+    #[cfg(test)]
+    mod test {
+        use super::*;
+        #[test]
+        fn size_of() {
+            assert_eq!(::std::mem::size_of::<ProgramHeader>(), SIZEOF_PHDR);
+        }
+    }
+
+    if_alloc! {
+
+        use elf::program_header::ProgramHeader as ElfProgramHeader;
+        #[cfg(any(feature = "std", feature = "endian_fd"))]
+        use error::Result;
+
+        use core::slice;
+        use core::fmt;
+
+        use plain::Plain;
+
+        if_std! {
+            use std::fs::File;
+            use std::io::{Seek, Read};
+            use std::io::SeekFrom::Start;
+        }
+
+        impl From<ProgramHeader> for ElfProgramHeader {
+            fn from(ph: ProgramHeader) -> Self {
+                ElfProgramHeader {
+                    p_type   : ph.p_type,
+                    p_flags  : ph.p_flags,
+                    p_offset : ph.p_offset as u64,
+                    p_vaddr  : ph.p_vaddr as u64,
+                    p_paddr  : ph.p_paddr as u64,
+                    p_filesz : ph.p_filesz as u64,
+                    p_memsz  : ph.p_memsz as u64,
+                    p_align  : ph.p_align as u64,
+                }
+            }
+        }
+
+        impl From<ElfProgramHeader> for ProgramHeader {
+            fn from(ph: ElfProgramHeader) -> Self {
+                ProgramHeader {
+                    p_type   : ph.p_type,
+                    p_flags  : ph.p_flags,
+                    p_offset : ph.p_offset as $size,
+                    p_vaddr  : ph.p_vaddr  as $size,
+                    p_paddr  : ph.p_paddr  as $size,
+                    p_filesz : ph.p_filesz as $size,
+                    p_memsz  : ph.p_memsz  as $size,
+                    p_align  : ph.p_align  as $size,
+                }
+            }
+        }
+
+        impl fmt::Debug for ProgramHeader {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                write!(f,
+                       "p_type: {} p_flags 0x{:x} p_offset: 0x{:x} p_vaddr: 0x{:x} p_paddr: 0x{:x} \
+                        p_filesz: 0x{:x} p_memsz: 0x{:x} p_align: {}",
+                       pt_to_str(self.p_type),
+                       self.p_flags,
+                       self.p_offset,
+                       self.p_vaddr,
+                       self.p_paddr,
+                       self.p_filesz,
+                       self.p_memsz,
+                       self.p_align)
+            }
+        }
+
+        impl ProgramHeader {
+            #[cfg(feature = "endian_fd")]
+            pub fn parse(bytes: &[u8], mut offset: usize, count: usize, ctx: ::scroll::Endian) -> Result<Vec<ProgramHeader>> {
+                use scroll::Pread;
+                let mut program_headers = vec![ProgramHeader::default(); count];
+                let offset = &mut offset;
+                bytes.gread_inout_with(offset, &mut program_headers, ctx)?;
+                Ok(program_headers)
+            }
+
+            pub fn from_bytes(bytes: &[u8], phnum: usize) -> Vec<ProgramHeader> {
+                let mut phdrs = vec![ProgramHeader::default(); phnum];
+                phdrs.copy_from_bytes(bytes).expect("buffer is too short for given number of entries");
+                phdrs
+            }
+
+            pub unsafe fn from_raw_parts<'a>(phdrp: *const ProgramHeader,
+                                             phnum: usize)
+                                             -> &'a [ProgramHeader] {
+                slice::from_raw_parts(phdrp, phnum)
+            }
+
+            #[cfg(feature = "std")]
+            pub fn from_fd(fd: &mut File, offset: u64, count: usize) -> Result<Vec<ProgramHeader>> {
+                let mut phdrs = vec![ProgramHeader::default(); count];
+                try!(fd.seek(Start(offset)));
+                unsafe {
+                    try!(fd.read(plain::as_mut_bytes(&mut *phdrs)));
+                }
+                Ok(phdrs)
+            }
+        }
+    } // end if_alloc
+};}
+
+
+pub mod program_header32 {
+    pub use elf::program_header::*;
+
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Default)]
+    #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+    /// A 64-bit ProgramHeader typically specifies how to map executable and data segments into memory
+    pub struct ProgramHeader {
+        /// Segment type
+        pub p_type: u32,
+        /// Segment file offset
+        pub p_offset: u32,
+        /// Segment virtual address
+        pub p_vaddr: u32,
+        /// Segment physical address
+        pub p_paddr: u32,
+        /// Segment size in file
+        pub p_filesz: u32,
+        /// Segment size in memory
+        pub p_memsz: u32,
+        /// Segment flags
+        pub p_flags: u32,
+        /// Segment alignment
+        pub p_align: u32,
+    }
+
+    pub const SIZEOF_PHDR: usize = 32;
+
+    use plain;
+    // Declare that this is a plain type.
+    unsafe impl plain::Plain for ProgramHeader {}
+
+    elf_program_header_std_impl!(u32);
+}
+
+
+pub mod program_header64 {
+    pub use elf::program_header::*;
+
+    #[repr(C)]
+    #[derive(Copy, Clone, PartialEq, Default)]
+    #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+    /// A 32-bit ProgramHeader typically specifies how to map executable and data segments into memory
+    pub struct ProgramHeader {
+        /// Segment type
+        pub p_type: u32,
+        /// Segment flags
+        pub p_flags: u32,
+        /// Segment file offset
+        pub p_offset: u64,
+        /// Segment virtual address
+        pub p_vaddr: u64,
+        /// Segment physical address
+        pub p_paddr: u64,
+        /// Segment size in file
+        pub p_filesz: u64,
+        /// Segment size in memory
+        pub p_memsz: u64,
+        /// Segment alignment
+        pub p_align: u64,
+    }
+
+    pub const SIZEOF_PHDR: usize = 56;
+
+    use plain;
+    // Declare that this is a plain type.
+    unsafe impl plain::Plain for ProgramHeader {}
+
+    elf_program_header_std_impl!(u64);
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/reloc.rs
@@ -0,0 +1,394 @@
+//! # Relocation computations
+//! Below are some common x86_64 relocation computations you might find useful:
+//!
+//! | Relocation | Value | Size | Formula |
+//! |:-----------|:------|:-----|:-------|
+//! | R_X86_64_NONE | 0 | none | none |
+//! | R_X86_64_64 | 1 | word64 | S + A |
+//! | R_X86_64_PC32 | 2 | word32 | S + A - P |
+//! | R_X86_64_GOT32 | 3 | word32 | G + A |
+//! | R_X86_64_PLT32 | 4 | word32 | L + A - P |
+//! | R_X86_64_COPY | 5 | none | none |
+//! | R_X86_64_GLOB_DAT | 6 | word64 | S |
+//! | R_X86_64_JUMP_SLOT | 7 | word64 | S |
+//! | R_X86_64_RELATIVE | 8 | word64 | B + A |
+//! | R_X86_64_GOTPCREL | 9 | word32 | G + GOT + A - P |
+//! | R_X86_64_32 | 10 | word32 | S + A |
+//! | R_X86_64_32S | 11 | word32 | S + A |
+//! | R_X86_64_16 | 12 | word16 | S + A |
+//! | R_X86_64_PC16 | 13 | word16 | S + A - P |
+//! | R_X86_64_8 | 14 | word8 | S + A |
+//! | R_X86_64_PC8 | 15 | word8 | S + A - P |
+//! | R_X86_64_DTPMOD64 | 16 | word64 | |
+//! | R_X86_64_DTPOFF64 | 17 | word64 | |
+//! | R_X86_64_TPOFF64 | 18 | word64 | |
+//! | R_X86_64_TLSGD | 19 | word32 | |
+//! | R_X86_64_TLSLD | 20 | word32 | |
+//! | R_X86_64_DTPOFF32 | 21 | word32 | |
+//! | R_X86_64_GOTTPOFF | 22 | word32 | |
+//! | R_X86_64_TPOFF32 | 23 | word32 | |
+//! | R_X86_64_PC64 | 24 | word64 | S + A - P |
+//! | R_X86_64_GOTOFF64 | 25 | word64 | S + A - GOT |
+//! | R_X86_64_GOTPC32 | 26 | word32 | GOT + A - P |
+//! | R_X86_64_SIZE32 | 32 | word32 | Z + A |
+//! | R_X86_64_SIZE64 | 33 | word64 | Z + A |
+//! | R_X86_64_GOTPC32_TLSDESC | 34 | word32 | |
+//! | R_X86_64_TLSDESC_CALL | 35 | none| |
+//! | R_X86_64_TLSDESC | 36 | word64×2 | |
+//! | R_X86_64_IRELATIVE | 37 | word64 | indirect (B + A) |
+//!
+//! TLS information is at http://people.redhat.com/aoliva/writeups/TLS/RFC-TLSDESC-x86.txt
+//!
+//! `R_X86_64_IRELATIVE` is similar to `R_X86_64_RELATIVE` except that
+//! the value used in this relocation is the program address returned by the function,
+//! which takes no arguments, at the address of the result of the corresponding
+//! `R_X86_64_RELATIVE` relocation.
+
+include!("constants_relocation.rs");
+
+macro_rules! elf_reloc {
+    ($size:ident, $isize:ty) => {
+        use core::fmt;
+        #[repr(C)]
+        #[derive(Clone, Copy, PartialEq, Default)]
+        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+        /// Relocation with an explicit addend
+        pub struct Rela {
+            /// Address
+            pub r_offset: $size,
+            /// Relocation type and symbol index
+            pub r_info: $size,
+            /// Addend
+            pub r_addend: $isize,
+        }
+        #[repr(C)]
+        #[derive(Clone, PartialEq, Default)]
+        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+        /// Relocation without an addend
+        pub struct Rel {
+            /// address
+            pub r_offset: $size,
+            /// relocation type and symbol address
+            pub r_info: $size,
+        }
+        use plain;
+        unsafe impl plain::Plain for Rela {}
+        unsafe impl plain::Plain for Rel {}
+
+        impl fmt::Debug for Rela {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                let sym = r_sym(self.r_info);
+                let typ = r_type(self.r_info);
+                write!(f,
+                       "r_offset: {:x} r_typ: {} r_sym: {} r_addend: {:x}",
+                       self.r_offset,
+                       typ,
+                       sym,
+                       self.r_addend)
+            }
+        }
+        impl fmt::Debug for Rel {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                let sym = r_sym(self.r_info);
+                let typ = r_type(self.r_info);
+                write!(f,
+                       "r_offset: {:x} r_typ: {} r_sym: {}",
+                       self.r_offset,
+                       typ,
+                       sym
+                )
+            }
+        }
+    };
+}
+
+macro_rules! elf_rela_std_impl { ($size:ident, $isize:ty) => {
+
+    if_alloc! {
+            use elf::reloc::Reloc;
+
+            use core::slice;
+
+            if_std! {
+                use error::Result;
+
+                use std::fs::File;
+                use std::io::{Read, Seek};
+                use std::io::SeekFrom::Start;
+            }
+
+            impl From<Rela> for Reloc {
+                fn from(rela: Rela) -> Self {
+                    Reloc {
+                        r_offset: rela.r_offset as u64,
+                        r_addend: Some(rela.r_addend as i64),
+                        r_sym: r_sym(rela.r_info) as usize,
+                        r_type: r_type(rela.r_info),
+                    }
+                }
+            }
+
+            impl From<Rel> for Reloc {
+                fn from(rel: Rel) -> Self {
+                    Reloc {
+                        r_offset: rel.r_offset as u64,
+                        r_addend: None,
+                        r_sym: r_sym(rel.r_info) as usize,
+                        r_type: r_type(rel.r_info),
+                    }
+                }
+            }
+
+            impl From<Reloc> for Rela {
+                fn from(rela: Reloc) -> Self {
+                    let r_info = r_info(rela.r_sym as $size, rela.r_type as $size);
+                    Rela {
+                        r_offset: rela.r_offset as $size,
+                        r_info: r_info,
+                        r_addend: rela.r_addend.unwrap_or(0) as $isize,
+                    }
+                }
+            }
+
+            impl From<Reloc> for Rel {
+                fn from(rel: Reloc) -> Self {
+                    let r_info = r_info(rel.r_sym as $size, rel.r_type as $size);
+                    Rel {
+                        r_offset: rel.r_offset as $size,
+                        r_info: r_info,
+                    }
+                }
+            }
+
+            /// Gets the rela entries given a rela pointer and the _size_ of the rela section in the binary,
+            /// in bytes.
+            /// Assumes the pointer is valid and can safely return a slice of memory pointing to the relas because:
+            /// 1. `ptr` points to memory received from the kernel (i.e., it loaded the executable), _or_
+            /// 2. The binary has already been mmapped (i.e., it's a `SharedObject`), and hence it's safe to return a slice of that memory.
+            /// 3. Or if you obtained the pointer in some other lawful manner
+            pub unsafe fn from_raw_rela<'a>(ptr: *const Rela, size: usize) -> &'a [Rela] {
+                slice::from_raw_parts(ptr, size / SIZEOF_RELA)
+            }
+
+            /// Gets the rel entries given a rel pointer and the _size_ of the rel section in the binary,
+            /// in bytes.
+            /// Assumes the pointer is valid and can safely return a slice of memory pointing to the rels because:
+            /// 1. `ptr` points to memory received from the kernel (i.e., it loaded the executable), _or_
+            /// 2. The binary has already been mmapped (i.e., it's a `SharedObject`), and hence it's safe to return a slice of that memory.
+            /// 3. Or if you obtained the pointer in some other lawful manner
+            pub unsafe fn from_raw_rel<'a>(ptr: *const Rel, size: usize) -> &'a [Rel] {
+                slice::from_raw_parts(ptr, size / SIZEOF_REL)
+            }
+
+            #[cfg(feature = "std")]
+            pub fn from_fd(fd: &mut File, offset: usize, size: usize) -> Result<Vec<Rela>> {
+                let count = size / SIZEOF_RELA;
+                let mut relocs = vec![Rela::default(); count];
+                fd.seek(Start(offset as u64))?;
+                unsafe {
+                    fd.read(plain::as_mut_bytes(&mut *relocs))?;
+                }
+                Ok(relocs)
+            }
+        } // end if_alloc
+    };
+}
+
+
+pub mod reloc32 {
+
+    pub use elf::reloc::*;
+
+    elf_reloc!(u32, i32);
+
+    pub const SIZEOF_RELA: usize = 4 + 4 + 4;
+    pub const SIZEOF_REL: usize = 4 + 4;
+
+    #[inline(always)]
+    pub fn r_sym(info: u32) -> u32 {
+        info >> 8
+    }
+
+    #[inline(always)]
+    pub fn r_type(info: u32) -> u32 {
+        info & 0xff
+    }
+
+    #[inline(always)]
+    pub fn r_info(sym: u32, typ: u32) -> u32 {
+        (sym << 8) + (typ & 0xff)
+    }
+
+    elf_rela_std_impl!(u32, i32);
+}
+
+
+pub mod reloc64 {
+    pub use elf::reloc::*;
+
+    elf_reloc!(u64, i64);
+
+    pub const SIZEOF_RELA: usize = 8 + 8 + 8;
+    pub const SIZEOF_REL: usize = 8 + 8;
+
+    #[inline(always)]
+    pub fn r_sym(info: u64) -> u32 {
+        (info >> 32) as u32
+    }
+
+    #[inline(always)]
+    pub fn r_type(info: u64) -> u32 {
+        (info & 0xffffffff) as u32
+    }
+
+    #[inline(always)]
+    pub fn r_info(sym: u64, typ: u64) -> u64 {
+        (sym << 32) + typ
+    }
+
+    elf_rela_std_impl!(u64, i64);
+}
+
+//////////////////////////////
+// Generic Reloc
+/////////////////////////////
+if_alloc! {
+    use core::fmt;
+    use core::result;
+    use scroll::ctx;
+    use container::{Ctx, Container};
+    #[cfg(feature = "endian_fd")]
+    use alloc::vec::Vec;
+
+    #[derive(Clone, Copy, PartialEq, Default)]
+    /// A unified ELF relocation structure
+    pub struct Reloc {
+        /// Address
+        pub r_offset: u64,
+        /// Addend
+        pub r_addend: Option<i64>,
+        /// The index into the corresponding symbol table - either dynamic or regular
+        pub r_sym: usize,
+        /// The relocation type
+        pub r_type: u32,
+    }
+
+    impl Reloc {
+        pub fn size(is_rela: bool, ctx: Ctx) -> usize {
+            use scroll::ctx::SizeWith;
+            Reloc::size_with(&(is_rela, ctx))
+        }
+        #[cfg(feature = "endian_fd")]
+        pub fn parse(bytes: &[u8], mut offset: usize, filesz: usize, is_rela: bool, ctx: Ctx) -> ::error::Result<Vec<Reloc>> {
+            use scroll::Pread;
+            let count = filesz / Reloc::size(is_rela, ctx);
+            let mut relocs = Vec::with_capacity(count);
+            let offset = &mut offset;
+            for _ in 0..count {
+                let reloc = bytes.gread_with::<Reloc>(offset, (is_rela, ctx))?;
+                relocs.push(reloc);
+            }
+            Ok(relocs)
+        }
+    }
+
+    type RelocCtx = (bool, Ctx);
+
+    impl ctx::SizeWith<RelocCtx> for Reloc {
+        type Units = usize;
+        fn size_with( &(is_rela, Ctx { container, .. }): &RelocCtx) -> Self::Units {
+            match container {
+                Container::Little => {
+                    if is_rela { reloc32::SIZEOF_RELA } else { reloc32::SIZEOF_REL }
+                },
+                Container::Big => {
+                    if is_rela { reloc64::SIZEOF_RELA } else { reloc64::SIZEOF_REL }
+                }
+            }
+        }
+    }
+
+    impl<'a> ctx::TryFromCtx<'a, RelocCtx> for Reloc {
+        type Error = ::error::Error;
+        type Size = usize;
+        fn try_from_ctx(bytes: &'a [u8], (is_rela, Ctx { container, le }): RelocCtx) -> result::Result<(Self, Self::Size), Self::Error> {
+            use scroll::Pread;
+            let reloc = match container {
+                Container::Little => {
+                    if is_rela {
+                        (bytes.pread_with::<reloc32::Rela>(0, le)?.into(), reloc32::SIZEOF_RELA)
+                    } else {
+                        (bytes.pread_with::<reloc32::Rel>(0, le)?.into(), reloc32::SIZEOF_REL)
+                    }
+                },
+                Container::Big => {
+                    if is_rela {
+                        (bytes.pread_with::<reloc64::Rela>(0, le)?.into(), reloc64::SIZEOF_RELA)
+                    } else {
+                        (bytes.pread_with::<reloc64::Rel>(0, le)?.into(), reloc64::SIZEOF_REL)
+                    }
+                }
+            };
+            Ok(reloc)
+        }
+    }
+
+    impl ctx::TryIntoCtx<RelocCtx> for Reloc {
+        type Error = ::error::Error;
+        type Size = usize;
+        // TODO: I think this is a bad idea
+        /// Writes the relocation into `bytes`
+        fn try_into_ctx(self, bytes: &mut [u8], (is_rela, Ctx {container, le}): RelocCtx) -> result::Result<Self::Size, Self::Error> {
+            use scroll::Pwrite;
+            match container {
+                Container::Little => {
+                    if is_rela {
+                        let rela: reloc32::Rela = self.into();
+                        Ok(bytes.pwrite_with(rela, 0, le)?)
+                    } else {
+                        let rel: reloc32::Rel = self.into();
+                        Ok(bytes.pwrite_with(rel, 0, le)?)
+                    }
+                },
+                Container::Big => {
+                    if is_rela {
+                        let rela: reloc64::Rela = self.into();
+                        Ok(bytes.pwrite_with(rela, 0, le)?)
+                    } else {
+                        let rel: reloc64::Rel = self.into();
+                        Ok(bytes.pwrite_with(rel, 0, le)?)
+                    }
+                },
+            }
+        }
+    }
+
+    impl ctx::IntoCtx<(bool, Ctx)> for Reloc {
+        /// Writes the relocation into `bytes`
+        fn into_ctx(self, bytes: &mut [u8], ctx: RelocCtx) {
+            use scroll::Pwrite;
+            bytes.pwrite_with(self, 0, ctx).unwrap();
+        }
+    }
+
+    impl fmt::Debug for Reloc {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            if let Some(addend) = self.r_addend {
+                write!(f,
+                    "r_offset: {:x} r_typ: {} r_sym: {} r_addend: {:x}",
+                    self.r_offset,
+                    self.r_type,
+                    self.r_sym,
+                    addend,
+                )
+            } else {
+                write!(f,
+                    "r_offset: {:x} r_typ: {} r_sym: {}",
+                    self.r_offset,
+                    self.r_type,
+                    self.r_sym,
+                )
+            }
+        }
+    }
+} // end if_alloc
new file mode 100644
--- /dev/null
+++ b/third_party/rust/goblin/src/elf/section_header.rs
@@ -0,0 +1,547 @@
+macro_rules! elf_section_header {
+    ($size:ident) => {
+        #[repr(C)]
+        #[derive(Copy, Clone, Eq, PartialEq, Default)]
+        #[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
+        /// Section Headers are typically used by humans and static linkers for additional information or how to relocate the object
+        ///
+        /// **NOTE** section headers are strippable from a binary without any loss of portability/executability; _do not_ rely on them being there!
+        pub struct SectionHeader {
+            /// Section name (string tbl index)
+            pub sh_name: u32,
+            /// Section type
+            pub sh_type: u32,
+            /// Section flags
+            pub sh_flags: $size,
+            /// Section virtual addr at execution
+            pub sh_addr: $size,
+            /// Section file offset
+            pub sh_offset: $size,
+            /// Section size in bytes
+            pub sh_size: $size,
+            /// Link to another section
+            pub sh_link: u32,
+            /// Additional section information
+            pub sh_info: u32,
+            /// Section alignment
+            pub sh_addralign: $size,
+            /// Entry size if section holds table
+            pub sh_entsize: $size,
+        }
+
+        use plain;
+        // Declare that this is a plain type.
+        unsafe impl plain::Plain for SectionHeader {}
+
+        impl ::core::fmt::Debug for SectionHeader {
+            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
+                write!(f,
+                       "sh_name: {} sh_type {} sh_flags: 0x{:x} sh_addr: 0x{:x} sh_offset: 0x{:x} \
+                        sh_size: 0x{:x} sh_link: 0x{:x} sh_info: 0x{:x} sh_addralign 0x{:x} sh_entsize 0x{:x}",
+                       self.sh_name,
+                       sht_to_str(self.sh_type as u32),
+                       self.sh_flags,
+                       self.sh_addr,
+                       self.sh_offset,
+                       self.sh_size,
+                       self.sh_link,
+                       self.sh_info,
+                       self.sh_addralign,
+                       self.sh_entsize)
+            }
+        }
+    }
+}
+
+/// Undefined section.
+pub const SHN_UNDEF: u32 = 0;
+/// Start of reserved indices.
+pub const SHN_LORESERVE: u32 = 0xff00;
+/// Start of processor-specific.
+pub const SHN_LOPROC: u32 = 0xff00;
+/// Order section before all others (Solaris).
+pub const SHN_BEFORE: u32 = 0xff00;
+/// Order section after all others (Solaris).
+pub const SHN_AFTER: u32 = 0xff01;
+/// End of processor-specific.
+pub const SHN_HIPROC: u32 = 0xff1f;
+/// Start of OS-specific.
+pub const SHN_LOOS: u32 = 0xff20;
+/// End of OS-specific.
+pub const SHN_HIOS: u32 = 0xff3f;
+/// Associated symbol is absolute.
+pub const SHN_ABS: u32 = 0xfff1;
+/// Associated symbol is common.
+pub const SHN_COMMON: u32 = 0xfff2;
+/// Index is in extra table.
+pub const SHN_XINDEX: u32 = 0xffff;
+/// End of reserved indices.
+pub const SHN_HIRESERVE: u32 = 0xffff;
+
+// === Legal values for sh_type (section type). ===
+/// Section header table entry unused.
+pub const SHT_NULL: u32 = 0;
+/// Program data.
+pub const SHT_PROGBITS: u32 = 1;
+/// Symbol table.
+pub const SHT_SYMTAB: u32 = 2;
+/// String table.
+pub const SHT_STRTAB: u32 = 3;
+/// Relocation entries with addends.
+pub const SHT_RELA: u32 = 4;
+/// Symbol hash table.
+pub const SHT_HASH: u32 = 5;
+/// Dynamic linking information.
+pub const SHT_DYNAMIC: u32 = 6;
+/// Notes.
+pub const SHT_NOTE: u32 = 7;
+/// Program space with no data (bss).
+pub const SHT_NOBITS: u32 = 8;
+/// Relocation entries, no addends.
+pub const SHT_REL: u32 = 9;
+/// Reserved.
+pub const SHT_SHLIB: u32 = 10;
+/// Dynamic linker symbol table.
+pub const SHT_DYNSYM: u32 = 11;
+/// Array of constructors.
+pub const SHT_INIT_ARRAY: u32 = 14;
+/// Array of destructors.
+pub const SHT_FINI_ARRAY: u32 = 15;
+/// Array of pre-constructors.
+pub const SHT_PREINIT_ARRAY: u32 = 16;
+/// Section group.
+pub const SHT_GROUP: u32 = 17;
+/// Extended section indeces.
+pub const SHT_SYMTAB_SHNDX: u32 = 18;
+/// Number of defined types.
+pub const SHT_NUM: u32 = 19;
+/// Start OS-specific.
+pub const SHT_LOOS: u32 = 0x60000000;
+/// Object attributes.
+pub const SHT_GNU_ATTRIBUTES: u32 = 0x6ffffff5;
+/// GNU-style hash table.
+pub const SHT_GNU_HASH: u32 = 0x6ffffff6;
+/// Prelink library list.
+pub const SHT_GNU_LIBLIST: u32 = 0x6ffffff7;
+/// Checksum for DSO content.
+pub const SHT_CHECKSUM: u32 = 0x6ffffff8;
+/// Sun-specific low bound.
+pub const SHT_LOSUNW: u32 = 0x6ffffffa;
+pub const SHT_SUNW_MOVE: u32 = 0x6ffffffa;
+pub const SHT_SUNW_COMDAT: u32 = 0x6ffffffb;
+pub const SHT_SUNW_SYMINFO: u32 = 0x6ffffffc;
+/// Version definition section.
+pub const SHT_GNU_VERDEF: u32 = 0x6ffffffd;
+/// Version needs section.
+pub const SHT_GNU_VERNEED: u32 = 0x6ffffffe;
+/// Version symbol table.
+pub const SHT_GNU_VERSYM: u32 = 0x6fffffff;
+/// Sun-specific high bound.
+pub const SHT_HISUNW: u32 = 0x6fffffff;
+/// End OS-specific type.
+pub const SHT_HIOS: u32 = 0x6fffffff;
+/// Start of processor-specific.
+pub const SHT_LOPROC: u32 = 0x70000000;
+/// End of processor-specific.
+pub const SHT_HIPROC: u32 = 0x7fffffff;
+/// Start of application-specific.
+pub const SHT_LOUSER: u32 = 0x80000000;
+/// End of application-specific.
+pub const SHT_HIUSER: u32 = 0x8fffffff;
+
+// Legal values for sh_flags (section flags)
+/// Writable.
+pub const SHF_WRITE: u32 = 0x1;
+/// Occupies memory during execution.
+pub const SHF_ALLOC: u32 = 0x2;
+/// Executable.
+pub const SHF_EXECINSTR: u32 = 0x4;
+/// Might be merged.
+pub const SHF_MERGE: u32 = 0x10;
+/// Contains nul-terminated strings.
+pub const SHF_STRINGS: u32 = 0x20;
+/// `sh_info' contains SHT index.
+pub const SHF_INFO_LINK: u32 = 0x40;
+/// Preserve order after combining.
+pub const SHF_LINK_ORDER: u32 = 0x80;
+/// Non-standard OS specific handling required.
+pub const SHF_OS_NONCONFORMING: u32 = 0x100;
+/// Section is member of a group.
+pub const SHF_GROUP: u32 = 0x200;
+/// Section hold thread-local data.
+pub const SHF_TLS: u32 = 0x400;
+/// Section with compressed data.
+pub const SHF_COMPRESSED: u32 = 0x800;
+/// OS-specific..
+pub const SHF_MASKOS: u32 = 0x0ff00000;
+/// Processor-specific.
+pub const SHF_MASKPROC: u32 = 0xf0000000;
+/// Special ordering requirement (Solaris).
+pub const SHF_ORDERED: u32 = 1 << 30;
+/// Number of "regular" section header flags
+pub const SHF_NUM_REGULAR_FLAGS: usize = 12;
+// /// Section is excluded unless referenced or allocated (Solaris).
+// pub const SHF_EXCLUDE: u32 = 1U << 31;
+
+pub const SHF_FLAGS: [u32; SHF_NUM_REGULAR_FLAGS] = [
+    SHF_WRITE,
+    SHF_ALLOC,
+    SHF_EXECINSTR,
+    SHF_MERGE,
+    SHF_STRINGS,
+    SHF_INFO_LINK,
+    SHF_LINK_ORDER,
+    SHF_OS_NONCONFORMING,
+    SHF_GROUP,
+    SHF_TLS,
+    SHF_COMPRESSED,
+    SHF_ORDERED,
+];
+
+pub fn sht_to_str(sht: u32) -> &'static str {
+    match sht {
+        SHT_NULL => "SHT_NULL",
+        SHT_PROGBITS => "SHT_PROGBITS",