Write .splitmeta section in split objects
This enables showing the original address of symbols in objdiff, as well as `elf disasm` on split objects retaining the original addresses.
This commit is contained in:
parent
a2cae4f82a
commit
4f8a9e6fab
|
@ -49,9 +49,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
|
@ -80,7 +80,7 @@ dependencies = [
|
|||
"argh_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -187,6 +187,16 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "542f33a8835a0884b006a0c3df3dadd99c0c3f296ed26c2fdc8028e01ad6230c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
@ -320,6 +330,7 @@ dependencies = [
|
|||
"multimap",
|
||||
"nintendo-lz",
|
||||
"num_enum",
|
||||
"objdiff-core",
|
||||
"object",
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
|
@ -397,14 +408,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -469,6 +480,20 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"log",
|
||||
"regex-automata 0.4.3",
|
||||
"regex-syntax 0.8.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.2"
|
||||
|
@ -507,9 +532,9 @@ checksum = "d9f1a0777d972970f204fdf8ef319f1f4f8459131636d7e3c96c5d59570d0fa6"
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
version = "2.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
checksum = "967d6dd42f16dbf0eb8040cb9e477933562684d3918f7d253f2ff9087fb3e7a3"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
|
@ -555,9 +580,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
|
@ -588,9 +613,9 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
|||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.0"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375"
|
||||
checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -644,9 +669,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -669,14 +694,37 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-core"
|
||||
version = "1.0.0"
|
||||
source = "git+https://github.com/encounter/objdiff?rev=5b9ac93c084bd0a9ae710e8c8195c4b0db939b8a#5b9ac93c084bd0a9ae710e8c8195c4b0db939b8a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"byteorder",
|
||||
"cwdemangle",
|
||||
"filetime",
|
||||
"flagset",
|
||||
"globset",
|
||||
"log",
|
||||
"memmap2",
|
||||
"num-traits",
|
||||
"object",
|
||||
"ppc750cl",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"similar",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.1"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"hashbrown",
|
||||
|
@ -775,9 +823,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
@ -796,9 +844,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -825,9 +873,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
@ -935,30 +983,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.192"
|
||||
name = "semver"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.192"
|
||||
version = "1.0.197"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.108"
|
||||
version = "1.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -973,14 +1027,14 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.27"
|
||||
version = "0.9.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c"
|
||||
checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
|
@ -1009,6 +1063,12 @@ dependencies = [
|
|||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.2"
|
||||
|
@ -1054,9 +1114,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
version = "2.0.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1108,7 +1168,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1157,7 +1217,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1312,7 +1372,16 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1330,6 +1399,21 @@ dependencies = [
|
|||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.4",
|
||||
"windows_aarch64_msvc 0.52.4",
|
||||
"windows_i686_gnu 0.52.4",
|
||||
"windows_i686_msvc 0.52.4",
|
||||
"windows_x86_64_gnu 0.52.4",
|
||||
"windows_x86_64_gnullvm 0.52.4",
|
||||
"windows_x86_64_msvc 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -1342,6 +1426,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1354,6 +1444,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -1366,6 +1462,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1378,6 +1480,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
|
@ -1390,6 +1498,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
|
@ -1402,6 +1516,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
|
@ -1414,6 +1534,12 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.19"
|
||||
|
@ -1446,5 +1572,5 @@ checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
"syn 2.0.52",
|
||||
]
|
||||
|
|
|
@ -47,6 +47,7 @@ memmap2 = "0.9.0"
|
|||
multimap = "0.9.1"
|
||||
nintendo-lz = "0.1.3"
|
||||
num_enum = "0.7.1"
|
||||
objdiff-core = { git = "https://github.com/encounter/objdiff", rev = "5b9ac93c084bd0a9ae710e8c8195c4b0db939b8a", features = ["ppc"] }
|
||||
object = { version = "0.32.1", features = ["read_core", "std", "elf", "write_std"], default-features = false }
|
||||
once_cell = "1.18.0"
|
||||
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
|
||||
|
|
|
@ -836,7 +836,8 @@ fn split_write_obj(
|
|||
}
|
||||
|
||||
debug!("Splitting {} objects", module.obj.link_order.len());
|
||||
let split_objs = split_obj(&module.obj)?;
|
||||
let module_name = module.config.name().to_string();
|
||||
let split_objs = split_obj(&module.obj, Some(module_name.as_str()))?;
|
||||
|
||||
debug!("Writing object files");
|
||||
DirBuilder::new()
|
||||
|
@ -855,7 +856,7 @@ fn split_write_obj(
|
|||
module.obj.symbols.by_name("_prolog")?.map(|(_, s)| s.name.clone())
|
||||
};
|
||||
let mut out_config = OutputModule {
|
||||
name: module.config.name().to_string(),
|
||||
name: module_name,
|
||||
module_id,
|
||||
ldscript: out_dir.join("ldscript.lcf"),
|
||||
units: Vec::with_capacity(split_objs.len()),
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::{
|
|||
|
||||
use anyhow::{anyhow, bail, ensure, Context, Result};
|
||||
use argp::FromArgs;
|
||||
use objdiff_core::obj::split_meta::{SplitMeta, SPLITMETA_SECTION};
|
||||
use object::{
|
||||
elf,
|
||||
write::{Mangling, SectionId, SymbolId},
|
||||
|
@ -148,7 +149,7 @@ fn disasm(args: DisasmArgs) -> Result<()> {
|
|||
match obj.kind {
|
||||
ObjKind::Executable => {
|
||||
log::info!("Splitting {} objects", obj.link_order.len());
|
||||
let split_objs = split_obj(&obj)?;
|
||||
let split_objs = split_obj(&obj, None)?;
|
||||
|
||||
let asm_dir = args.out.join("asm");
|
||||
let include_dir = args.out.join("include");
|
||||
|
@ -183,7 +184,7 @@ fn split(args: SplitArgs) -> Result<()> {
|
|||
|
||||
let mut file_map = HashMap::<String, Vec<u8>>::new();
|
||||
|
||||
let split_objs = split_obj(&obj)?;
|
||||
let split_objs = split_obj(&obj, None)?;
|
||||
for (unit, split_obj) in obj.link_order.iter().zip(&split_objs) {
|
||||
let out_obj = write_elf(split_obj, false)?;
|
||||
match file_map.entry(unit.name.clone()) {
|
||||
|
@ -596,5 +597,27 @@ fn info(args: InfoArgs) -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(split_meta_section) = in_file.section_by_name(SPLITMETA_SECTION) {
|
||||
let data = split_meta_section.uncompressed_data()?;
|
||||
if !data.is_empty() {
|
||||
let meta =
|
||||
SplitMeta::from_reader(&mut data.as_ref(), in_file.endianness(), in_file.is_64())
|
||||
.context("While reading .splitmeta section")?;
|
||||
println!("\nSplit metadata (.splitmeta):");
|
||||
if let Some(generator) = &meta.generator {
|
||||
println!("\tGenerator: {}", generator);
|
||||
}
|
||||
if let Some(virtual_addresses) = &meta.virtual_addresses {
|
||||
println!("\tVirtual addresses:");
|
||||
println!("\t{: >10} | {: <10}", "Addr", "Symbol");
|
||||
for (symbol, addr) in in_file.symbols().zip(virtual_addresses) {
|
||||
if symbol.is_definition() {
|
||||
println!("\t{: >10} | {: <10}", format!("{:#X}", addr), symbol.name()?);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -485,7 +485,7 @@ fn merge(args: MergeArgs) -> Result<()> {
|
|||
align: mod_section.align,
|
||||
elf_index: mod_section.elf_index,
|
||||
relocations: Default::default(),
|
||||
original_address: mod_section.original_address,
|
||||
virtual_address: mod_section.virtual_address,
|
||||
file_offset: mod_section.file_offset,
|
||||
section_known: mod_section.section_known,
|
||||
splits: mod_section.splits.clone(),
|
||||
|
|
|
@ -100,7 +100,7 @@ enum SubCommand {
|
|||
// Duplicated from supports-color so we can check early.
|
||||
fn env_no_color() -> bool {
|
||||
match env::var("NO_COLOR").as_deref() {
|
||||
Ok("0") | Err(_) => false,
|
||||
Ok("") | Ok("0") | Err(_) => false,
|
||||
Ok(_) => true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::{anyhow, bail, ensure, Result};
|
||||
use objdiff_core::obj::split_meta::SplitMeta;
|
||||
pub use relocations::{ObjReloc, ObjRelocKind, ObjRelocations};
|
||||
pub use sections::{ObjSection, ObjSectionKind, ObjSections};
|
||||
pub use splits::{ObjSplit, ObjSplits};
|
||||
|
@ -55,6 +56,7 @@ pub struct ObjInfo {
|
|||
pub sections: ObjSections,
|
||||
pub entry: Option<u64>,
|
||||
pub mw_comment: Option<MWComment>,
|
||||
pub split_meta: Option<SplitMeta>,
|
||||
|
||||
// Linker generated
|
||||
pub sda2_base: Option<u32>,
|
||||
|
@ -94,6 +96,7 @@ impl ObjInfo {
|
|||
sections: ObjSections::new(kind, sections),
|
||||
entry: None,
|
||||
mw_comment: Default::default(),
|
||||
split_meta: None,
|
||||
sda2_base: None,
|
||||
sda_base: None,
|
||||
stack_address: None,
|
||||
|
|
|
@ -28,7 +28,7 @@ pub struct ObjSection {
|
|||
/// REL files reference the original ELF section indices
|
||||
pub elf_index: usize,
|
||||
pub relocations: ObjRelocations,
|
||||
pub original_address: u64,
|
||||
pub virtual_address: Option<u64>,
|
||||
pub file_offset: u64,
|
||||
pub section_known: bool,
|
||||
pub splits: ObjSplits,
|
||||
|
|
|
@ -89,7 +89,7 @@ where W: Write + ?Sized {
|
|||
.or_else(|| vec.iter().find(|e| e.kind == SymbolEntryKind::Start))
|
||||
.map(|e| e.index);
|
||||
if target_symbol_idx.is_none() {
|
||||
let display_address = address as u64 + section.original_address;
|
||||
let display_address = address as u64 + section.virtual_address.unwrap_or(0);
|
||||
let symbol_idx = symbols.len();
|
||||
symbols.push(ObjSymbol {
|
||||
name: format!(".L_{display_address:08X}"),
|
||||
|
@ -148,7 +148,7 @@ where W: Write + ?Sized {
|
|||
.iter()
|
||||
.any(|e| e.kind == SymbolEntryKind::Label || e.kind == SymbolEntryKind::Start)
|
||||
{
|
||||
let display_address = address + target_section.original_address;
|
||||
let display_address = address + target_section.virtual_address.unwrap_or(0);
|
||||
let symbol_idx = symbols.len();
|
||||
symbols.push(ObjSymbol {
|
||||
name: format!(".L_{display_address:08X}"),
|
||||
|
@ -246,7 +246,7 @@ where
|
|||
for ins in disasm_iter(data, address) {
|
||||
let reloc = relocations.get(&ins.addr);
|
||||
let file_offset = section.file_offset + (ins.addr as u64 - section.address);
|
||||
write_ins(w, symbols, ins, reloc, file_offset, section.original_address)?;
|
||||
write_ins(w, symbols, ins, reloc, file_offset, section.virtual_address)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ fn write_ins<W>(
|
|||
mut ins: Ins,
|
||||
reloc: Option<&ObjReloc>,
|
||||
file_offset: u64,
|
||||
section_address: u64,
|
||||
section_vaddr: Option<u64>,
|
||||
) -> Result<()>
|
||||
where
|
||||
W: Write + ?Sized,
|
||||
|
@ -265,7 +265,7 @@ where
|
|||
write!(
|
||||
w,
|
||||
"/* {:08X} {:08X} {:02X} {:02X} {:02X} {:02X} */\t",
|
||||
ins.addr as u64 + section_address,
|
||||
ins.addr as u64 + section_vaddr.unwrap_or(0),
|
||||
file_offset,
|
||||
(ins.code >> 24) & 0xFF,
|
||||
(ins.code >> 16) & 0xFF,
|
||||
|
@ -466,7 +466,7 @@ where
|
|||
let dbg_symbols = vec.iter().map(|e| &symbols[e.index]).collect_vec();
|
||||
bail!(
|
||||
"Unaligned symbol entry @ {:#010X}:\n\t{:?}",
|
||||
section.original_address as u32 + sym_addr,
|
||||
section.virtual_address.unwrap_or(0) as u32 + sym_addr,
|
||||
dbg_symbols
|
||||
);
|
||||
}
|
||||
|
@ -838,11 +838,12 @@ fn write_section_header<W>(
|
|||
where
|
||||
W: Write + ?Sized,
|
||||
{
|
||||
let section_virtual_address = section.virtual_address.unwrap_or(0);
|
||||
writeln!(
|
||||
w,
|
||||
"\n# {:#010X} - {:#010X}",
|
||||
start as u64 + section.original_address,
|
||||
end as u64 + section.original_address
|
||||
start as u64 + section_virtual_address,
|
||||
end as u64 + section_virtual_address
|
||||
)?;
|
||||
match section.name.as_str() {
|
||||
".text" if subsection == 0 => {
|
||||
|
|
|
@ -430,7 +430,7 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
|
|||
align: 0,
|
||||
elf_index: 0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: Some(dol_section.address as u64),
|
||||
file_offset: dol_section.file_offset as u64,
|
||||
section_known: known,
|
||||
splits: Default::default(),
|
||||
|
@ -460,7 +460,7 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
|
|||
align: 0,
|
||||
elf_index: 0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: Some(addr as u64),
|
||||
file_offset: 0,
|
||||
section_known: false,
|
||||
splits: Default::default(),
|
||||
|
@ -480,7 +480,7 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
|
|||
align: 0,
|
||||
elf_index: 0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: Some(bss_section.address as u64),
|
||||
file_offset: 0,
|
||||
section_known: false,
|
||||
splits: Default::default(),
|
||||
|
@ -507,7 +507,7 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
|
|||
align: 0,
|
||||
elf_index: 0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: Some(bss_sections[0].0 as u64),
|
||||
file_offset: 0,
|
||||
section_known: false,
|
||||
splits: Default::default(),
|
||||
|
@ -521,7 +521,7 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
|
|||
align: 0,
|
||||
elf_index: 0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: Some(bss_sections[1].0 as u64),
|
||||
file_offset: 0,
|
||||
section_known: false,
|
||||
splits: Default::default(),
|
||||
|
|
153
src/util/elf.rs
153
src/util/elf.rs
|
@ -9,6 +9,7 @@ use anyhow::{anyhow, bail, ensure, Context, Result};
|
|||
use cwdemangle::demangle;
|
||||
use flagset::Flags;
|
||||
use indexmap::IndexMap;
|
||||
use objdiff_core::obj::split_meta::{SplitMeta, SHT_SPLITMETA, SPLITMETA_SECTION};
|
||||
use object::{
|
||||
elf,
|
||||
elf::{SHF_ALLOC, SHF_EXECINSTR, SHF_WRITE, SHT_NOBITS, SHT_PROGBITS},
|
||||
|
@ -95,7 +96,7 @@ where P: AsRef<Path> {
|
|||
align: section.align(),
|
||||
elf_index: section.index().0,
|
||||
relocations: Default::default(),
|
||||
original_address: 0, // TODO load from abs symbol
|
||||
virtual_address: None, // Loaded from section symbol
|
||||
file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(),
|
||||
section_known: true,
|
||||
splits: Default::default(),
|
||||
|
@ -127,6 +128,26 @@ where P: AsRef<Path> {
|
|||
None
|
||||
};
|
||||
|
||||
let split_meta = if let Some(split_meta_section) = obj_file.section_by_name(SPLITMETA_SECTION) {
|
||||
let data = split_meta_section.uncompressed_data()?;
|
||||
if data.is_empty() {
|
||||
None
|
||||
} else {
|
||||
let mut reader = Cursor::new(&*data);
|
||||
let metadata =
|
||||
SplitMeta::from_reader(&mut reader, obj_file.endianness(), obj_file.is_64())
|
||||
.context("While reading .splitmeta section")?;
|
||||
log::debug!("Loaded .splitmeta section");
|
||||
ensure!(
|
||||
data.len() - reader.position() as usize == 0,
|
||||
".splitmeta section data not fully read"
|
||||
);
|
||||
Some(metadata)
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut symbols: Vec<ObjSymbol> = vec![];
|
||||
let mut symbol_indexes: Vec<Option<usize>> = vec![];
|
||||
let mut section_starts = IndexMap::<String, Vec<(u64, String)>>::new();
|
||||
|
@ -209,6 +230,16 @@ where P: AsRef<Path> {
|
|||
let section_index = symbol
|
||||
.section_index()
|
||||
.ok_or_else(|| anyhow!("Section symbol without section"))?;
|
||||
|
||||
// Resolve original address from split metadata
|
||||
if let Some(addr) = split_meta
|
||||
.as_ref()
|
||||
.and_then(|m| m.virtual_addresses.as_ref())
|
||||
.and_then(|v| v.get(symbol.index().0).cloned())
|
||||
{
|
||||
sections[section_index.0].virtual_address = Some(addr);
|
||||
}
|
||||
|
||||
let section = obj_file.section_by_index(section_index)?;
|
||||
let section_name = section.name()?.to_string();
|
||||
match &mut boundary_state {
|
||||
|
@ -335,6 +366,7 @@ where P: AsRef<Path> {
|
|||
let mut obj = ObjInfo::new(kind, architecture, obj_name, symbols, sections);
|
||||
obj.entry = NonZeroU64::new(obj_file.entry()).map(|n| n.get());
|
||||
obj.mw_comment = mw_comment.map(|(header, _)| header);
|
||||
obj.split_meta = split_meta;
|
||||
obj.sda2_base = sda2_base;
|
||||
obj.sda_base = sda_base;
|
||||
obj.stack_address = stack_address;
|
||||
|
@ -348,7 +380,7 @@ where P: AsRef<Path> {
|
|||
|
||||
pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
||||
let mut out_data = Vec::new();
|
||||
let mut writer = object::write::elf::Writer::new(Endianness::Big, false, &mut out_data);
|
||||
let mut writer = Writer::new(Endianness::Big, false, &mut out_data);
|
||||
|
||||
struct OutSection {
|
||||
index: SectionIndex,
|
||||
|
@ -357,6 +389,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
rela_offset: usize,
|
||||
name: StringId,
|
||||
rela_name: Option<StringId>,
|
||||
virtual_address: Option<u64>,
|
||||
}
|
||||
struct OutSymbol {
|
||||
#[allow(dead_code)]
|
||||
|
@ -376,6 +409,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
rela_offset: 0,
|
||||
name,
|
||||
rela_name: None,
|
||||
virtual_address: section.virtual_address,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -395,11 +429,12 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
writer.reserve_strtab_section_index();
|
||||
writer.reserve_shstrtab_section_index();
|
||||
|
||||
// Generate comment section
|
||||
// Generate .comment section
|
||||
let mut comment_data = if let Some(mw_comment) = &obj.mw_comment {
|
||||
let mut comment_data = Vec::<u8>::with_capacity(0x2C + obj.symbols.count() * 8);
|
||||
// Reserve section
|
||||
let name = writer.add_section_name(".comment".as_bytes());
|
||||
let index = writer.reserve_section_index();
|
||||
let out_section_idx = out_sections.len();
|
||||
out_sections.push(OutSection {
|
||||
index,
|
||||
rela_index: None,
|
||||
|
@ -407,12 +442,42 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
rela_offset: 0,
|
||||
name,
|
||||
rela_name: None,
|
||||
virtual_address: None,
|
||||
});
|
||||
|
||||
// Generate .comment data
|
||||
let mut comment_data = Vec::<u8>::with_capacity(0x2C + obj.symbols.count() * 8);
|
||||
mw_comment.to_writer_static(&mut comment_data, Endian::Big)?;
|
||||
// Null symbol
|
||||
CommentSym { align: 0, vis_flags: 0, active_flags: 0 }
|
||||
.to_writer_static(&mut comment_data, Endian::Big)?;
|
||||
Some(comment_data)
|
||||
Some((comment_data, out_section_idx))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Generate .splitmeta section
|
||||
let mut split_meta = if let Some(metadata) = &obj.split_meta {
|
||||
// Reserve section
|
||||
let name = writer.add_section_name(SPLITMETA_SECTION.as_bytes());
|
||||
let index = writer.reserve_section_index();
|
||||
let out_section_idx = out_sections.len();
|
||||
out_sections.push(OutSection {
|
||||
index,
|
||||
rela_index: None,
|
||||
offset: 0,
|
||||
rela_offset: 0,
|
||||
name,
|
||||
rela_name: None,
|
||||
virtual_address: None,
|
||||
});
|
||||
|
||||
// Generate .splitmeta data
|
||||
let mut out = metadata.clone();
|
||||
out.virtual_addresses = Some(vec![
|
||||
0, // Null symbol
|
||||
]);
|
||||
Some((out, out_section_idx))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -449,10 +514,15 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
st_size: 0,
|
||||
},
|
||||
});
|
||||
if let Some(comment_data) = &mut comment_data {
|
||||
if let Some((comment_data, _)) = &mut comment_data {
|
||||
CommentSym { align: 1, vis_flags: 0, active_flags: 0 }
|
||||
.to_writer_static(comment_data, Endian::Big)?;
|
||||
}
|
||||
if let Some(virtual_addresses) =
|
||||
split_meta.as_mut().and_then(|(m, _)| m.virtual_addresses.as_mut())
|
||||
{
|
||||
virtual_addresses.push(0);
|
||||
}
|
||||
section_symbol_offset += 1;
|
||||
}
|
||||
|
||||
|
@ -472,10 +542,15 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
};
|
||||
num_local = writer.symbol_count();
|
||||
out_symbols.push(OutSymbol { index, sym });
|
||||
if let Some(comment_data) = &mut comment_data {
|
||||
if let Some((comment_data, _)) = &mut comment_data {
|
||||
CommentSym { align: section.align as u32, vis_flags: 0, active_flags: 0 }
|
||||
.to_writer_static(comment_data, Endian::Big)?;
|
||||
}
|
||||
if let Some(virtual_addresses) =
|
||||
split_meta.as_mut().and_then(|(m, _)| m.virtual_addresses.as_mut())
|
||||
{
|
||||
virtual_addresses.push(section.virtual_address.unwrap_or(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,7 +570,8 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
continue;
|
||||
}
|
||||
|
||||
let section_index = symbol.section.and_then(|idx| out_sections.get(idx)).map(|s| s.index);
|
||||
let section = symbol.section.and_then(|idx| out_sections.get(idx));
|
||||
let section_index = section.map(|s| s.index);
|
||||
let index = writer.reserve_symbol_index(section_index);
|
||||
let name_index = if symbol.name.is_empty() {
|
||||
None
|
||||
|
@ -539,9 +615,18 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
}
|
||||
out_symbols.push(OutSymbol { index, sym });
|
||||
symbol_map[symbol_index] = Some(index.0);
|
||||
if let Some(comment_data) = &mut comment_data {
|
||||
if let Some((comment_data, _)) = &mut comment_data {
|
||||
CommentSym::from(symbol, export_all).to_writer_static(comment_data, Endian::Big)?;
|
||||
}
|
||||
if let Some(virtual_addresses) =
|
||||
split_meta.as_mut().and_then(|(m, _)| m.virtual_addresses.as_mut())
|
||||
{
|
||||
if let Some(section_vaddr) = section.and_then(|s| s.virtual_address) {
|
||||
virtual_addresses.push(section_vaddr + symbol.address);
|
||||
} else {
|
||||
virtual_addresses.push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.reserve_file_header();
|
||||
|
@ -576,12 +661,18 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
writer.reserve_strtab();
|
||||
writer.reserve_shstrtab();
|
||||
|
||||
// Reserve comment section
|
||||
if let Some(comment_data) = &comment_data {
|
||||
let out_section = out_sections.last_mut().unwrap();
|
||||
// Reserve .comment section
|
||||
if let Some((comment_data, idx)) = &comment_data {
|
||||
let out_section = &mut out_sections[*idx];
|
||||
out_section.offset = writer.reserve(comment_data.len(), 32);
|
||||
}
|
||||
|
||||
// Reserve .splitmeta section
|
||||
if let Some((metadata, idx)) = &split_meta {
|
||||
let out_section = &mut out_sections[*idx];
|
||||
out_section.offset = writer.reserve(metadata.write_size(false), 32);
|
||||
}
|
||||
|
||||
writer.reserve_section_headers();
|
||||
|
||||
writer.write_file_header(&object::write::elf::FileHeader {
|
||||
|
@ -688,13 +779,24 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
writer.write_shstrtab();
|
||||
|
||||
// Write comment section
|
||||
if let Some(comment_data) = &comment_data {
|
||||
let out_section = out_sections.last().unwrap();
|
||||
if let Some((comment_data, idx)) = &comment_data {
|
||||
let out_section = &out_sections[*idx];
|
||||
writer.write_align(32);
|
||||
ensure!(writer.len() == out_section.offset);
|
||||
writer.write(comment_data);
|
||||
}
|
||||
|
||||
// Write .splitmeta section
|
||||
if let Some((metadata, idx)) = &split_meta {
|
||||
let out_section = &out_sections[*idx];
|
||||
writer.write_align(32);
|
||||
ensure!(writer.len() == out_section.offset);
|
||||
// object::write::elf::Writer doesn't implement std::io::Write...
|
||||
let mut data = Vec::with_capacity(metadata.write_size(false));
|
||||
metadata.to_writer(&mut data, object::BigEndian, false)?;
|
||||
writer.write(&data);
|
||||
}
|
||||
|
||||
writer.write_null_section_header();
|
||||
for ((_, section), out_section) in obj.sections.iter().zip(&out_sections) {
|
||||
writer.write_section_header(&SectionHeader {
|
||||
|
@ -737,9 +839,9 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
writer.write_strtab_section_header();
|
||||
writer.write_shstrtab_section_header();
|
||||
|
||||
// Write comment section header
|
||||
if let Some(comment_data) = &comment_data {
|
||||
let out_section = out_sections.last().unwrap();
|
||||
// Write .comment section header
|
||||
if let Some((comment_data, idx)) = &comment_data {
|
||||
let out_section = &out_sections[*idx];
|
||||
writer.write_section_header(&SectionHeader {
|
||||
name: Some(out_section.name),
|
||||
sh_type: SHT_PROGBITS,
|
||||
|
@ -754,6 +856,23 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
|||
});
|
||||
}
|
||||
|
||||
// Write .splitmeta section header
|
||||
if let Some((metadata, idx)) = &split_meta {
|
||||
let out_section = &out_sections[*idx];
|
||||
writer.write_section_header(&SectionHeader {
|
||||
name: Some(out_section.name),
|
||||
sh_type: SHT_SPLITMETA,
|
||||
sh_flags: 0,
|
||||
sh_addr: 0,
|
||||
sh_offset: out_section.offset as u64,
|
||||
sh_size: metadata.write_size(false) as u64,
|
||||
sh_link: 0,
|
||||
sh_info: 0,
|
||||
sh_addralign: 1,
|
||||
sh_entsize: 1,
|
||||
});
|
||||
}
|
||||
|
||||
ensure!(writer.reserved_len() == writer.len());
|
||||
Ok(out_data)
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ where R: Read + Seek + ?Sized {
|
|||
.unwrap_or_default() as u64,
|
||||
elf_index: idx,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: None, // TODO option to set?
|
||||
file_offset: offset as u64,
|
||||
section_known,
|
||||
splits: Default::default(),
|
||||
|
|
|
@ -410,7 +410,7 @@ where R: Read + Seek + ?Sized {
|
|||
align: 0,
|
||||
elf_index: idx as usize,
|
||||
relocations: Default::default(),
|
||||
original_address: 0,
|
||||
virtual_address: None, // TODO option to set?
|
||||
file_offset: offset as u64,
|
||||
section_known: false,
|
||||
splits: Default::default(),
|
||||
|
|
|
@ -5,6 +5,7 @@ use std::{
|
|||
|
||||
use anyhow::{anyhow, bail, ensure, Context, Result};
|
||||
use itertools::Itertools;
|
||||
use objdiff_core::obj::split_meta::SplitMeta;
|
||||
use petgraph::{graph::NodeIndex, Graph};
|
||||
use sanitise_file_name::sanitize_with_options;
|
||||
use tracing_attributes::instrument;
|
||||
|
@ -882,7 +883,7 @@ fn resolve_link_order(obj: &ObjInfo) -> Result<Vec<ObjUnit>> {
|
|||
|
||||
/// Split an object into multiple relocatable objects.
|
||||
#[instrument(level = "debug", skip(obj))]
|
||||
pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
|
||||
pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo>> {
|
||||
let mut objects: Vec<ObjInfo> = vec![];
|
||||
let mut object_symbols: Vec<Vec<Option<usize>>> = vec![];
|
||||
let mut name_to_obj: HashMap<String, usize> = HashMap::new();
|
||||
|
@ -903,6 +904,12 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
|
|||
} else {
|
||||
split_obj.mw_comment = obj.mw_comment.clone();
|
||||
}
|
||||
split_obj.split_meta = Some(SplitMeta {
|
||||
generator: Some(format!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"))),
|
||||
module_name: module_name.map(str::to_string),
|
||||
module_id: Some(obj.module_id),
|
||||
virtual_addresses: None,
|
||||
});
|
||||
objects.push(split_obj);
|
||||
}
|
||||
|
||||
|
@ -1083,7 +1090,7 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
|
|||
align,
|
||||
elf_index: out_section_idx + 1,
|
||||
relocations: ObjRelocations::new(out_relocations)?,
|
||||
original_address: current_address.address as u64,
|
||||
virtual_address: Some(current_address.address as u64),
|
||||
file_offset: section.file_offset
|
||||
+ (current_address.address as u64 - section.address),
|
||||
section_known: true,
|
||||
|
@ -1148,7 +1155,7 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
|
|||
else {
|
||||
bail!(
|
||||
"Bad extabindex relocation @ {:#010X}",
|
||||
reloc_address as u64 + section.original_address
|
||||
reloc_address as u64 + section.virtual_address.unwrap_or(0)
|
||||
);
|
||||
};
|
||||
let target_section = &obj.sections.at_address(target_addr)?.1.name;
|
||||
|
@ -1158,9 +1165,9 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
|
|||
\tTarget object: {}:{:#010X} ({})\n\
|
||||
\tTarget symbol: {:#010X} ({})\n\
|
||||
This will cause the linker to crash.\n",
|
||||
reloc_address as u64 + section.original_address,
|
||||
reloc_address as u64 + section.virtual_address.unwrap_or(0),
|
||||
section.name,
|
||||
section.original_address,
|
||||
section.virtual_address.unwrap_or(0),
|
||||
out_obj.name,
|
||||
target_section,
|
||||
target_addr,
|
||||
|
|
Loading…
Reference in New Issue