From b787d9308f1c4b1e3dae64c9799912adcc5ccce3 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Sun, 1 Mar 2026 02:47:22 +1300 Subject: [PATCH 01/10] rabase and squash onto main. add start for windows support --- Cargo.lock | 216 +- Cargo.toml | 6 + docs/docs.md | 4 + justfile | 9 + kernel32.dump | 8313 +++++++++++++++++ libwild/Cargo.toml | 15 + libwild/src/arch.rs | 23 + libwild/src/archive.rs | 14 +- libwild/src/args/consts.rs | 64 + libwild/src/{args.rs => args/linux.rs} | 570 +- libwild/src/args/mod.rs | 473 + libwild/src/args/windows.rs | 1586 ++++ libwild/src/dwarf_address_info.rs | 27 +- libwild/src/elf.rs | 14 +- libwild/src/elf_writer.rs | 4 +- libwild/src/file_writer.rs | 6 +- libwild/src/fs.rs | 9 + libwild/src/gc_stats.rs | 6 +- libwild/src/grouping.rs | 6 +- libwild/src/input_data.rs | 12 +- libwild/src/layout.rs | 18 +- libwild/src/lib.rs | 34 +- libwild/src/linker_plugins.rs | 8 +- libwild/src/linker_plugins_disabled.rs | 2 +- libwild/src/output_kind.rs | 4 +- libwild/src/output_section_id.rs | 4 +- libwild/src/parsing.rs | 6 +- libwild/src/part_id.rs | 4 +- libwild/src/platform.rs | 10 +- libwild/src/resolution.rs | 8 +- libwild/src/save_dir.rs | 23 +- libwild/src/string_merging.rs | 8 +- .../{subprocess.rs => subprocess/linux.rs} | 8 +- libwild/src/subprocess/mod.rs | 18 + libwild/src/subprocess/windows.rs | 168 + libwild/src/subprocess_unsupported.rs | 4 +- libwild/src/symbol_db.rs | 16 +- libwild/src/target_os.rs | 57 + wild/src/main.rs | 2 +- windows/wlibwild/Cargo.toml | 39 + windows/wlibwild/done.txzt | 3 + windows/wlibwild/example-linkerflags-rust.txt | 35 + windows/wlibwild/src/bin/main.rs | 3 + windows/wlibwild/src/lib.rs | 201 + windows/wlibwild/src/paths.rs | 204 + windows/wlibwild/src/subprocess.rs | 179 + windows/wlibwild/w.just | 23 + 47 files changed, 12094 insertions(+), 372 deletions(-) create mode 100644 docs/docs.md create mode 100644 justfile create mode 100644 kernel32.dump create mode 100644 libwild/src/args/consts.rs rename libwild/src/{args.rs => args/linux.rs} (86%) create mode 100644 libwild/src/args/mod.rs create mode 100644 libwild/src/args/windows.rs rename libwild/src/{subprocess.rs => subprocess/linux.rs} (96%) create mode 100644 libwild/src/subprocess/mod.rs create mode 100644 libwild/src/subprocess/windows.rs create mode 100644 libwild/src/target_os.rs create mode 100644 windows/wlibwild/Cargo.toml create mode 100644 windows/wlibwild/done.txzt create mode 100644 windows/wlibwild/example-linkerflags-rust.txt create mode 100644 windows/wlibwild/src/bin/main.rs create mode 100644 windows/wlibwild/src/lib.rs create mode 100644 windows/wlibwild/src/paths.rs create mode 100644 windows/wlibwild/src/subprocess.rs create mode 100644 windows/wlibwild/w.just diff --git a/Cargo.lock b/Cargo.lock index 63e2820d4..78f9cb29f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -88,7 +88,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -215,6 +215,26 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -318,7 +338,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -337,7 +357,7 @@ dependencies = [ "libc", "once_cell", "unicode-width", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -480,6 +500,17 @@ dependencies = [ "objc2", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "either" version = "1.15.0" @@ -523,7 +554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -895,17 +926,20 @@ dependencies = [ "object 0.38.1", "perf-event", "perfetto-recorder", + "phnt", "rayon", "sharded-offset-map", "sharded-vec-writer 0.4.0", "smallvec", "symbolic-common", "symbolic-demangle", + "target-lexicon", "tempfile", "thread_local", "tracing", "tracing-subscriber", "uuid", + "windows-sys 0.61.2", "winnow", "zerocopy", "zstd", @@ -1065,6 +1099,25 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nt-string" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64f73b19d9405e886b53b9dee286e7fbb622a5276a7fd143c2d8e4dac3a0c6c" +dependencies = [ + "displaydoc", + "widestring", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1276,7 +1329,7 @@ dependencies = [ "objc2-foundation", "objc2-ui-kit", "serde", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1348,7 +1401,19 @@ dependencies = [ "nix", "prost", "rand", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "phnt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a88b858d3d129dd19de9bd1e4318b20753f2c92bea944fc0fb2728e444bf5f44" +dependencies = [ + "nt-string", + "quote", + "syn", + "windows-sys 0.59.0", ] [[package]] @@ -1643,7 +1708,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1652,6 +1717,15 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1883,6 +1957,12 @@ dependencies = [ "syn", ] +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + [[package]] name = "tempfile" version = "3.25.0" @@ -1893,7 +1973,7 @@ dependencies = [ "getrandom 0.4.1", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -2058,6 +2138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", + "nu-ansi-term", "once_cell", "regex-automata", "sharded-slab", @@ -2133,6 +2214,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasip2" version = "1.0.2+wasi-0.2.9" @@ -2251,6 +2342,12 @@ dependencies = [ "winsafe", ] +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "wild-linker" version = "0.8.0" @@ -2291,6 +2388,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2303,6 +2409,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -2312,6 +2427,70 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "0.7.14" @@ -2415,6 +2594,25 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wlibwild" +version = "0.8.0" +dependencies = [ + "anyhow", + "bytemuck", + "bytesize", + "colored", + "indexmap", + "itertools", + "object 0.38.1", + "phnt", + "rayon", + "tracing", + "tracing-subscriber", + "walkdir", + "windows-sys 0.61.2", +] + [[package]] name = "zerocopy" version = "0.8.39" diff --git a/Cargo.toml b/Cargo.toml index 908dc206b..43eade3db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "wild", "libwild", "benchmarks/runner", + "windows/wlibwild", ] resolver = "2" @@ -30,6 +31,7 @@ ar = "0.9.0" atomic-take = "1.0.0" bitflags = "2.4.0" blake3 = { version = "1.0.0", features = ["rayon"] } +bytemuck = { version = "1.0.0", features = ["derive"] } bumpalo-herd = "0.1.2" bytesize = "2.0.0" clap = { version = "4.1.0", features = ["derive"] } @@ -67,6 +69,7 @@ object = { version = "0.38.1", default-features = false, features = [ "std", "unaligned", "archive", + "pe", ] } os_info = "3.0.0" paste = "1.0.15" @@ -97,9 +100,12 @@ tracing-subscriber = { version = "0.3.16", default-features = false, features = ] } uuid = { version = "1.0.0", features = ["v4"] } wait-timeout = "0.2.0" +walkdir = "2" wait4 = "0.1.3" which = "8.0.0" +windows-sys = "0.61.2" winnow = { version = "0.7.13", features = ["simd"] } +phnt = "0.1.2" zerocopy = { version = "0.8.27", features = ["derive"] } zstd = "0.13.0" diff --git a/docs/docs.md b/docs/docs.md new file mode 100644 index 000000000..f1461c064 --- /dev/null +++ b/docs/docs.md @@ -0,0 +1,4 @@ +# Documentation Related to Linking + + +## [Windows Docs](windows/windows.md) \ No newline at end of file diff --git a/justfile b/justfile new file mode 100644 index 000000000..3455f99cc --- /dev/null +++ b/justfile @@ -0,0 +1,9 @@ +mod w "windows/wlibwild/w.just" + + +default: + @just w + + +dump-kernel32: + @llvm-objdump -a -t "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib" > kernel32.dump \ No newline at end of file diff --git a/kernel32.dump b/kernel32.dump new file mode 100644 index 000000000..508100375 --- /dev/null +++ b/kernel32.dump @@ -0,0 +1,8313 @@ + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 +--------- 0/0 498 (date: "-1" contains non-decimal chars) KERNEL32.dll + +SYMBOL TABLE: +[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id +[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __IMPORT_DESCRIPTOR_KERNEL32 +[ 2](sec 2)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$2 +[ 3](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 +[ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$4 +[ 5](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$5 +[ 6](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR +[ 7](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 KERNEL32_NULL_THUNK_DATA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 +--------- 0/0 251 (date: "-1" contains non-decimal chars) KERNEL32.dll + +SYMBOL TABLE: +[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id +[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 +--------- 0/0 288 (date: "-1" contains non-decimal chars) KERNEL32.dll + +SYMBOL TABLE: +[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id +[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 KERNEL32_NULL_THUNK_DATA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AcquireSRWLockExclusive +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AcquireSRWLockExclusive + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AcquireSRWLockShared +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AcquireSRWLockShared + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ActivateActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ActivateActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ActivatePackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ActivatePackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddAtomA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddAtomA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddAtomW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddAtomW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddConsoleAliasA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddConsoleAliasA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddConsoleAliasW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddConsoleAliasW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddDllDirectory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddDllDirectory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddIntegrityLabelToBoundaryDescriptor +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddIntegrityLabelToBoundaryDescriptor + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddLocalAlternateComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddLocalAlternateComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddLocalAlternateComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddLocalAlternateComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddRefActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddRefActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddResourceAttributeAce +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddResourceAttributeAce + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddSIDToBoundaryDescriptor +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddSIDToBoundaryDescriptor + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddScopedPolicyIDAce +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddScopedPolicyIDAce + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddSecureMemoryCacheCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddSecureMemoryCacheCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddVectoredContinueHandler +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddVectoredContinueHandler + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddVectoredExceptionHandler +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddVectoredExceptionHandler + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocateUserPhysicalPages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocateUserPhysicalPages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocateUserPhysicalPagesNuma +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocateUserPhysicalPagesNuma + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetClrCompat +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetClrCompat + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetCreateFileAccess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetCreateFileAccess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetLifecycleManagement +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetLifecycleManagement + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetMediaFoundationCodecLoading +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetMediaFoundationCodecLoading + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetProcessTerminationMethod +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetProcessTerminationMethod + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetShowDeveloperDiagnostic +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetShowDeveloperDiagnostic + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetThreadInitializationType +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetThreadInitializationType + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetWindowingModel +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetWindowingModel + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppXGetOSMaxVersionTested +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppXGetOSMaxVersionTested + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ApplicationRecoveryFinished +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ApplicationRecoveryFinished + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ApplicationRecoveryInProgress +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ApplicationRecoveryInProgress + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AreFileApisANSI +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AreFileApisANSI + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AreShortNamesEnabled +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AreShortNamesEnabled + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AssignProcessToJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AssignProcessToJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AttachConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AttachConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupRead +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupRead + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupSeek +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupSeek + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupWrite +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupWrite + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BaseGetNamedObjectDirectory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BaseGetNamedObjectDirectory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BaseSetLastNTError +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BaseSetLastNTError + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 38 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Beep +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Beep + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BeginUpdateResourceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BeginUpdateResourceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BeginUpdateResourceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BeginUpdateResourceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BindIoCompletionCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BindIoCompletionCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBAndTimeoutsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBAndTimeoutsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBAndTimeoutsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBAndTimeoutsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingCancelRequest +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingCancelRequest + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingFlushFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingFlushFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingReadFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingReadFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingRegisterBuffers +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingRegisterBuffers + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingRegisterFileHandles +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingRegisterFileHandles + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingWriteFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingWriteFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallNamedPipeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallNamedPipeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallNamedPipeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallNamedPipeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallbackMayRunLong +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallbackMayRunLong + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelDeviceWakeupRequest +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelDeviceWakeupRequest + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelIoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelIoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelSynchronousIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelSynchronousIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelThreadpoolIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelThreadpoolIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelTimerQueueTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelTimerQueueTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelWaitableTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelWaitableTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CeipIsOptedIn +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CeipIsOptedIn + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ChangeTimerQueueTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ChangeTimerQueueTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckElevation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckElevation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckElevationEnabled +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckElevationEnabled + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckNameLegalDOS8Dot3A +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckNameLegalDOS8Dot3A + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckNameLegalDOS8Dot3W +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckNameLegalDOS8Dot3W + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckRemoteDebuggerPresent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckRemoteDebuggerPresent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckTokenCapability +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckTokenCapability + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckTokenMembershipEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckTokenMembershipEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClearCommBreak +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClearCommBreak + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClearCommError +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClearCommError + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseIoRing +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseIoRing + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePackageInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePackageInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePrivateNamespace +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePrivateNamespace + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePseudoConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePseudoConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpool +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpool + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolCleanupGroup +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolCleanupGroup + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolCleanupGroupMembers +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolCleanupGroupMembers + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolWait +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolWait + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolWork +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolWork + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CommConfigDialogA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CommConfigDialogA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CommConfigDialogW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CommConfigDialogW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringOrdinal +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringOrdinal + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConnectNamedPipe +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConnectNamedPipe + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ContinueDebugEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ContinueDebugEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertDefaultLocale +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertDefaultLocale + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertFiberToThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertFiberToThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertThreadToFiber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertThreadToFiber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertThreadToFiberEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertThreadToFiberEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFile2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFile2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateActCtxA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateActCtxA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateActCtxW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateActCtxW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateBoundaryDescriptorA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateBoundaryDescriptorA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateBoundaryDescriptorW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateBoundaryDescriptorW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateConsoleScreenBuffer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateConsoleScreenBuffer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEnclave +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEnclave + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFiber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFiber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFiberEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFiberEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFile2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFile2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingFromApp +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingFromApp + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingNumaA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingNumaA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingNumaW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingNumaW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateIoCompletionPort +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateIoCompletionPort + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateIoRing +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateIoRing + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobObjectA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobObjectA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobObjectW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobObjectW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobSet +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobSet + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMailslotA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMailslotA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMailslotW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMailslotW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMemoryResourceNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMemoryResourceNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateNamedPipeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateNamedPipeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateNamedPipeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateNamedPipeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePipe +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePipe + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePrivateNamespaceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePrivateNamespaceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePrivateNamespaceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePrivateNamespaceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateProcessA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateProcessA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateProcessW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateProcessW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePseudoConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePseudoConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateRemoteThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateRemoteThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateRemoteThreadEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateRemoteThreadEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTapePartition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTapePartition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpool +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpool + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolCleanupGroup +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolCleanupGroup + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolWait +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolWait + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolWork +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolWork + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTimerQueue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTimerQueue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTimerQueueTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTimerQueueTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateToolhelp32Snapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateToolhelp32Snapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateUmsCompletionList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateUmsCompletionList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateUmsThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateUmsThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CtrlRoutine +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CtrlRoutine + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeactivateActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeactivateActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeactivatePackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeactivatePackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugActiveProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugActiveProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugActiveProcessStop +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugActiveProcessStop + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugBreak +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugBreak + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugBreakProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugBreakProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugSetProcessKillOnExit +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugSetProcessKillOnExit + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DecodePointer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DecodePointer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DecodeSystemPointer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DecodeSystemPointer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DefineDosDeviceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DefineDosDeviceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DefineDosDeviceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DefineDosDeviceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DelayLoadFailureHook +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DelayLoadFailureHook + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteAtom +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteAtom + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteBoundaryDescriptor +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteBoundaryDescriptor + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteCriticalSection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteCriticalSection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFiber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFiber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteProcThreadAttributeList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteProcThreadAttributeList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteSynchronizationBarrier +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteSynchronizationBarrier + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueueEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueueEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueueTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueueTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteUmsCompletionList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteUmsCompletionList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteUmsThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteUmsThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteVolumeMountPointA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteVolumeMountPointA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteVolumeMountPointW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteVolumeMountPointW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DequeueUmsCompletionListItems +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DequeueUmsCompletionListItems + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeviceIoControl +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeviceIoControl + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisableThreadLibraryCalls +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisableThreadLibraryCalls + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisableThreadProfiling +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisableThreadProfiling + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisassociateCurrentThreadFromCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisassociateCurrentThreadFromCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DiscardVirtualMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DiscardVirtualMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisconnectNamedPipe +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisconnectNamedPipe + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DosDateTimeToFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DosDateTimeToFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DosPathToSessionPathW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DosPathToSessionPathW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DuplicateHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DuplicateHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DuplicatePackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DuplicatePackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnableProcessOptionalXStateFeatures +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnableProcessOptionalXStateFeatures + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnableThreadProfiling +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnableThreadProfiling + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EncodePointer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EncodePointer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EncodeSystemPointer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EncodeSystemPointer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EndUpdateResourceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EndUpdateResourceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EndUpdateResourceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EndUpdateResourceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterCriticalSection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterCriticalSection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterSynchronizationBarrier +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterSynchronizationBarrier + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterUmsSchedulingMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterUmsSchedulingMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumLanguageGroupLocalesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumLanguageGroupLocalesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumLanguageGroupLocalesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumLanguageGroupLocalesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemCodePagesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemCodePagesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemCodePagesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemCodePagesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemFirmwareTables +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemFirmwareTables + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemGeoID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemGeoID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemGeoNames +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemGeoNames + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLanguageGroupsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLanguageGroupsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLanguageGroupsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLanguageGroupsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumUILanguagesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumUILanguagesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumUILanguagesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumUILanguagesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumerateLocalComputerNamesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumerateLocalComputerNamesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumerateLocalComputerNamesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumerateLocalComputerNamesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EraseTape +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EraseTape + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EscapeCommFunction +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EscapeCommFunction + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExecuteUmsThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExecuteUmsThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExitProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExitProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExitThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExitThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExpandEnvironmentStringsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExpandEnvironmentStringsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExpandEnvironmentStringsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExpandEnvironmentStringsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalAppExitA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalAppExitA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalAppExitW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalAppExitW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalExit +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalExit + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToDosDateTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToDosDateTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToLocalFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToLocalFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToSystemTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToSystemTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputCharacterA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputCharacterA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputCharacterW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputCharacterW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionGuid +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionGuid + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindAtomA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindAtomA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindAtomW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindAtomW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindClose +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindClose + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindCloseChangeNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindCloseChangeNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstChangeNotificationA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstChangeNotificationA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstChangeNotificationW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstChangeNotificationW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileNameTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileNameTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstStreamTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstStreamTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstStreamW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstStreamW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeMountPointA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeMountPointA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeMountPointW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeMountPointW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNLSString +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNLSString + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNLSStringEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNLSStringEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextChangeNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextChangeNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextStreamW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextStreamW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeMountPointA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeMountPointA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeMountPointW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeMountPointW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindPackagesByPackageFamily +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindPackagesByPackageFamily + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindStringOrdinal +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindStringOrdinal + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindVolumeClose +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindVolumeClose + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindVolumeMountPointClose +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindVolumeMountPointClose + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsGetValue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsGetValue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsSetValue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsSetValue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushConsoleInputBuffer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushConsoleInputBuffer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushFileBuffers +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushFileBuffers + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushInstructionCache +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushInstructionCache + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushProcessWriteBuffers +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushProcessWriteBuffers + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushViewOfFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushViewOfFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FoldStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FoldStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FoldStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FoldStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatApplicationUserModelId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatApplicationUserModelId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatMessageA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatMessageA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatMessageW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatMessageW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeEnvironmentStringsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeEnvironmentStringsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeEnvironmentStringsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeEnvironmentStringsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibrary +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibrary + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibraryAndExitThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibraryAndExitThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibraryWhenCallbackReturns +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibraryWhenCallbackReturns + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeMemoryJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeMemoryJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeResource +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeResource + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeUserPhysicalPages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeUserPhysicalPages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GenerateConsoleCtrlEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GenerateConsoleCtrlEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetACP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetACP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetActiveProcessorCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetActiveProcessorCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetActiveProcessorGroupCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetActiveProcessorGroupCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAppContainerAce +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAppContainerAce + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAppContainerNamedObjectPath +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAppContainerNamedObjectPath + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationRecoveryCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationRecoveryCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationRestartSettings +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationRestartSettings + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationUserModelId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationUserModelId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAtomNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAtomNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAtomNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAtomNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryType +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryType + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryTypeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryTypeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryTypeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryTypeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfoExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfoExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfoExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfoExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCachedSigningLevel +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCachedSigningLevel + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommConfig +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommConfig + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommModemStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommModemStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommProperties +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommProperties + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommTimeouts +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommTimeouts + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommandLineA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommandLineA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommandLineW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommandLineW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesLengthA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesLengthA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesLengthW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesLengthW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesLengthA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesLengthA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesLengthW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesLengthW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleCP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleCP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleCursorInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleCursorInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleDisplayMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleDisplayMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleFontSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleFontSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleHistoryInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleHistoryInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOriginalTitleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOriginalTitleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOriginalTitleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOriginalTitleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOutputCP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOutputCP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleProcessList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleProcessList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleScreenBufferInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleScreenBufferInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleScreenBufferInfoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleScreenBufferInfoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleSelectionInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleSelectionInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleTitleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleTitleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleTitleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleTitleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleWindow +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleWindow + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentApplicationUserModelId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentApplicationUserModelId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentConsoleFont +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentConsoleFont + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentConsoleFontEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentConsoleFontEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageFamilyName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageFamilyName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackagePath +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackagePath + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessorNumber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessorNumber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessorNumberEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessorNumberEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThreadId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThreadId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThreadStackLimits +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThreadStackLimits + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentUmsThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentUmsThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDefaultCommConfigA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDefaultCommConfigA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDefaultCommConfigW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDefaultCommConfigW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDevicePowerState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDevicePowerState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskSpaceInformationA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskSpaceInformationA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskSpaceInformationW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskSpaceInformationW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDllDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDllDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDllDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDllDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDriveTypeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDriveTypeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDriveTypeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDriveTypeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDurationFormat +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDurationFormat + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDurationFormatEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDurationFormatEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDynamicTimeZoneInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDynamicTimeZoneInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnabledXStateFeatures +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnabledXStateFeatures + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStrings +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStrings + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStringsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStringsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStringsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStringsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentVariableA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentVariableA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentVariableW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentVariableW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEraNameCountedString +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEraNameCountedString + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetErrorMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetErrorMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetExitCodeProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetExitCodeProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetExitCodeThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetExitCodeThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileBandwidthReservation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileBandwidthReservation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileInformationByHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileInformationByHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileInformationByHandleEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileInformationByHandleEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileMUIInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileMUIInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileMUIPath +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileMUIPath + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileSizeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileSizeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileType +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileType + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFinalPathNameByHandleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFinalPathNameByHandleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFinalPathNameByHandleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFinalPathNameByHandleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareType +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareType + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetHandleInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetHandleInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetIoRingInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetIoRingInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLargePageMinimum +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLargePageMinimum + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLargestConsoleWindowSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLargestConsoleWindowSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLastError +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLastError + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocalTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocalTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDriveStringsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDriveStringsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDriveStringsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDriveStringsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDrives +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDrives + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalProcessorInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalProcessorInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalProcessorInformationEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalProcessorInformationEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMachineTypeAttributes +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMachineTypeAttributes + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMailslotInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMailslotInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMaximumProcessorCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMaximumProcessorCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMaximumProcessorGroupCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMaximumProcessorGroupCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMemoryErrorHandlingCapabilities +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMemoryErrorHandlingCapabilities + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleFileNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleFileNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNLSVersion +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNLSVersion + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNLSVersionEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNLSVersionEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientProcessId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientProcessId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientSessionId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientSessionId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeHandleStateA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeHandleStateA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeHandleStateW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeHandleStateW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeServerProcessId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeServerProcessId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeServerSessionId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeServerSessionId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNativeSystemInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNativeSystemInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNextUmsListItem +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNextUmsListItem + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaAvailableMemoryNode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaAvailableMemoryNode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaAvailableMemoryNodeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaAvailableMemoryNodeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaHighestNodeNumber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaHighestNodeNumber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeNumberFromHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeNumberFromHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMask2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMask2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMaskEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMaskEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProcessorNode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProcessorNode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProcessorNodeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProcessorNodeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProximityNode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProximityNode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProximityNodeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProximityNodeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberOfConsoleInputEvents +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberOfConsoleInputEvents + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberOfConsoleMouseButtons +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberOfConsoleMouseButtons + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOEMCP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOEMCP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOverlappedResult +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOverlappedResult + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOverlappedResultEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOverlappedResultEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageApplicationIds +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageApplicationIds + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageFamilyName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageFamilyName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagePath +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagePath + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagePathByFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagePathByFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagesByPackageFamily +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagesByPackageFamily + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPhysicallyInstalledSystemMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPhysicallyInstalledSystemMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPriorityClass +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPriorityClass + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileIntA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileIntA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileIntW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileIntW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionNamesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionNamesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionNamesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionNamesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStructA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStructA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStructW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStructW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcAddress +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcAddress + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessAffinityMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessAffinityMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDEPPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDEPPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDefaultCpuSetMasks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDefaultCpuSetMasks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDefaultCpuSets +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDefaultCpuSets + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessGroupAffinity +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessGroupAffinity + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHandleCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHandleCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHeap +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHeap + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHeaps +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHeaps + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessIdOfThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessIdOfThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessIoCounters +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessIoCounters + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessMitigationPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessMitigationPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessPriorityBoost +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessPriorityBoost + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessShutdownParameters +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessShutdownParameters + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessTimes +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessTimes + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessVersion +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessVersion + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessWorkingSetSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessWorkingSetSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessWorkingSetSizeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessWorkingSetSizeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessesInVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessesInVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessorSystemCycleTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessorSystemCycleTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProductInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProductInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileIntA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileIntA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileIntW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileIntW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileSectionA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileSectionA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileSectionW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileSectionW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetQueuedCompletionStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetQueuedCompletionStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetQueuedCompletionStatusEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetQueuedCompletionStatusEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetShortPathNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetShortPathNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetShortPathNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetShortPathNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStagedPackagePathByFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStagedPackagePathByFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStartupInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStartupInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStartupInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStartupInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStateFolder +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStateFolder + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStdHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStdHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringScripts +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringScripts + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemAppDataKey +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemAppDataKey + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemCpuSetInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemCpuSetInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDEPPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDEPPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLCID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLCID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLangID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLangID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLocaleName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLocaleName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultUILanguage +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultUILanguage + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemFileCacheSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemFileCacheSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemFirmwareTable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemFirmwareTable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemPowerStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemPowerStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemRegistryQuota +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemRegistryQuota + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimeAdjustment +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimeAdjustment + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimeAsFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimeAsFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimePreciseAsFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimePreciseAsFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimes +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimes + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWindowsDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWindowsDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWindowsDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWindowsDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWow64DirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWow64DirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWow64DirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWow64DirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapeParameters +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapeParameters + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapePosition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapePosition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapeStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapeStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempFileNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempFileNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPath2A +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPath2A + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPath2W +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPath2W + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPathA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPathA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPathW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPathW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadDescription +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadDescription + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadEnabledXStateFeatures +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadEnabledXStateFeatures + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadErrorMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadErrorMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadGroupAffinity +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadGroupAffinity + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadIOPendingFlag +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadIOPendingFlag + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadIdealProcessorEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadIdealProcessorEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadLocale +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadLocale + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPriority +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPriority + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPriorityBoost +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPriorityBoost + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectedCpuSetMasks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectedCpuSetMasks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectedCpuSets +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectedCpuSets + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectorEntry +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectorEntry + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadTimes +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadTimes + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadUILanguage +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadUILanguage + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTickCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTickCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTickCount64 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTickCount64 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeZoneInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeZoneInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeZoneInformationForYear +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeZoneInformationForYear + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUILanguageInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUILanguageInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUmsCompletionListEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUmsCompletionListEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUmsSystemThreadInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUmsSystemThreadInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultGeoName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultGeoName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLCID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLCID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLangID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLangID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLocaleName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLocaleName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultUILanguage +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultUILanguage + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserGeoID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserGeoID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersion +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersion + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersionExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersionExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersionExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersionExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationByHandleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationByHandleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeNameForVolumeMountPointA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeNameForVolumeMountPointA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeNameForVolumeMountPointW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeNameForVolumeMountPointW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNamesForVolumeNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNamesForVolumeNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNamesForVolumeNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNamesForVolumeNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWindowsDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWindowsDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWindowsDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWindowsDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWriteWatch +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWriteWatch + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetXStateFeaturesMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetXStateFeaturesMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalCompact +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalCompact + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalDeleteAtom +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalDeleteAtom + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFindAtomA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFindAtomA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFindAtomW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFindAtomW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFix +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFix + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFlags +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFlags + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalGetAtomNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalGetAtomNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalGetAtomNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalGetAtomNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalLock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalLock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalMemoryStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalMemoryStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalMemoryStatusEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalMemoryStatusEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalReAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalReAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnWire +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnWire + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnfix +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnfix + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalWire +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalWire + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32First +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32First + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32ListFirst +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32ListFirst + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32ListNext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32ListNext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32Next +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32Next + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapCompact +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapCompact + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapCreate +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapCreate + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapDestroy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapDestroy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapLock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapLock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapQueryInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapQueryInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapReAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapReAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSetInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSetInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSummary +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSummary + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapUnlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapUnlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapValidate +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapValidate + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapWalk +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapWalk + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitAtomTable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitAtomTable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceBeginInitialize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceBeginInitialize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceComplete +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceComplete + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceExecuteOnce +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceExecuteOnce + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceInitialize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceInitialize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeConditionVariable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeConditionVariable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeContext2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeContext2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSectionAndSpinCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSectionAndSpinCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSectionEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSectionEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeEnclave +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeEnclave + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeProcThreadAttributeList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeProcThreadAttributeList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSListHead +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSListHead + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSRWLock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSRWLock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSynchronizationBarrier +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSynchronizationBarrier + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InstallELAMCertificateInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InstallELAMCertificateInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedFlushSList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedFlushSList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPopEntrySList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPopEntrySList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushEntrySList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushEntrySList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushListSList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushListSList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushListSListEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushListSListEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadCodePtr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadCodePtr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadHugeReadPtr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadHugeReadPtr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadHugeWritePtr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadHugeWritePtr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadReadPtr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadReadPtr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadStringPtrA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadStringPtrA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadStringPtrW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadStringPtrW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadWritePtr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadWritePtr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDBCSLeadByte +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDBCSLeadByte + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDBCSLeadByteEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDBCSLeadByteEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDebuggerPresent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDebuggerPresent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsEnclaveTypeSupported +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsEnclaveTypeSupported + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsIoRingOpSupported +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsIoRingOpSupported + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNLSDefinedString +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNLSDefinedString + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNativeVhdBoot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNativeVhdBoot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNormalizedString +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNormalizedString + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessCritical +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessCritical + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessInJob +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessInJob + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessorFeaturePresent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessorFeaturePresent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsSystemResumeAutomatic +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsSystemResumeAutomatic + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsThreadAFiber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsThreadAFiber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsThreadpoolTimerSet +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsThreadpoolTimerSet + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsUserCetAvailableInEnvironment +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsUserCetAvailableInEnvironment + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidCodePage +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidCodePage + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLanguageGroup +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLanguageGroup + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLocale +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLocale + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLocaleName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLocaleName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidNLSVersion +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidNLSVersion + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64GuestMachineSupported +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64GuestMachineSupported + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64Process +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64Process + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64Process2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64Process2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EmptyWorkingSet +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EmptyWorkingSet + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumDeviceDrivers +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumDeviceDrivers + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumPageFilesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumPageFilesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumPageFilesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumPageFilesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcessModules +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcessModules + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcessModulesEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcessModulesEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcesses +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcesses + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverBaseNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverBaseNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverBaseNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverBaseNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverFileNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverFileNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetMappedFileNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetMappedFileNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetMappedFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetMappedFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleBaseNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleBaseNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleBaseNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleBaseNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleFileNameExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleFileNameExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleFileNameExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleFileNameExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetPerformanceInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetPerformanceInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessImageFileNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessImageFileNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessImageFileNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessImageFileNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessMemoryInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessMemoryInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetWsChanges +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetWsChanges + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetWsChangesEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetWsChangesEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32InitializeProcessForWsWatch +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32InitializeProcessForWsWatch + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32QueryWorkingSet +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32QueryWorkingSet + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32QueryWorkingSetEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32QueryWorkingSetEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCIDToLocaleName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCIDToLocaleName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LeaveCriticalSection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LeaveCriticalSection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LeaveCriticalSectionWhenCallbackReturns +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LeaveCriticalSectionWhenCallbackReturns + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadAppInitDlls +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadAppInitDlls + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadEnclaveData +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadEnclaveData + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadModule +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadModule + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadPackagedLibrary +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadPackagedLibrary + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadResource +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadResource + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadStringBaseExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadStringBaseExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadStringBaseW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadStringBaseW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalCompact +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalCompact + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFileTimeToFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFileTimeToFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFileTimeToLocalSystemTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFileTimeToLocalSystemTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFlags +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFlags + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalLock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalLock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalReAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalReAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalShrink +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalShrink + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalSystemTimeToLocalFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalSystemTimeToLocalFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalUnlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalUnlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocaleNameToLCID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocaleNameToLCID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocateXStateFeature +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocateXStateFeature + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockResource +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockResource + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapUserPhysicalPages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapUserPhysicalPages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapUserPhysicalPagesScatter +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapUserPhysicalPagesScatter + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileExNuma +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileExNuma + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileFromApp +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileFromApp + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32First +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32First + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32FirstW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32FirstW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32Next +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32Next + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32NextW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32NextW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileWithProgressA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileWithProgressA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileWithProgressW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileWithProgressW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MulDiv +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MulDiv + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MultiByteToWideChar +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MultiByteToWideChar + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NeedCurrentDirectoryForExePathA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NeedCurrentDirectoryForExePathA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NeedCurrentDirectoryForExePathW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NeedCurrentDirectoryForExePathW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NormalizeString +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NormalizeString + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NotifyMountMgr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NotifyMountMgr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NotifyUILanguageChange +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NotifyUILanguageChange + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OOBEComplete +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OOBEComplete + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OfferVirtualMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OfferVirtualMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenEventA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenEventA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenEventW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenEventW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileById +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileById + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileMappingA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileMappingA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileMappingW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileMappingW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenJobObjectA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenJobObjectA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenJobObjectW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenJobObjectW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenMutexA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenMutexA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenMutexW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenMutexW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPackageInfoByFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPackageInfoByFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPrivateNamespaceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPrivateNamespaceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPrivateNamespaceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPrivateNamespaceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenSemaphoreA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenSemaphoreA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenSemaphoreW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenSemaphoreW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenStateExplicit +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenStateExplicit + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenWaitableTimerA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenWaitableTimerA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenWaitableTimerW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenWaitableTimerW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OutputDebugStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OutputDebugStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OutputDebugStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OutputDebugStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFamilyNameFromFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFamilyNameFromFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFamilyNameFromId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFamilyNameFromId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFullNameFromId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFullNameFromId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageIdFromFullName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageIdFromFullName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageNameAndPublisherIdFromFamilyName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageNameAndPublisherIdFromFamilyName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ParseApplicationUserModelId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ParseApplicationUserModelId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekConsoleInputA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekConsoleInputA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekConsoleInputW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekConsoleInputW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekNamedPipe +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekNamedPipe + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PopIoRingCompletion +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PopIoRingCompletion + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PostQueuedCompletionStatus +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PostQueuedCompletionStatus + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerClearRequest +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerClearRequest + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerCreateRequest +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerCreateRequest + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerSetRequest +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerSetRequest + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PrefetchVirtualMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PrefetchVirtualMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PrepareTape +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PrepareTape + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32First +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32First + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32FirstW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32FirstW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32Next +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32Next + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32NextW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32NextW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ProcessIdToSessionId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ProcessIdToSessionId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssCaptureSnapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssCaptureSnapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssDuplicateSnapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssDuplicateSnapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssFreeSnapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssFreeSnapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssQuerySnapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssQuerySnapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerCreate +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerCreate + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerGetPosition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerGetPosition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerRewind +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerRewind + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSeek +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSeek + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSeekToBeginning +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSeekToBeginning + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSetPosition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSetPosition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerTell +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerTell + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkSnapshot +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkSnapshot + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PulseEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PulseEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PurgeComm +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PurgeComm + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryActCtxSettingsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryActCtxSettingsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryActCtxW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryActCtxW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDepthSList +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDepthSList + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDosDeviceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDosDeviceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDosDeviceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDosDeviceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryFullProcessImageNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryFullProcessImageNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryFullProcessImageNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryFullProcessImageNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIdleProcessorCycleTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIdleProcessorCycleTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIdleProcessorCycleTimeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIdleProcessorCycleTimeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryInformationJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryInformationJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIoRateControlInformationJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIoRateControlInformationJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIoRingCapabilities +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIoRingCapabilities + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryMemoryResourceNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryMemoryResourceNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryPerformanceCounter +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryPerformanceCounter + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryPerformanceFrequency +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryPerformanceFrequency + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProcessAffinityUpdateMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProcessAffinityUpdateMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProcessCycleTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProcessCycleTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProtectedPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProtectedPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadCycleTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadCycleTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadProfiling +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadProfiling + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadpoolStackInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadpoolStackInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryUmsThreadInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryUmsThreadInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryUnbiasedInterruptTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryUnbiasedInterruptTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserAPC +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserAPC + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserAPC2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserAPC2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserWorkItem +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserWorkItem + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RaiseException +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RaiseException + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RaiseFailFastException +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RaiseFailFastException + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReOpenFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReOpenFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleInputA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleInputA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleInputW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleInputW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputCharacterA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputCharacterA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputCharacterW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputCharacterW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadDirectoryChangesExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadDirectoryChangesExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadDirectoryChangesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadDirectoryChangesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFileScatter +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFileScatter + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadProcessMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadProcessMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadThreadProfilingData +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadThreadProfilingData + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReclaimVirtualMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReclaimVirtualMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterApplicationRecoveryCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterApplicationRecoveryCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterApplicationRestart +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterApplicationRestart + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterBadMemoryNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterBadMemoryNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForInputIdle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForInputIdle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForSingleObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForSingleObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForSingleObjectEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForSingleObjectEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitUntilOOBECompleted +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitUntilOOBECompleted + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseMutex +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseMutex + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseMutexWhenCallbackReturns +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseMutexWhenCallbackReturns + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleasePackageVirtualizationContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleasePackageVirtualizationContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSRWLockExclusive +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSRWLockExclusive + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSRWLockShared +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSRWLockShared + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSemaphore +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSemaphore + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSemaphoreWhenCallbackReturns +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSemaphoreWhenCallbackReturns + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDllDirectory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDllDirectory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveLocalAlternateComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveLocalAlternateComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveLocalAlternateComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveLocalAlternateComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveSecureMemoryCacheCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveSecureMemoryCacheCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveVectoredContinueHandler +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveVectoredContinueHandler + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveVectoredExceptionHandler +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveVectoredExceptionHandler + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFileA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFileA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFileW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFileW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplacePartitionUnit +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplacePartitionUnit + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RequestDeviceWakeup +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RequestDeviceWakeup + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RequestWakeupLatency +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RequestWakeupLatency + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResetEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResetEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResetWriteWatch +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResetWriteWatch + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResizePseudoConsole +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResizePseudoConsole + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveDelayLoadedAPI +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveDelayLoadedAPI + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveDelayLoadsFromDll +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveDelayLoadsFromDll + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveLocaleName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveLocaleName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RestoreLastError +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RestoreLastError + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResumeThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResumeThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlAddFunctionTable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlAddFunctionTable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCaptureContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCaptureContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCaptureStackBackTrace +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCaptureStackBackTrace + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCompareMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCompareMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCopyMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCopyMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlDeleteFunctionTable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlDeleteFunctionTable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlFillMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlFillMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlInstallFunctionTableCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlInstallFunctionTableCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlIsEcCode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlIsEcCode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlLookupFunctionEntry +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlLookupFunctionEntry + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlMoveMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlMoveMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlPcToFileHeader +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlPcToFileHeader + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlRaiseException +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlRaiseException + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlRestoreContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlRestoreContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlUnwind +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlUnwind + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlUnwindEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlUnwindEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlVirtualUnwind +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlVirtualUnwind + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlVirtualUnwind2 +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlVirtualUnwind2 + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlZeroMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlZeroMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ScrollConsoleScreenBufferA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ScrollConsoleScreenBufferA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ScrollConsoleScreenBufferW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ScrollConsoleScreenBufferW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SearchPathA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SearchPathA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SearchPathW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SearchPathW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCachedSigningLevel +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCachedSigningLevel + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCalendarInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCalendarInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCalendarInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCalendarInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommBreak +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommBreak + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommConfig +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommConfig + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommTimeouts +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommTimeouts + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameEx2W +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameEx2W + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleActiveScreenBuffer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleActiveScreenBuffer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCtrlHandler +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCtrlHandler + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursor +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursor + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursorInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursorInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursorPosition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursorPosition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleDisplayMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleDisplayMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleHistoryInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleHistoryInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleOutputCP +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleOutputCP + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleScreenBufferInfoEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleScreenBufferInfoEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleScreenBufferSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleScreenBufferSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTextAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTextAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTitleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTitleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTitleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTitleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleWindowInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleWindowInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCriticalSectionSpinCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCriticalSectionSpinCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentConsoleFontEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentConsoleFontEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultCommConfigA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultCommConfigA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultCommConfigW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultCommConfigW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultDllDirectories +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultDllDirectories + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDllDirectoryA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDllDirectoryA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDllDirectoryW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDllDirectoryW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDynamicTimeZoneInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDynamicTimeZoneInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEndOfFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEndOfFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentStringsA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentStringsA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentStringsW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentStringsW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentVariableA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentVariableA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentVariableW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentVariableW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetErrorMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetErrorMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEventWhenCallbackReturns +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEventWhenCallbackReturns + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileApisToANSI +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileApisToANSI + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileApisToOEM +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileApisToOEM + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesTransactedA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesTransactedA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesTransactedW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesTransactedW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileBandwidthReservation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileBandwidthReservation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileCompletionNotificationModes +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileCompletionNotificationModes + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileInformationByHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileInformationByHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileIoOverlappedRange +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileIoOverlappedRange + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFilePointer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFilePointer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFilePointerEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFilePointerEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileShortNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileShortNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileShortNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileShortNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileValidData +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileValidData + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableExA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableExA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableExW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableExW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetHandleCount +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetHandleCount + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetHandleInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetHandleInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetInformationJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetInformationJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetIoRateControlInformationJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetIoRateControlInformationJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetIoRingCompletionEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetIoRingCompletionEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLastError +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLastError + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalPrimaryComputerNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalPrimaryComputerNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalPrimaryComputerNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalPrimaryComputerNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocaleInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocaleInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocaleInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocaleInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetMailslotInfo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetMailslotInfo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetMessageWaitingIndicator +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetMessageWaitingIndicator + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetNamedPipeAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetNamedPipeAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetNamedPipeHandleState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetNamedPipeHandleState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetPriorityClass +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetPriorityClass + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessAffinityMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessAffinityMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessAffinityUpdateMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessAffinityUpdateMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDEPPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDEPPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDefaultCpuSetMasks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDefaultCpuSetMasks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDefaultCpuSets +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDefaultCpuSets + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDynamicEHContinuationTargets +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDynamicEHContinuationTargets + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 78 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDynamicEnforcedCetCompatibleRanges +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDynamicEnforcedCetCompatibleRanges + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessMitigationPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessMitigationPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessPriorityBoost +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessPriorityBoost + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessShutdownParameters +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessShutdownParameters + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessWorkingSetSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessWorkingSetSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessWorkingSetSizeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessWorkingSetSizeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProtectedPolicy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProtectedPolicy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSearchPathMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSearchPathMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetStdHandle +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetStdHandle + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetStdHandleEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetStdHandleEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemFileCacheSize +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemFileCacheSize + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemPowerState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemPowerState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemTimeAdjustment +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemTimeAdjustment + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTapeParameters +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTapeParameters + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTapePosition +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTapePosition + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadAffinityMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadAffinityMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadDescription +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadDescription + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadErrorMode +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadErrorMode + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadExecutionState +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadExecutionState + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadGroupAffinity +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadGroupAffinity + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadIdealProcessor +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadIdealProcessor + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadIdealProcessorEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadIdealProcessorEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadLocale +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadLocale + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPreferredUILanguages +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPreferredUILanguages + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPriority +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPriority + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPriorityBoost +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPriorityBoost + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadSelectedCpuSetMasks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadSelectedCpuSetMasks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadSelectedCpuSets +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadSelectedCpuSets + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadStackGuarantee +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadStackGuarantee + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadUILanguage +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadUILanguage + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolStackInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolStackInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolThreadMaximum +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolThreadMaximum + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolThreadMinimum +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolThreadMinimum + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolTimerEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolTimerEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolWait +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolWait + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolWaitEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolWaitEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTimeZoneInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTimeZoneInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTimerQueueTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTimerQueueTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUmsThreadInformation +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUmsThreadInformation + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUnhandledExceptionFilter +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUnhandledExceptionFilter + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUserGeoID +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUserGeoID + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUserGeoName +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUserGeoName + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeLabelA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeLabelA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeLabelW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeLabelW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeMountPointA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeMountPointA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeMountPointW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeMountPointW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetWaitableTimer +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetWaitableTimer + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetWaitableTimerEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetWaitableTimerEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetXStateFeaturesMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetXStateFeaturesMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetupComm +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetupComm + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SignalObjectAndWait +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SignalObjectAndWait + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SizeofResource +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SizeofResource + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 39 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Sleep +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Sleep + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepConditionVariableCS +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepConditionVariableCS + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepConditionVariableSRW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepConditionVariableSRW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_StartThreadpoolIo +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 StartThreadpoolIo + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SubmitIoRing +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SubmitIoRing + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SubmitThreadpoolWork +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SubmitThreadpoolWork + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SuspendThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SuspendThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SwitchToFiber +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SwitchToFiber + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SwitchToThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SwitchToThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToFileTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToFileTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToTzSpecificLocalTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToTzSpecificLocalTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToTzSpecificLocalTimeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToTzSpecificLocalTimeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateJobObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateJobObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Thread32First +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Thread32First + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Thread32Next +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Thread32Next + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsGetValue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsGetValue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsSetValue +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsSetValue + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Toolhelp32ReadProcessMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Toolhelp32ReadProcessMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TransactNamedPipe +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TransactNamedPipe + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TransmitCommChar +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TransmitCommChar + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryAcquireSRWLockExclusive +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryAcquireSRWLockExclusive + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryAcquireSRWLockShared +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryAcquireSRWLockShared + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryEnterCriticalSection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryEnterCriticalSection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TrySubmitThreadpoolCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TrySubmitThreadpoolCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TzSpecificLocalTimeToSystemTime +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TzSpecificLocalTimeToSystemTime + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TzSpecificLocalTimeToSystemTimeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TzSpecificLocalTimeToSystemTimeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UmsThreadYield +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UmsThreadYield + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnhandledExceptionFilter +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnhandledExceptionFilter + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnlockFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnlockFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnlockFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnlockFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnmapViewOfFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnmapViewOfFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnmapViewOfFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnmapViewOfFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterApplicationRecoveryCallback +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterApplicationRecoveryCallback + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterApplicationRestart +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterApplicationRestart + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterBadMemoryNotification +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterBadMemoryNotification + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWait +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWait + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWaitEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWaitEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWaitUntilOOBECompleted +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWaitUntilOOBECompleted + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateProcThreadAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateProcThreadAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateResourceA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateResourceA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateResourceW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateResourceW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerLanguageNameA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerLanguageNameA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerLanguageNameW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerLanguageNameW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerSetConditionMask +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerSetConditionMask + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyScripts +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyScripts + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyVersionInfoA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyVersionInfoA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyVersionInfoW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyVersionInfoW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAlloc +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAlloc + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAllocEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAllocEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAllocExNuma +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAllocExNuma + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualFree +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualFree + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualFreeEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualFreeEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualLock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualLock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualProtect +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualProtect + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualProtectEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualProtectEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualQuery +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualQuery + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualQueryEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualQueryEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualUnlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualUnlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WTSGetActiveConsoleSessionId +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WTSGetActiveConsoleSessionId + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitCommEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitCommEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForDebugEvent +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForDebugEvent + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForDebugEventEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForDebugEventEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForMultipleObjects +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForMultipleObjects + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForMultipleObjectsEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForMultipleObjectsEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForSingleObject +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForSingleObject + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForSingleObjectEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForSingleObjectEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolIoCallbacks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolIoCallbacks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolTimerCallbacks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolTimerCallbacks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolWaitCallbacks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolWaitCallbacks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolWorkCallbacks +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolWorkCallbacks + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitNamedPipeA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitNamedPipeA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitNamedPipeW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitNamedPipeW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WakeAllConditionVariable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WakeAllConditionVariable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WakeConditionVariable +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WakeConditionVariable + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerGetFlags +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerGetFlags + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterAdditionalProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterAdditionalProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterAppLocalDump +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterAppLocalDump + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterCustomMetadata +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterCustomMetadata + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterExcludedMemoryBlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterExcludedMemoryBlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterMemoryBlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterMemoryBlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterRuntimeExceptionModule +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterRuntimeExceptionModule + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerSetFlags +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerSetFlags + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterAdditionalProcess +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterAdditionalProcess + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterAppLocalDump +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterAppLocalDump + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterCustomMetadata +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterCustomMetadata + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterExcludedMemoryBlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterExcludedMemoryBlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterMemoryBlock +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterMemoryBlock + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterRuntimeExceptionModule +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterRuntimeExceptionModule + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerpInitiateRemoteRecovery +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerpInitiateRemoteRecovery + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WideCharToMultiByte +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WideCharToMultiByte + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WinExec +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WinExec + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64DisableWow64FsRedirection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64DisableWow64FsRedirection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64EnableWow64FsRedirection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64EnableWow64FsRedirection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64GetThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64GetThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64GetThreadSelectorEntry +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64GetThreadSelectorEntry + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64RevertWow64FsRedirection +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64RevertWow64FsRedirection + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64SetThreadContext +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64SetThreadContext + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64SuspendThread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64SuspendThread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleInputA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleInputA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleInputW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleInputW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputAttribute +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputAttribute + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputCharacterA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputCharacterA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputCharacterW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputCharacterW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFile +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFile + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFileEx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFileEx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFileGather +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFileGather + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileSectionA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileSectionA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileSectionW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileSectionW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStructA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStructA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStructW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStructW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProcessMemory +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProcessMemory + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileSectionA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileSectionA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileSectionW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileSectionW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileStringA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileStringA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileStringW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileStringW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteTapemark +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteTapemark + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ZombifyActCtx +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ZombifyActCtx + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__hread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _hread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__hwrite +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _hwrite + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lclose +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lclose + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lcreat +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lcreat + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__llseek +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _llseek + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lopen +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lopen + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lread +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lread + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lwrite +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lwrite + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcat +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcat + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcatA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcatA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcatW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcatW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmp +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmp + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpi +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpi + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpiA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpiA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpiW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpiW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyn +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyn + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpynA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpynA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpynW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpynW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlen +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlen + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlenA +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlenA + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlenW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlenW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrcmpW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrcmpW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrcmpiW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrcmpiW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrlenW +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrlenW + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcschr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcschr + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcscpy +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcscpy + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcsicmp +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcsicmp + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcslen +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcslen + +C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file + +--------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll +[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcsrchr +[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcsrchr diff --git a/libwild/Cargo.toml b/libwild/Cargo.toml index c3ebbba2a..272c32b55 100644 --- a/libwild/Cargo.toml +++ b/libwild/Cargo.toml @@ -45,6 +45,7 @@ sharded-vec-writer = { workspace = true } smallvec = { workspace = true } symbolic-common = { workspace = true } symbolic-demangle = { workspace = true } +target-lexicon = "0.13" thread_local = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } @@ -56,6 +57,20 @@ zstd = { workspace = true } [target.'cfg(all(target_os = "linux", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies] perf-event = { workspace = true } +[target.'cfg(target_os = "windows")'.dependencies] +phnt = { workspace = true } + +[target.'cfg(target_os = "windows")'.dependencies.windows-sys] +workspace = true +features = [ + "Win32_System_Threading", + "Win32_System_Console", + "Win32_System_Pipes", + "Win32_Security", + "Win32_Storage_FileSystem", + "Win32_System_IO", +] + [dev-dependencies] ar = { workspace = true } tempfile = { workspace = true } diff --git a/libwild/src/arch.rs b/libwild/src/arch.rs index 6edd35f36..965f58ad6 100644 --- a/libwild/src/arch.rs +++ b/libwild/src/arch.rs @@ -14,6 +14,29 @@ pub(crate) enum Architecture { LoongArch64, } +impl Default for Architecture { + fn default() -> Self { + Architecture::DEFAULT + } +} + +impl Architecture { + pub const DEFAULT: Self = const { + #[cfg(target_arch = "x86_64")] + { + Architecture::X86_64 + } + #[cfg(target_arch = "aarch64")] + { + Architecture::AArch64 + } + #[cfg(target_arch = "riscv64")] + { + Architecture::RISCV64 + } + }; +} + impl TryFrom for Architecture { type Error = crate::error::Error; diff --git a/libwild/src/archive.rs b/libwild/src/archive.rs index 1db4fac6b..732337b3b 100644 --- a/libwild/src/archive.rs +++ b/libwild/src/archive.rs @@ -3,8 +3,10 @@ //! dependency in our tests so that we can verify consistency. use crate::error::Result; +#[cfg(unix)] use std::ffi::OsStr; use std::ops::Range; +#[cfg(unix)] use std::os::unix::ffi::OsStrExt as _; use std::path::Path; @@ -94,7 +96,17 @@ impl<'data> Identifier<'data> { } pub(crate) fn as_path(&self) -> &'data std::path::Path { - Path::new(OsStr::from_bytes(self.as_slice())) + #[cfg(unix)] + { + Path::new(OsStr::from_bytes(self.as_slice())) + } + #[cfg(not(unix))] + { + // Archive member names are essentially always UTF-8/ASCII. + let s = std::str::from_utf8(self.as_slice()) + .expect("archive member name is not valid UTF-8"); + Path::new(s) + } } } diff --git a/libwild/src/args/consts.rs b/libwild/src/args/consts.rs new file mode 100644 index 000000000..7a6363a4b --- /dev/null +++ b/libwild/src/args/consts.rs @@ -0,0 +1,64 @@ +pub const WILD_UNSUPPORTED_ENV: &str = "WILD_UNSUPPORTED"; +pub const VALIDATE_ENV: &str = "WILD_VALIDATE_OUTPUT"; +pub const WRITE_LAYOUT_ENV: &str = "WILD_WRITE_LAYOUT"; +pub const WRITE_TRACE_ENV: &str = "WILD_WRITE_TRACE"; +pub const REFERENCE_LINKER_ENV: &str = "WILD_REFERENCE_LINKER"; +pub(crate) const FILES_PER_GROUP_ENV: &str = "WILD_FILES_PER_GROUP"; + +/// Set this environment variable if you get a failure during writing due to too much or too little +/// space being allocated to some section. When set, each time we allocate during layout, we'll +/// check that what we're doing is consistent with writing and fail in a more easy to debug way. i.e +/// we'll report the particular combination of value flags, resolution flags etc that triggered the +/// inconsistency. +pub(crate) const WRITE_VERIFY_ALLOCATIONS_ENV: &str = "WILD_VERIFY_ALLOCATIONS"; + +// These flags don't currently affect our behaviour. TODO: Assess whether we should error or warn if +// these are given. This is tricky though. On the one hand we want to be a drop-in replacement for +// other linkers. On the other, we should perhaps somehow let the user know that we don't support a +// feature. +pub(super) const SILENTLY_IGNORED_FLAGS: &[&str] = &[ + // Just like other modern linkers, we don't need groups in order to resolve cycles. + "start-group", + "end-group", + // TODO: This is supposed to suppress built-in search paths, but I don't think we have any + // built-in search paths. Perhaps we should? + "nostdlib", + // TODO + "no-undefined-version", + "fatal-warnings", + "color-diagnostics", + "undefined-version", + "sort-common", + "stats", +]; +pub(super) const SILENTLY_IGNORED_SHORT_FLAGS: &[&str] = &[ + "(", + ")", + // On Illumos, the Clang driver inserts a meaningless -C flag before calling any non-GNU ld + // linker. + #[cfg(target_os = "illumos")] + "C", +]; + +pub(super) const IGNORED_FLAGS: &[&str] = &[ + "gdb-index", + "fix-cortex-a53-835769", + "fix-cortex-a53-843419", + "discard-all", + "use-android-relr-tags", + "x", // alias for --discard-all +]; + +// These flags map to the default behavior of the linker. +pub(super) const DEFAULT_FLAGS: &[&str] = &[ + "no-call-graph-profile-sort", + "no-copy-dt-needed-entries", + "no-add-needed", + "discard-locals", + "no-fatal-warnings", + "no-use-android-relr-tags", +]; +pub(super) const DEFAULT_SHORT_FLAGS: &[&str] = &[ + "X", // alias for --discard-locals + "EL", // little endian +]; diff --git a/libwild/src/args.rs b/libwild/src/args/linux.rs similarity index 86% rename from libwild/src/args.rs rename to libwild/src/args/linux.rs index 30434d8fb..f2a86eb3a 100644 --- a/libwild/src/args.rs +++ b/libwild/src/args/linux.rs @@ -65,7 +65,7 @@ pub(crate) enum DefsymValue { } #[derive(Debug)] -pub struct Args { +pub struct ElfArgs { pub(crate) unrecognized_options: Vec, pub(crate) arch: Architecture, @@ -154,6 +154,7 @@ pub struct Args { pub(crate) relocation_model: RelocationModel, pub(crate) should_output_executable: bool, + /// The number of actually available threads (considering jobserver) pub(crate) available_threads: NonZeroUsize, @@ -194,7 +195,7 @@ pub(crate) enum CopyRelocations { /// Represents a command-line argument that specifies the number of threads to use, /// triggering activation of the thread pool. pub struct ActivatedArgs { - pub args: Args, + pub args: ElfArgs, _jobserver_tokens: Vec, } @@ -321,7 +322,7 @@ pub(crate) enum InputSpec { Search(Box), } -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub(crate) enum BSymbolicKind { None, All, @@ -345,74 +346,11 @@ pub(crate) enum UnresolvedSymbols { IgnoreAll, } -pub const WILD_UNSUPPORTED_ENV: &str = "WILD_UNSUPPORTED"; -pub const VALIDATE_ENV: &str = "WILD_VALIDATE_OUTPUT"; -pub const WRITE_LAYOUT_ENV: &str = "WILD_WRITE_LAYOUT"; -pub const WRITE_TRACE_ENV: &str = "WILD_WRITE_TRACE"; -pub const REFERENCE_LINKER_ENV: &str = "WILD_REFERENCE_LINKER"; -pub(crate) const FILES_PER_GROUP_ENV: &str = "WILD_FILES_PER_GROUP"; - -/// Set this environment variable if you get a failure during writing due to too much or too little -/// space being allocated to some section. When set, each time we allocate during layout, we'll -/// check that what we're doing is consistent with writing and fail in a more easy to debug way. i.e -/// we'll report the particular combination of value flags, resolution flags etc that triggered the -/// inconsistency. -pub(crate) const WRITE_VERIFY_ALLOCATIONS_ENV: &str = "WILD_VERIFY_ALLOCATIONS"; - -// These flags don't currently affect our behaviour. TODO: Assess whether we should error or warn if -// these are given. This is tricky though. On the one hand we want to be a drop-in replacement for -// other linkers. On the other, we should perhaps somehow let the user know that we don't support a -// feature. -const SILENTLY_IGNORED_FLAGS: &[&str] = &[ - // Just like other modern linkers, we don't need groups in order to resolve cycles. - "start-group", - "end-group", - // TODO: This is supposed to suppress built-in search paths, but I don't think we have any - // built-in search paths. Perhaps we should? - "nostdlib", - // TODO - "no-undefined-version", - "fatal-warnings", - "color-diagnostics", - "undefined-version", - "sort-common", - "stats", -]; -const SILENTLY_IGNORED_SHORT_FLAGS: &[&str] = &[ - "(", - ")", - // On Illumos, the Clang driver inserts a meaningless -C flag before calling any non-GNU ld - // linker. - #[cfg(target_os = "illumos")] - "C", -]; - -const IGNORED_FLAGS: &[&str] = &[ - "gdb-index", - "fix-cortex-a53-835769", - "fix-cortex-a53-843419", - "discard-all", - "use-android-relr-tags", - "x", // alias for --discard-all -]; - -// These flags map to the default behavior of the linker. -const DEFAULT_FLAGS: &[&str] = &[ - "no-call-graph-profile-sort", - "no-copy-dt-needed-entries", - "no-add-needed", - "discard-locals", - "no-fatal-warnings", - "no-use-android-relr-tags", -]; -const DEFAULT_SHORT_FLAGS: &[&str] = &[ - "X", // alias for --discard-locals - "EL", // little endian -]; - -impl Default for Args { +use super::consts::*; + +impl Default for ElfArgs { fn default() -> Self { - Args { + ElfArgs { arch: default_target_arch(), unrecognized_options: Vec::new(), @@ -504,7 +442,7 @@ impl Default for Args { } // Parse the supplied input arguments, which should not include the program name. -pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { +pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { use crate::input_data::MAX_FILES_PER_GROUP; // SAFETY: Should be called early before other descriptors are opened and @@ -523,7 +461,7 @@ pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F ); } - let mut args = Args { + let mut args = ElfArgs { files_per_group, jobserver_client, ..Default::default() @@ -596,8 +534,8 @@ pub(crate) fn read_args_from_file(path: &Path) -> Result> { arguments_from_string(&contents) } -impl Args { - pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { +impl ElfArgs { + pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { timing_phase!("Parse args"); parse(input) } @@ -817,34 +755,51 @@ fn warn_unsupported(opt: &str) -> Result { Ok(()) } -struct ArgumentParser { - options: HashMap<&'static str, OptionHandler>, - short_options: HashMap<&'static str, OptionHandler>, // Short option lookup - prefix_options: HashMap<&'static str, PrefixOptionHandler>, // For options like -L, -l, etc. +pub(crate) struct ArgumentParser { + options: HashMap<&'static str, OptionHandler>, + short_options: HashMap<&'static str, OptionHandler>, + prefix_options: HashMap<&'static str, PrefixOptionHandler>, + case_insensitive: bool, } -#[derive(Clone)] -struct OptionHandler { +struct OptionHandler { help_text: &'static str, - handler: OptionHandlerFn, + handler: OptionHandlerFn, short_names: Vec<&'static str>, } -struct PrefixOptionHandler { +impl Clone for OptionHandler { + fn clone(&self) -> Self { + Self { + help_text: self.help_text, + handler: self.handler, + short_names: self.short_names.clone(), + } + } +} + +struct PrefixOptionHandler { help_text: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, - sub_options: HashMap<&'static str, SubOption>, + handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>, + sub_options: HashMap<&'static str, SubOption>, } #[allow(clippy::enum_variant_names)] -#[derive(Clone, Copy)] -enum OptionHandlerFn { - NoParam(fn(&mut Args, &mut Vec) -> Result<()>), - WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), - OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), +enum OptionHandlerFn { + NoParam(fn(&mut ArgsType, &mut Vec) -> Result<()>), + WithParam(fn(&mut ArgsType, &mut Vec, &str) -> Result<()>), + OptionalParam(fn(&mut ArgsType, &mut Vec, Option<&str>) -> Result<()>), } -impl OptionHandlerFn { +impl Clone for OptionHandlerFn { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for OptionHandlerFn {} + +impl OptionHandlerFn { fn help_suffix_long(&self) -> &'static str { match self { OptionHandlerFn::NoParam(_) => "", @@ -862,57 +817,82 @@ impl OptionHandlerFn { } } -struct OptionDeclaration<'a, T> { - parser: &'a mut ArgumentParser, +pub(crate) struct OptionDeclaration<'a, ArgsType, T> { + parser: &'a mut ArgumentParser, long_names: Vec<&'static str>, short_names: Vec<&'static str>, prefixes: Vec<&'static str>, - sub_options: HashMap<&'static str, SubOption>, + sub_options: HashMap<&'static str, SubOption>, help_text: &'static str, _phantom: std::marker::PhantomData, } -struct NoParam; -struct WithParam; -struct WithOptionalParam; +pub struct NoParam; +pub struct WithParam; +pub struct WithOptionalParam; -#[derive(Clone, Copy)] -enum SubOptionHandler { +enum SubOptionHandler { /// Handler without value parameter (exact match) - NoValue(fn(&mut Args, &mut Vec) -> Result<()>), + NoValue(fn(&mut ArgsType, &mut Vec) -> Result<()>), /// Handler with value parameter (prefix match) - WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), + WithValue(fn(&mut ArgsType, &mut Vec, &str) -> Result<()>), } -#[derive(Clone, Copy)] -struct SubOption { +impl Clone for SubOptionHandler { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOptionHandler {} + +struct SubOption { help: &'static str, - handler: SubOptionHandler, + handler: SubOptionHandler, } -impl SubOption { +impl Clone for SubOption { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOption {} + +impl SubOption { fn with_value(&self) -> bool { matches!(self.handler, SubOptionHandler::WithValue(_)) } } -impl Default for ArgumentParser { +impl Default for ArgumentParser { fn default() -> Self { Self::new() } } -impl ArgumentParser { +impl ArgumentParser { #[must_use] - fn new() -> Self { + pub fn new() -> Self { Self { options: HashMap::new(), short_options: HashMap::new(), prefix_options: HashMap::new(), + case_insensitive: false, } } - fn declare(&mut self) -> OptionDeclaration<'_, NoParam> { + #[must_use] + pub fn new_case_insensitive() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: true, + } + } + + pub fn declare(&mut self) -> OptionDeclaration<'_, ArgsType, NoParam> { OptionDeclaration { parser: self, long_names: Vec::new(), @@ -924,7 +904,7 @@ impl ArgumentParser { } } - fn declare_with_param(&mut self) -> OptionDeclaration<'_, WithParam> { + pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, ArgsType, WithParam> { OptionDeclaration { parser: self, long_names: Vec::new(), @@ -936,7 +916,9 @@ impl ArgumentParser { } } - fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, WithOptionalParam> { + pub fn declare_with_optional_param( + &mut self, + ) -> OptionDeclaration<'_, ArgsType, WithOptionalParam> { OptionDeclaration { parser: self, long_names: Vec::new(), @@ -948,13 +930,32 @@ impl ArgumentParser { } } - fn handle_argument, I: Iterator>( + fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { + if self.case_insensitive { + if let Some(handler) = self.options.get(option_name) { + return Some(handler); + } + for (key, handler) in &self.options { + if key.eq_ignore_ascii_case(option_name) { + return Some(handler); + } + } + None + } else { + self.options.get(option_name) + } + } + + pub(crate) fn handle_argument, I: Iterator>( &self, - args: &mut Args, + args: &mut ArgsType, modifier_stack: &mut Vec, arg: &str, input: &mut I, - ) -> Result<()> { + ) -> Result<()> + where + ArgsType: super::PrivateArgs, + { // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. // Handle `@file`option (recursively) - merging in the options contained in the file if let Some(path) = arg.strip_prefix('@') { @@ -966,13 +967,13 @@ impl ArgumentParser { return Ok(()); } - if let Some(stripped) = strip_option(arg) { - // Check for option with '=' syntax - if let Some(eq_pos) = stripped.find('=') { + if let Some(stripped) = ArgsType::strip_option(arg) { + // Check for option with separator syntax + if let Some(eq_pos) = ArgsType::find_separator(stripped) { let option_name = &stripped[..eq_pos]; let value = &stripped[eq_pos + 1..]; - if let Some(handler) = self.options.get(option_name) { + if let Some(handler) = self.get_option_handler(option_name) { match &handler.handler { OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, @@ -982,14 +983,14 @@ impl ArgumentParser { } } else { if stripped == "build-id" - && let Some(handler) = self.options.get(stripped) + && let Some(handler) = self.get_option_handler(stripped) && let OptionHandlerFn::WithParam(f) = &handler.handler { f(args, modifier_stack, "fast")?; return Ok(()); } - if let Some(handler) = self.options.get(stripped) { + if let Some(handler) = self.get_option_handler(stripped) { match &handler.handler { OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, OptionHandlerFn::WithParam(f) => { @@ -1068,20 +1069,20 @@ impl ArgumentParser { } } - if arg.starts_with('-') { - if let Some(stripped) = strip_option(arg) + if ArgsType::has_option_prefix(arg) { + if let Some(stripped) = ArgsType::strip_option(arg) && IGNORED_FLAGS.contains(&stripped) { warn_unsupported(arg)?; return Ok(()); } - args.unrecognized_options.push(arg.to_owned()); + args.unrecognized_options_mut().push(arg.to_owned()); return Ok(()); } - args.save_dir.handle_file(arg); - args.inputs.push(Input { + args.save_dir_mut().handle_file(arg); + args.inputs_mut().push(Input { spec: InputSpec::File(Box::from(Path::new(arg))), search_first: None, modifiers: *modifier_stack.last().unwrap(), @@ -1193,36 +1194,36 @@ impl ArgumentParser { } } -impl<'a, T> OptionDeclaration<'a, T> { +impl<'a, ArgsType, T> OptionDeclaration<'a, ArgsType, T> { #[must_use] - fn long(mut self, name: &'static str) -> Self { + pub fn long(mut self, name: &'static str) -> Self { self.long_names.push(name); self } #[must_use] - fn short(mut self, option: &'static str) -> Self { + pub fn short(mut self, option: &'static str) -> Self { self.short_names.push(option); self } #[must_use] - fn help(mut self, text: &'static str) -> Self { + pub fn help(mut self, text: &'static str) -> Self { self.help_text = text; self } - fn prefix(mut self, prefix: &'static str) -> Self { + pub fn prefix(mut self, prefix: &'static str) -> Self { self.prefixes.push(prefix); self } #[must_use] - fn sub_option( + pub fn sub_option( mut self, name: &'static str, help: &'static str, - handler: fn(&mut Args, &mut Vec) -> Result<()>, + handler: fn(&mut ArgsType, &mut Vec) -> Result<()>, ) -> Self { self.sub_options.insert( name, @@ -1235,11 +1236,11 @@ impl<'a, T> OptionDeclaration<'a, T> { } #[must_use] - fn sub_option_with_value( + pub fn sub_option_with_value( mut self, name: &'static str, help: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>, ) -> Self { self.sub_options.insert( name, @@ -1252,8 +1253,8 @@ impl<'a, T> OptionDeclaration<'a, T> { } } -impl<'a> OptionDeclaration<'a, NoParam> { - fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { +impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, NoParam> { + pub fn execute(self, handler: fn(&mut ArgsType, &mut Vec) -> Result<()>) { let option_handler = OptionHandler { help_text: self.help_text, handler: OptionHandlerFn::NoParam(handler), @@ -1272,8 +1273,8 @@ impl<'a> OptionDeclaration<'a, NoParam> { } } -impl<'a> OptionDeclaration<'a, WithParam> { - fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { +impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, WithParam> { + pub fn execute(self, handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>) { let mut short_names = self.short_names.clone(); short_names.extend_from_slice(&self.prefixes); @@ -1305,8 +1306,11 @@ impl<'a> OptionDeclaration<'a, WithParam> { } } -impl<'a> OptionDeclaration<'a, WithOptionalParam> { - fn execute(self, handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>) { +impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, WithOptionalParam> { + pub fn execute( + self, + handler: fn(&mut ArgsType, &mut Vec, Option<&str>) -> Result<()>, + ) { let option_handler = OptionHandler { help_text: self.help_text, handler: OptionHandlerFn::OptionalParam(handler), @@ -1325,18 +1329,14 @@ impl<'a> OptionDeclaration<'a, WithOptionalParam> { } } -fn strip_option(arg: &str) -> Option<&str> { - arg.strip_prefix("--").or(arg.strip_prefix('-')) -} - -fn setup_argument_parser() -> ArgumentParser { +fn setup_argument_parser() -> ArgumentParser { let mut parser = ArgumentParser::new(); parser .declare_with_param() .prefix("L") .help("Add directory to library search path") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { let handle_sysroot = |path| { args.sysroot .as_ref() @@ -1381,7 +1381,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|args, modifier_stack, value| { + .execute(|args: &mut ElfArgs, modifier_stack, value| { let spec = if let Some(stripped) = value.strip_prefix(':') { InputSpec::Search(Box::from(stripped)) } else { @@ -1399,7 +1399,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .prefix("u") .help("Force resolution of the symbol") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.undefined.push(value.to_owned()); Ok(()) }); @@ -1443,7 +1443,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|_args, _modifier_stack, value| { + .execute(|_args: &mut ElfArgs, _modifier_stack, value| { bail!("-m {value} is not yet supported"); }); @@ -1577,7 +1577,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|_args, _modifier_stack, value| { + .execute(|_args: &mut ElfArgs, _modifier_stack, value| { warn_unsupported(&("-z ".to_owned() + value))?; Ok(()) }); @@ -1586,7 +1586,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .prefix("R") .help("Add runtime library search path") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { if Path::new(value).is_file() { args.unrecognized_options .push(format!("-R,{value}(filename)")); @@ -1599,7 +1599,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare_with_param() .prefix("O") - .execute(|_args, _modifier_stack, _value| + .execute(|_args: &mut ElfArgs, _modifier_stack, _value| // We don't use opt-level for now. Ok(())); @@ -1608,7 +1608,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("static") .long("Bstatic") .help("Disallow linking of shared libraries") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().allow_shared = false; Ok(()) }); @@ -1617,7 +1617,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bdynamic") .help("Allow linking of shared libraries") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().allow_shared = true; Ok(()) }); @@ -1627,7 +1627,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("output") .short("o") .help("Set the output filename") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.output = Arc::from(Path::new(value)); Ok(()) }); @@ -1637,7 +1637,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("strip-all") .short("s") .help("Strip all symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.strip = Strip::All; Ok(()) }); @@ -1647,7 +1647,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("strip-debug") .short("S") .help("Strip debug symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.strip = Strip::Debug; Ok(()) }); @@ -1656,7 +1656,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("gc-sections") .help("Enable removal of unused sections") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.gc_sections = true; Ok(()) }); @@ -1665,7 +1665,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-gc-sections") .help("Disable removal of unused sections") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.gc_sections = false; Ok(()) }); @@ -1675,7 +1675,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("shared") .long("Bshareable") .help("Create a shared library") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.should_output_executable = false; Ok(()) }); @@ -1685,7 +1685,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("pie") .long("pic-executable") .help("Create a position-independent executable") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.relocation_model = RelocationModel::Relocatable; args.should_output_executable = true; Ok(()) @@ -1695,7 +1695,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-pie") .help("Do not create a position-dependent executable (default)") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.relocation_model = RelocationModel::NonRelocatable; args.should_output_executable = true; Ok(()) @@ -1705,7 +1705,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("pack-dyn-relocs") .help("Specify dynamic relocation packing format") - .execute(|_args, _modifier_stack, value| { + .execute(|_args: &mut ElfArgs, _modifier_stack, value| { if value != "none" { warn_unsupported(&format!("--pack-dyn-relocs={value}"))?; } @@ -1716,7 +1716,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("help") .help("Show this help message") - .execute(|_args, _modifier_stack| { + .execute(|_args: &mut ElfArgs, _modifier_stack| { let parser = setup_argument_parser(); println!("{}", parser.generate_help()); @@ -1731,7 +1731,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("version") .help("Show version information and exit") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.version_mode = VersionMode::ExitAfterPrint; Ok(()) }); @@ -1740,7 +1740,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .short("v") .help("Print version and continue linking") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.version_mode = VersionMode::Verbose; Ok(()) }); @@ -1749,7 +1749,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("demangle") .help("Enable symbol demangling") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.demangle = true; Ok(()) }); @@ -1758,7 +1758,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-demangle") .help("Disable symbol demangling") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.demangle = false; Ok(()) }); @@ -1767,7 +1767,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("time") .help("Show timing information") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { match value { Some(v) => args.time_phase_options = Some(parse_time_phase_options(v)?), None => args.time_phase_options = Some(Vec::new()), @@ -1779,7 +1779,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dynamic-linker") .help("Set dynamic linker path") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.dynamic_linker = Some(Box::from(Path::new(value))); Ok(()) }); @@ -1788,7 +1788,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-dynamic-linker") .help("Omit the load-time dynamic linker request") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.dynamic_linker = None; Ok(()) }); @@ -1797,7 +1797,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("mmap-output-file") .help("Write output file using mmap (default)") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.mmap_output_file = true; Ok(()) }); @@ -1806,7 +1806,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-mmap-output-file") .help("Write output file without mmap") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.mmap_output_file = false; Ok(()) }); @@ -1816,7 +1816,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("entry") .short("e") .help("Set the entry point") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.entry = Some(value.to_owned()); Ok(()) }); @@ -1825,7 +1825,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("threads") .help("Use multiple threads for linking") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { match value { Some(v) => { args.num_threads = Some(NonZeroUsize::try_from(v.parse::()?)?); @@ -1841,7 +1841,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-threads") .help("Use a single thread") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.num_threads = Some(NonZeroUsize::new(1).unwrap()); Ok(()) }); @@ -1850,7 +1850,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("wild-experiments") .help("List of numbers. Used to tweak internal parameters. '_' keeps default value.") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.numeric_experiments = value .split(',') .map(|p| { @@ -1868,7 +1868,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("as-needed") .help("Set DT_NEEDED if used") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().as_needed = true; Ok(()) }); @@ -1877,7 +1877,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-as-needed") .help("Always set DT_NEEDED") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().as_needed = false; Ok(()) }); @@ -1886,7 +1886,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("whole-archive") .help("Include all objects from archives") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().whole_archive = true; Ok(()) }); @@ -1895,7 +1895,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-whole-archive") .help("Disable --whole-archive") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().whole_archive = false; Ok(()) }); @@ -1904,7 +1904,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("push-state") .help("Save current linker flags") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.push(*modifier_stack.last().unwrap()); Ok(()) }); @@ -1913,7 +1913,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("pop-state") .help("Restore previous linker flags") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.pop(); if modifier_stack.is_empty() { bail!("Mismatched --pop-state"); @@ -1925,7 +1925,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("eh-frame-hdr") .help("Create .eh_frame_hdr section") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.should_write_eh_frame_hdr = true; Ok(()) }); @@ -1934,7 +1934,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-eh-frame-hdr") .help("Don't create .eh_frame_hdr section") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.should_write_eh_frame_hdr = false; Ok(()) }); @@ -1944,7 +1944,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("export-dynamic") .short("E") .help("Export all dynamic symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.export_all_dynamic_symbols = true; Ok(()) }); @@ -1953,7 +1953,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-export-dynamic") .help("Do not export dynamic symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.export_all_dynamic_symbols = false; Ok(()) }); @@ -1963,7 +1963,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("soname") .prefix("h") .help("Set shared object name") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.soname = Some(value.to_owned()); Ok(()) }); @@ -1972,7 +1972,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("rpath") .help("Add directory to runtime library search path") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.rpath_set.insert(value.to_string()); Ok(()) }); @@ -1981,7 +1981,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-string-merge") .help("Disable section merging") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.merge_sections = false; Ok(()) }); @@ -1990,7 +1990,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-undefined") .help("Do not allow unresolved symbols in object files") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.no_undefined = true; Ok(()) }); @@ -1999,7 +1999,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("allow-multiple-definition") .help("Allow multiple definitions of symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.allow_multiple_definitions = true; Ok(()) }); @@ -2008,7 +2008,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("relax") .help("Enable target-specific optimization (instruction relaxation)") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.relax = true; Ok(()) }); @@ -2017,7 +2017,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-relax") .help("Disable relaxation") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.relax = false; Ok(()) }); @@ -2025,7 +2025,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("validate-output") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.validate_output = true; Ok(()) }); @@ -2033,7 +2033,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("write-layout") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.write_layout = true; Ok(()) }); @@ -2041,7 +2041,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("write-trace") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.write_trace = true; Ok(()) }); @@ -2050,7 +2050,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("got-plt-syms") .help("Write symbol table entries that point to the GOT/PLT entry for symbols") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.got_plt_syms = true; Ok(()) }); @@ -2059,7 +2059,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic") .help("Bind global references locally") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.b_symbolic = BSymbolicKind::All; Ok(()) }); @@ -2068,7 +2068,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-functions") .help("Bind global function references locally") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.b_symbolic = BSymbolicKind::Functions; Ok(()) }); @@ -2077,7 +2077,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-non-weak-functions") .help("Bind non-weak global function references locally") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.b_symbolic = BSymbolicKind::NonWeakFunctions; Ok(()) }); @@ -2086,7 +2086,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-non-weak") .help("Bind non-weak global references locally") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.b_symbolic = BSymbolicKind::NonWeak; Ok(()) }); @@ -2095,7 +2095,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bno-symbolic") .help("Do not bind global symbol references locally") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.b_symbolic = BSymbolicKind::None; Ok(()) }); @@ -2104,7 +2104,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("thread-count") .help("Set the number of threads to use") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.num_threads = Some(NonZeroUsize::try_from(value.parse::()?)?); Ok(()) }); @@ -2113,7 +2113,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("exclude-libs") .help("Exclude libraries") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { for lib in value.split([',', ':']) { if lib.is_empty() { continue; @@ -2144,7 +2144,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("version-script") .help("Use version script") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.save_dir.handle_file(value); args.version_script_path = Some(PathBuf::from(value)); Ok(()) @@ -2155,7 +2155,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("script") .prefix("T") .help("Use linker script") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.save_dir.handle_file(value); args.add_script(value); Ok(()) @@ -2165,7 +2165,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("export-dynamic-symbol") .help("Export dynamic symbol") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.export_list.push(value.to_owned()); Ok(()) }); @@ -2174,7 +2174,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("export-dynamic-symbol-list") .help("Export dynamic symbol list") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.export_list_path = Some(PathBuf::from(value)); Ok(()) }); @@ -2183,7 +2183,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dynamic-list") .help("Read the dynamic symbol list from a file") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.b_symbolic = BSymbolicKind::All; args.export_list_path = Some(PathBuf::from(value)); Ok(()) @@ -2193,7 +2193,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("write-gc-stats") .help("Write GC statistics") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.write_gc_stats = Some(PathBuf::from(value)); Ok(()) }); @@ -2202,7 +2202,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("gc-stats-ignore") .help("Ignore files in GC stats") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.gc_stats_ignore.push(value.to_owned()); Ok(()) }); @@ -2211,7 +2211,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-identity-comment") .help("Don't write the linker name and version in .comment") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.should_write_linker_identity = false; Ok(()) }); @@ -2220,7 +2220,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("debug-address") .help("Set debug address") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.debug_address = Some(parse_number(value).context("Invalid --debug-address")?); Ok(()) }); @@ -2228,7 +2228,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare_with_param() .long("debug-fuel") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.debug_fuel = Some(AtomicI64::new(value.parse()?)); args.num_threads = Some(NonZeroUsize::new(1).unwrap()); Ok(()) @@ -2238,7 +2238,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("unresolved-symbols") .help("Specify how to handle unresolved symbols") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.unresolved_symbols = match value { "report-all" => UnresolvedSymbols::ReportAll, "ignore-in-shared-libs" => UnresolvedSymbols::IgnoreInSharedLibs, @@ -2253,7 +2253,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("undefined") .help("Force resolution of the symbol") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.undefined.push(value.to_owned()); Ok(()) }); @@ -2262,7 +2262,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("wrap") .help("Use a wrapper function") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.wrap.push(value.to_owned()); Ok(()) }); @@ -2271,7 +2271,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("defsym") .help("Define a symbol alias: --defsym=symbol=value") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { let parts: Vec<&str> = value.splitn(2, '=').collect(); if parts.len() != 2 { bail!("Invalid --defsym format. Expected: --defsym=symbol=value"); @@ -2289,7 +2289,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("section-start") .help("Set start address for a section: --section-start=.section=address") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { let parts: Vec<&str> = value.splitn(2, '=').collect(); if parts.len() != 2 { bail!("Invalid --section-start format. Expected: --section-start=.section=address"); @@ -2311,7 +2311,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("hash-style") .help("Set hash style") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.hash_style = match value { "gnu" => HashStyle::Gnu, "sysv" => HashStyle::Sysv, @@ -2325,7 +2325,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("enable-new-dtags") .help("Use DT_RUNPATH and DT_FLAGS/DT_FLAGS_1 (default)") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.enable_new_dtags = true; Ok(()) }); @@ -2334,7 +2334,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("disable-new-dtags") .help("Use DT_RPATH and individual dynamic entries instead of DT_FLAGS") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.enable_new_dtags = false; Ok(()) }); @@ -2346,7 +2346,7 @@ fn setup_argument_parser() -> ArgumentParser { "Filter symtab to contain only symbols listed in the supplied file. \ One symbol per line.", ) - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { // The performance this flag is not especially optimised. For one, we copy each string // to the heap. We also do two lookups in the hashset for each symbol. This is a pretty // obscure flag that we don't expect to be used much, so at this stage, it doesn't seem @@ -2372,7 +2372,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("build-id") .help("Generate build ID") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.build_id = match value { "none" => BuildIdOption::None, "fast" | "md5" | "sha1" => BuildIdOption::Fast, @@ -2394,7 +2394,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("icf") .help("Enable identical code folding (merge duplicate functions)") - .execute(|_args, _modifier_stack, value| { + .execute(|_args: &mut ElfArgs, _modifier_stack, value| { match value { "none" => {} other => warn_unsupported(&format!("--icf={other}"))?, @@ -2406,7 +2406,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("sysroot") .help("Set system root") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.save_dir.handle_file(value); let sysroot = std::fs::canonicalize(value).unwrap_or_else(|_| PathBuf::from(value)); args.sysroot = Some(Box::from(sysroot.as_path())); @@ -2423,7 +2423,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("auxiliary") .short("f") .help("Set DT_AUXILIARY to a given value") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.auxiliary.push(value.to_owned()); Ok(()) }); @@ -2432,7 +2432,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("plugin-opt") .help("Pass options to the plugin") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.plugin_args .push(CString::new(value).context("Invalid --plugin-opt argument")?); Ok(()) @@ -2442,7 +2442,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dependency-file") .help("Write dependency rules") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.dependency_file = Some(PathBuf::from(value)); Ok(()) }); @@ -2451,7 +2451,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("plugin") .help("Load plugin") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.plugin_path = Some(value.to_owned()); Ok(()) }); @@ -2460,7 +2460,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("rpath-link") .help("Add runtime library search path") - .execute(|_args, _modifier_stack, _value| { + .execute(|_args: &mut ElfArgs, _modifier_stack, _value| { // TODO Ok(()) }); @@ -2469,7 +2469,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("sym-info") .help("Show symbol information. Accepts symbol name or ID.") - .execute(|args, _modifier_stack, value| { + .execute(|args: &mut ElfArgs, _modifier_stack, value| { args.sym_info = Some(value.to_owned()); Ok(()) }); @@ -2478,7 +2478,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("start-lib") .help("Start library group") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().archive_semantics = true; Ok(()) }); @@ -2487,7 +2487,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("end-lib") .help("End library group") - .execute(|_args, modifier_stack| { + .execute(|_args: &mut ElfArgs, modifier_stack| { modifier_stack.last_mut().unwrap().archive_semantics = false; Ok(()) }); @@ -2496,7 +2496,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-fork") .help("Do not fork while linking") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.should_fork = false; Ok(()) }); @@ -2505,7 +2505,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("update-in-place") .help("Update file in place") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.file_write_mode = Some(FileWriteMode::UpdateInPlace); Ok(()) }); @@ -2514,7 +2514,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-update-in-place") .help("Delete and recreate the file") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.file_write_mode = Some(FileWriteMode::UnlinkAndReplace); Ok(()) }); @@ -2523,7 +2523,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("EB") .help("Big-endian (not supported)") - .execute(|_args, _modifier_stack| { + .execute(|_args: &mut ElfArgs, _modifier_stack| { bail!("Big-endian target is not supported"); }); @@ -2531,7 +2531,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("prepopulate-maps") .help("Prepopulate maps") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.prepopulate_maps = true; Ok(()) }); @@ -2540,7 +2540,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("verbose-gc-stats") .help("Show GC statistics") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.verbose_gc_stats = true; Ok(()) }); @@ -2549,7 +2549,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("allow-shlib-undefined") .help("Allow undefined symbol references in shared libraries") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.allow_shlib_undefined = true; Ok(()) }); @@ -2558,7 +2558,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-allow-shlib-undefined") .help("Disallow undefined symbol references in shared libraries") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.allow_shlib_undefined = false; Ok(()) }); @@ -2567,7 +2567,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("error-unresolved-symbols") .help("Treat unresolved symbols as errors") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.error_unresolved_symbols = true; Ok(()) }); @@ -2576,7 +2576,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("warn-unresolved-symbols") .help("Treat unresolved symbols as warnings") - .execute(|args, _modifier_stack| { + .execute(|args: &mut ElfArgs, _modifier_stack| { args.error_unresolved_symbols = false; Ok(()) }); @@ -2587,30 +2587,12 @@ fn setup_argument_parser() -> ArgumentParser { parser } -fn add_silently_ignored_flags(parser: &mut ArgumentParser) { - for flag in SILENTLY_IGNORED_FLAGS { - let mut declaration = parser.declare(); - declaration = declaration.long(flag); - declaration.execute(|_args, _modifier_stack| Ok(())); - } - for flag in SILENTLY_IGNORED_SHORT_FLAGS { - let mut declaration = parser.declare(); - declaration = declaration.short(flag); - declaration.execute(|_args, _modifier_stack| Ok(())); - } +fn add_silently_ignored_flags(parser: &mut ArgumentParser) { + super::add_silently_ignored_flags(parser); } -fn add_default_flags(parser: &mut ArgumentParser) { - for flag in DEFAULT_FLAGS { - let mut declaration = parser.declare(); - declaration = declaration.long(flag); - declaration.execute(|_args, _modifier_stack| Ok(())); - } - for flag in DEFAULT_SHORT_FLAGS { - let mut declaration = parser.declare(); - declaration = declaration.short(flag); - declaration.execute(|_args, _modifier_stack| Ok(())); - } +fn add_default_flags(parser: &mut ArgumentParser) { + super::add_default_flags(parser); } fn parse_time_phase_options(input: &str) -> Result> { @@ -2654,11 +2636,61 @@ impl Display for CopyRelocationsDisabledReason { } } +impl super::PrivateArgs for ElfArgs { + fn new_default() -> Self { + Self::default() + } + + fn save_dir_mut(&mut self) -> &mut crate::save_dir::SaveDir { + &mut self.save_dir + } + + fn inputs_mut(&mut self) -> &mut Vec { + &mut self.inputs + } + + fn unrecognized_options_mut(&mut self) -> &mut Vec { + &mut self.unrecognized_options + } + + fn files_per_group_mut(&mut self) -> &mut Option { + &mut self.files_per_group + } + + fn jobserver_client_mut(&mut self) -> &mut Option { + &mut self.jobserver_client + } + + fn write_layout_mut(&mut self) -> &mut bool { + &mut self.write_layout + } + + fn write_trace_mut(&mut self) -> &mut bool { + &mut self.write_trace + } + + fn setup_argument_parser() -> ArgumentParser { + setup_argument_parser() + } + + fn has_option_prefix(arg: &str) -> bool { + arg.starts_with('-') + } + + fn strip_option<'a>(arg: &'a str) -> Option<&'a str> { + arg.strip_prefix("--").or(arg.strip_prefix('-')) + } + + fn find_separator(stripped: &str) -> Option { + stripped.find('=') + } +} + #[cfg(test)] mod tests { use super::SILENTLY_IGNORED_FLAGS; use super::VersionMode; - use crate::Args; + use crate::args::ElfArgs; use crate::args::InputSpec; use itertools::Itertools; use std::fs::File; @@ -2803,7 +2835,7 @@ mod tests { assert!(c.iter().any(|p| p.as_ref() == Path::new(v))); } - fn input1_assertions(args: &Args) { + fn input1_assertions(args: &ElfArgs) { assert_eq!( args.inputs .iter() @@ -2842,7 +2874,7 @@ mod tests { ); } - fn inline_and_file_options_assertions(args: &Args) { + fn inline_and_file_options_assertions(args: &ElfArgs) { assert_contains(&args.lib_search_path, "/lib"); } diff --git a/libwild/src/args/mod.rs b/libwild/src/args/mod.rs new file mode 100644 index 000000000..b8b2a696e --- /dev/null +++ b/libwild/src/args/mod.rs @@ -0,0 +1,473 @@ +//! A handwritten parser for our arguments. +//! +//! We don't currently use a 3rd party library like clap for a few reasons. Firstly, we need to +//! support flags like `--push-state` and `--pop-state`. These need to push and pop a state stack +//! when they're parsed. Some of the other flags then need to manipulate the state of the top of the +//! stack. Positional arguments like input files and libraries to link, then need to have the +//! current state of the stack attached to that file. +//! +//! Secondly, long arguments need to also be accepted with a single '-' in addition to the more +//! common double-dash. +//! +//! Basically, we need to be able to parse arguments in the same way as the other linkers on the +//! platform that we're targeting. + +mod consts; +pub mod linux; +pub mod windows; + +pub use consts::*; + +// Re-export everything from linux.rs for backward compatibility. +// The rest of the crate uses `crate::args::Args`, `crate::args::FileWriteMode`, etc. +// and this re-export ensures those paths continue to work. +pub use linux::*; + +// Re-export types that sub-modules (windows.rs, parser.rs) need via `super::*`. +pub(crate) use crate::arch::Architecture; +pub(crate) use crate::output_kind::OutputKind; +pub(crate) use crate::save_dir::SaveDir; + +use crate::bail; +use crate::save_dir; +use crate::error::Result; +use crate::target_os::Os; +use jobserver::Client; +use target_lexicon::Triple; + +#[allow(dead_code)] +/// Trait providing mutable access to shared fields during argument parsing. +/// +/// This trait is used by the generic `ArgumentParser` to access fields +/// that both Linux and Windows argument structs share. It also defines platform-specific +/// parsing helpers (option prefix detection, separator detection). +pub(crate) trait PrivateArgs { + fn new_default() -> Self; + fn save_dir_mut(&mut self) -> &mut save_dir::SaveDir; + fn inputs_mut(&mut self) -> &mut Vec; + fn unrecognized_options_mut(&mut self) -> &mut Vec; + fn files_per_group_mut(&mut self) -> &mut Option; + fn jobserver_client_mut(&mut self) -> &mut Option; + fn write_layout_mut(&mut self) -> &mut bool; + fn write_trace_mut(&mut self) -> &mut bool; + fn setup_argument_parser() -> linux::ArgumentParser + where + Self: Sized; + + /// Check if argument has a valid option prefix for this platform. + /// Linux: `-`, Windows: `/` or `-`. + fn has_option_prefix(arg: &str) -> bool; + + /// Strip the option prefix(es) from an argument. + /// Linux: `--` or `-`, Windows: `/` or `-`. + fn strip_option<'a>(arg: &'a str) -> Option<&'a str>; + + /// Find the key=value separator position in a stripped option. + /// Linux: `=`, Windows: `:` or `=`. + fn find_separator(stripped: &str) -> Option; +} + +pub(crate) fn add_silently_ignored_flags( + parser: &mut linux::ArgumentParser, +) { + fn noop(_args: &mut T, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in SILENTLY_IGNORED_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in SILENTLY_IGNORED_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +pub(crate) fn add_default_flags(parser: &mut linux::ArgumentParser) { + fn noop(_args: &mut T, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in DEFAULT_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in DEFAULT_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +/// The output binary format. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum OutputFormat { + Elf, + Pe, +} + +impl Default for OutputFormat { + fn default() -> Self { + match Os::DEFAULT { + Os::Linux => OutputFormat::Elf, + Os::Windows => OutputFormat::Pe, + Os::MacOS => todo!("macOS linking not yet supported"), + } + } +} + +/// Result of pre-scanning args for target-determining flags. +#[derive(Debug)] +pub(crate) struct DetectedTarget { + pub format: OutputFormat, + /// Architecture from `--target` triple. `None` if no `--target` was given. + pub arch: Option, +} + +/// Known `-m` emulation values that imply ELF output. +const ELF_EMULATIONS: &[&str] = &[ + "elf_x86_64", + "elf_x86_64_sol2", + "aarch64elf", + "aarch64linux", + "elf64lriscv", + "elf64loongarch", +]; + +/// Map `target_lexicon::Architecture` to Wild's `Architecture`. +fn map_triple_arch(arch: target_lexicon::Architecture) -> Result { + use target_lexicon::Architecture as TL; + match arch { + TL::X86_64 | TL::X86_64h => Ok(Architecture::X86_64), + TL::Aarch64(_) => Ok(Architecture::AArch64), + TL::Riscv64(_) => Ok(Architecture::RISCV64), + TL::LoongArch64 => Ok(Architecture::LoongArch64), + other => bail!("unsupported architecture in target triple: {other}"), + } +} + +/// Map `target_lexicon::BinaryFormat` to `OutputFormat`. +fn map_binary_format(fmt: target_lexicon::BinaryFormat) -> Result { + match fmt { + target_lexicon::BinaryFormat::Elf => Ok(OutputFormat::Elf), + target_lexicon::BinaryFormat::Coff => Ok(OutputFormat::Pe), + other => bail!("unsupported binary format: {other}"), + } +} + +/// Extract the target triple value from a flag, handling all prefix styles. +/// Returns `(Some(value), consumed_next)` if the arg is a target flag. +fn extract_target_value<'a>(arg: &'a str, next_arg: Option<&'a str>) -> (Option<&'a str>, bool) { + // Combined forms: --target=VAL, -target=VAL, /TARGET:VAL + if let Some(val) = arg + .strip_prefix("--target=") + .or_else(|| arg.strip_prefix("-target=")) + .or_else(|| arg.strip_prefix("/TARGET:")) + .or_else(|| arg.strip_prefix("/target:")) + { + return (Some(val), false); + } + // Space-separated: --target VAL, -target VAL, /TARGET VAL + if matches!(arg, "--target" | "-target" | "/TARGET" | "/target") { + if let Some(val) = next_arg { + return (Some(val), true); + } + } + (None, false) +} + +/// Pre-scan CLI arguments to determine the output format and architecture. +/// +/// Recognizes: +/// - `--target=` / `-target=` / `/TARGET:` — primary (parsed by target-lexicon) +/// - `-m ` — overrides format to ELF when present +/// +/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only. +pub(crate) fn detect_target(args: &[String]) -> Result { + let mut from_triple: Option<(OutputFormat, Architecture)> = None; + let mut m_implies_elf = false; + + let mut i = 0; + while i < args.len() { + let next = if i + 1 < args.len() { + Some(args[i + 1].as_str()) + } else { + None + }; + let (target_val, consumed_next) = extract_target_value(&args[i], next); + + if let Some(val) = target_val { + let triple: Triple = val + .parse() + .map_err(|e| anyhow::anyhow!("invalid target triple '{val}': {e}"))?; + let format = map_binary_format(triple.binary_format)?; + let arch = map_triple_arch(triple.architecture)?; + from_triple = Some((format, arch)); + if consumed_next { + i += 1; + } + } + // Check for -m (implies ELF) + else if args[i] == "-m" || args[i] == "--m" { + if let Some(next_val) = next { + if ELF_EMULATIONS.contains(&next_val) { + m_implies_elf = true; + } + i += 1; + } + } else if let Some(emu) = args[i].strip_prefix("-m") { + if ELF_EMULATIONS.contains(&emu) { + m_implies_elf = true; + } + } + + i += 1; + } + + match (from_triple, m_implies_elf) { + (Some((_, arch)), true) => { + // -m overrides format to ELF; arch from triple preserved + Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: Some(arch), + }) + } + (Some((format, arch)), false) => Ok(DetectedTarget { + format, + arch: Some(arch), + }), + (None, true) => Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: None, + }), + (None, false) => Ok(DetectedTarget { + format: OutputFormat::default(), + arch: None, + }), + } +} + +/// Map Wild `Architecture` to the GNU ld `-m` emulation name. +fn arch_to_elf_emulation(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "elf_x86_64", + Architecture::AArch64 => "aarch64linux", + Architecture::RISCV64 => "elf64lriscv", + Architecture::LoongArch64 => "elf64loongarch", + } +} + +/// Map Wild `Architecture` to the MSVC `/MACHINE:` value. +fn arch_to_machine_value(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "X64", + Architecture::AArch64 => "ARM64", + Architecture::RISCV64 => "X64", + Architecture::LoongArch64 => "X64", + } +} + +/// Strip `--target`/`-target`/`/TARGET` flags and inject a synthetic `-m` or `/MACHINE:` flag +/// from the detected architecture so the format-specific parser picks it up. +/// +/// The user's explicit `-m` or `/MACHINE:` flags are preserved and will override the injected one +/// since they appear later in the argument list. +pub(crate) fn filter_and_inject_target_flags( + args: &[String], + format: OutputFormat, + arch: Option, +) -> Vec { + let mut result = Vec::with_capacity(args.len() + 2); + + // Inject synthetic arch flag at the front (user's explicit flags override later) + if let Some(arch) = arch { + match format { + OutputFormat::Elf => { + result.push("-m".to_string()); + result.push(arch_to_elf_emulation(arch).to_string()); + } + OutputFormat::Pe => { + result.push(format!("/MACHINE:{}", arch_to_machine_value(arch))); + } + } + } + + // Strip --target flags, keep everything else + let mut i = 0; + while i < args.len() { + let arg = &args[i]; + if arg.starts_with("--target=") + || arg.starts_with("-target=") + || arg.starts_with("/TARGET:") + || arg.starts_with("/target:") + { + // Skip this combined arg + } else if matches!(arg.as_str(), "--target" | "-target" | "/TARGET" | "/target") { + i += 1; // skip value too + } else { + result.push(arg.clone()); + } + i += 1; + } + result +} + +/// Format-specific parsed arguments. +pub enum TargetArgs { + Elf(linux::ElfArgs), + #[allow(dead_code)] + Pe(windows::PeArgs), +} + +/// Parsed linker arguments. Shared fields are directly accessible. +/// Format-specific fields are behind the `target_args` enum. +pub struct Args { + pub should_fork: bool, + pub target_args: TargetArgs, +} + +impl Args { + /// Parse CLI arguments. Detects target format from `--target=`, `-m`, + /// or host default, then routes to the format-specific parser. + pub fn parse I, S: AsRef, I: Iterator>( + input: F, + ) -> Result { + let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); + let detected = detect_target(&all_args)?; + let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); + + match detected.format { + OutputFormat::Elf => { + let elf = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; + let should_fork = elf.should_fork(); + Ok(Args { should_fork, target_args: TargetArgs::Elf(elf) }) + } + OutputFormat::Pe => { + let pe = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; + let should_fork = pe.should_fork(); + Ok(Args { should_fork, target_args: TargetArgs::Pe(pe) }) + } + } + } +} + +/// Top-level parse function. +pub fn parse I, S: AsRef, I: Iterator>( + input: F, +) -> Result { + Args::parse(input) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn to_strings(args: &[&str]) -> Vec { + args.iter().map(|s| s.to_string()).collect() + } + + // ---- detect_target tests ---- + + #[test] + fn test_detect_format_from_triple_linux_x86() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_triple_windows() { + let args = to_strings(&["-target=x86_64-pc-windows-msvc", "/OUT:foo.exe"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_slash_target() { + let args = to_strings(&["/TARGET:aarch64-pc-windows-msvc", "foo.obj"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_space_separated() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_from_m_flag() { + let args = to_strings(&["-m", "elf_x86_64", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, None); + } + + #[test] + fn test_m_flag_overrides_target_format() { + let args = to_strings(&["--target=x86_64-pc-windows-msvc", "-m", "elf_x86_64"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + } + + #[test] + fn test_detect_format_default_no_flags() { + let args = to_strings(&["-o", "out", "foo.o"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::default()); + assert_eq!(result.arch, None); + } + + #[test] + fn test_detect_format_riscv_triple() { + let args = to_strings(&["--target=riscv64gc-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::RISCV64)); + } + + // ---- filter_and_inject_target_flags tests ---- + + #[test] + fn test_filter_strips_target_equals() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert_eq!(filtered[2], "-o"); + assert!(!filtered.iter().any(|a| a.contains("--target"))); + } + + #[test] + fn test_filter_strips_target_space() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "aarch64linux"); + assert!(!filtered.iter().any(|a| a == "--target" || a.contains("linux-gnu"))); + } + + #[test] + fn test_filter_strips_slash_target() { + let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "/MACHINE:X64"); + assert_eq!(filtered[1], "/OUT:foo.exe"); + } + + #[test] + fn test_filter_preserves_m_flag() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-m", "aarch64linux", "-o", "out"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert!(filtered.contains(&"-m".to_string())); + assert!(filtered.contains(&"aarch64linux".to_string())); + } + + #[test] + fn test_filter_no_target_no_inject() { + let args = to_strings(&["-o", "out", "foo.o"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, None); + assert_eq!(filtered, args); + } +} diff --git a/libwild/src/args/windows.rs b/libwild/src/args/windows.rs new file mode 100644 index 000000000..ee6de80e5 --- /dev/null +++ b/libwild/src/args/windows.rs @@ -0,0 +1,1586 @@ +use super::*; +use crate::bail; +use crate::ensure; +use jobserver::Client; +use std::num::NonZeroUsize; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum WindowsSubsystem { + Console, + Windows, + Native, + Posix, + BootApplication, + EfiApplication, + EfiBootServiceDriver, + EfiRom, + EfiRuntimeDriver, +} + +pub struct PeArgs { + pub num_threads: Option, + pub(crate) save_dir: SaveDir, + pub(crate) inputs: Vec, + pub(crate) unrecognized_options: Vec, + pub(crate) jobserver_client: Option, + pub(crate) files_per_group: Option, + pub(crate) write_layout: bool, + pub(crate) write_trace: bool, + pub(crate) output_kind: OutputKind, + pub(crate) allow_copy_relocations: bool, + /// The number of actually available threads (considering jobserver) + pub(crate) available_threads: NonZeroUsize, + should_fork: bool, + + // Windows-specific fields + pub(crate) output: Arc, + pub(crate) arch: Architecture, + pub(crate) lib_search_path: Vec>, + pub(crate) base_address: Option, + pub(crate) subsystem: Option, + pub(crate) entry_point: Option, + pub(crate) heap_size: Option, + pub(crate) stack_size: Option, + pub(crate) is_dll: bool, + pub(crate) debug_info: bool, + pub(crate) strip_symbols: bool, + pub(crate) def_file: Option, + pub(crate) import_lib: Option, + pub(crate) manifest_file: Option, + pub(crate) map_file: Option, + pub(crate) pdb_file: Option, + pub(crate) version: Option, + pub(crate) large_address_aware: bool, + pub(crate) dynamic_base: bool, + pub(crate) nx_compat: bool, + pub(crate) terminal_server_aware: bool, + pub(crate) high_entropy_va: bool, + pub(crate) no_default_libs: Vec, + pub(crate) ignore_all_default_libs: bool, +} + +impl Default for PeArgs { + fn default() -> Self { + Self { + save_dir: SaveDir::default(), + inputs: Vec::new(), + num_threads: None, + unrecognized_options: Vec::new(), + jobserver_client: None, + files_per_group: None, + write_layout: false, + write_trace: false, + output_kind: OutputKind::StaticExecutable(RelocationModel::NonRelocatable), + allow_copy_relocations: true, + available_threads: NonZeroUsize::new(1).unwrap(), + should_fork: false, + + // Windows-specific defaults + output: Arc::from(Path::new("a.exe")), + arch: Architecture::X86_64, + lib_search_path: Vec::new(), + base_address: None, + subsystem: None, + entry_point: None, + heap_size: None, + stack_size: None, + is_dll: false, + debug_info: false, + strip_symbols: false, + def_file: None, + import_lib: None, + manifest_file: None, + map_file: None, + pdb_file: None, + version: None, + large_address_aware: true, + dynamic_base: true, + nx_compat: true, + terminal_server_aware: true, + high_entropy_va: true, + no_default_libs: Vec::new(), + ignore_all_default_libs: false, + } + } +} + +impl super::PrivateArgs for PeArgs { + fn new_default() -> Self { + Self::default() + } + + fn save_dir_mut(&mut self) -> &mut SaveDir { + &mut self.save_dir + } + + fn inputs_mut(&mut self) -> &mut Vec { + &mut self.inputs + } + + fn unrecognized_options_mut(&mut self) -> &mut Vec { + &mut self.unrecognized_options + } + + fn files_per_group_mut(&mut self) -> &mut Option { + &mut self.files_per_group + } + + fn jobserver_client_mut(&mut self) -> &mut Option { + &mut self.jobserver_client + } + + fn write_layout_mut(&mut self) -> &mut bool { + &mut self.write_layout + } + + fn write_trace_mut(&mut self) -> &mut bool { + &mut self.write_trace + } + + fn setup_argument_parser() -> ArgumentParser + where + Self: Sized, + { + setup_windows_argument_parser() + } + + fn has_option_prefix(arg: &str) -> bool { + arg.starts_with('/') || arg.starts_with('-') + } + + fn strip_option<'a>(arg: &'a str) -> Option<&'a str> { + arg.strip_prefix('/').or(arg.strip_prefix('-')) + } + + fn find_separator(stripped: &str) -> Option { + stripped.find(':') + } +} + +impl PeArgs { + pub fn should_fork(&self) -> bool { + self.should_fork + } + + pub fn output_kind(&self) -> OutputKind { + self.output_kind + } + + /// Check if a specific library should be ignored due to /NODEFAULTLIB + pub fn should_ignore_default_lib(&self, lib_name: &str) -> bool { + self.ignore_all_default_libs || self.no_default_libs.contains(&lib_name.to_string()) + } + + /// Get the list of specifically ignored default libraries + pub fn ignored_default_libs(&self) -> &[String] { + &self.no_default_libs + } + + /// Check if all default libraries should be ignored + pub fn ignores_all_default_libs(&self) -> bool { + self.ignore_all_default_libs + } +} + +/// Parse Windows linker arguments from the given input iterator. +pub(crate) fn parse I, S: AsRef, I: Iterator>( + input: F, +) -> Result { + use crate::input_data::MAX_FILES_PER_GROUP; + + // SAFETY: Should be called early before other descriptors are opened. + let jobserver_client = unsafe { Client::from_env() }; + + let files_per_group: Option = std::env::var(FILES_PER_GROUP_ENV) + .ok() + .map(|s| s.parse()) + .transpose()?; + + if let Some(x) = files_per_group { + ensure!( + x <= MAX_FILES_PER_GROUP, + "{FILES_PER_GROUP_ENV}={x} but maximum is {MAX_FILES_PER_GROUP}" + ); + } + + let mut args = PeArgs { + files_per_group, + jobserver_client, + ..Default::default() + }; + + args.save_dir = SaveDir::new(&input)?; + + let mut input = input(); + + let mut modifier_stack = vec![Modifiers::default()]; + + if std::env::var(REFERENCE_LINKER_ENV).is_ok() { + args.write_layout = true; + args.write_trace = true; + } + + let arg_parser = setup_windows_argument_parser(); + while let Some(arg) = input.next() { + let arg = arg.as_ref(); + arg_parser.handle_argument(&mut args, &mut modifier_stack, arg, &mut input)?; + } + + if !args.unrecognized_options.is_empty() { + let options_list = args.unrecognized_options.join(", "); + bail!("unrecognized option(s): {}", options_list); + } + + Ok(args) +} + +pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { + // Helper function for unimplemented options + fn unimplemented_option(option: &str) -> Result<()> { + crate::bail!("Option {} is not yet implemented", option) + } + + let mut parser = ArgumentParser::new_case_insensitive(); + // /ALIGN - Specifies the alignment of each section. + parser + .declare_with_param() + .long("ALIGN") + .help("/ALIGN - Specifies the alignment of each section.") + .execute(|_args: &mut PeArgs, _modifier_stack, _value| { + unimplemented_option("/ALIGN") + }); + // /ALLOWBIND - Specifies that a DLL can't be bound. + parser + .declare() + .long("ALLOWBIND") + .help("/ALLOWBIND - Specifies that a DLL can't be bound.") + .execute(|_, _| unimplemented_option("/ALLOWBIND")); + // /ALLOWISOLATION - Specifies behavior for manifest lookup. + parser + .declare() + .long("ALLOWISOLATION") + .help("/ALLOWISOLATION - Specifies behavior for manifest lookup.") + .execute(|_, _| unimplemented_option("/ALLOWISOLATION")); + // /APPCONTAINER - Specifies whether the app must run within an appcontainer process environment. + parser + .declare() + .long("APPCONTAINER") + .help("/APPCONTAINER - Specifies whether the app must run within an appcontainer process environment.") + .execute(|_, _| unimplemented_option("/APPCONTAINER")); + // /ARM64XFUNCTIONPADMINX64 - Specifies the minimum number of bytes of padding between x64 functions in ARM64X images. 17.8 + parser + .declare_with_param() + .long("ARM64XFUNCTIONPADMINX64") + .help("/ARM64XFUNCTIONPADMINX64 - Specifies the minimum number of bytes of padding between x64 functions in ARM64X images. 17.8") + .execute(|_, _, _| unimplemented_option("/ARM64XFUNCTIONPADMINX64")); + // /ASSEMBLYDEBUG - Adds the DebuggableAttribute to a managed image. + parser + .declare() + .long("ASSEMBLYDEBUG") + .help("/ASSEMBLYDEBUG - Adds the DebuggableAttribute to a managed image.") + .execute(|_, _| unimplemented_option("/ASSEMBLYDEBUG")); + // /ASSEMBLYLINKRESOURCE - Creates a link to a managed resource. + parser + .declare_with_param() + .long("ASSEMBLYLINKRESOURCE") + .help("/ASSEMBLYLINKRESOURCE - Creates a link to a managed resource.") + .execute(|_, _, _| unimplemented_option("/ASSEMBLYLINKRESOURCE")); + // /ASSEMBLYMODULE - Specifies that a Microsoft intermediate language (MSIL) module should be imported into the assembly. + parser + .declare_with_param() + .long("ASSEMBLYMODULE") + .help("/ASSEMBLYMODULE - Specifies that a Microsoft intermediate language (MSIL) module should be imported into the assembly.") + .execute(|_, _, _| unimplemented_option("/ASSEMBLYMODULE")); + // /ASSEMBLYRESOURCE - Embeds a managed resource file in an assembly. + parser + .declare_with_param() + .long("ASSEMBLYRESOURCE") + .help("/ASSEMBLYRESOURCE - Embeds a managed resource file in an assembly.") + .execute(|_, _, _| unimplemented_option("/ASSEMBLYRESOURCE")); + // /BASE - Sets a base address for the program. + parser + .declare_with_param() + .long("BASE") + .help("/BASE - Sets a base address for the program.") + .execute(|args, _modifier_stack, value| { + // Parse hexadecimal base address + let base = if value.starts_with("0x") || value.starts_with("0X") { + u64::from_str_radix(&value[2..], 16) + } else { + value.parse::() + }; + + match base { + Ok(addr) => { + args.base_address = Some(addr); + Ok(()) + } + Err(_) => { + crate::bail!("Invalid base address: {}", value); + } + } + }); + // /CETCOMPAT - Marks the binary as CET Shadow Stack compatible. + parser + .declare() + .long("CETCOMPAT") + .help("/CETCOMPAT - Marks the binary as CET Shadow Stack compatible.") + .execute(|_, _| unimplemented_option("/CETCOMPAT")); + // /CGTHREADS - Sets number of cl.exe threads to use for optimization and code generation when link-time code generation is specified. + parser + .declare_with_param() + .long("CGTHREADS") + .help("/CGTHREADS - Sets number of cl.exe threads to use for optimization and code generation when link-time code generation is specified.") + .execute(|args, _modifier_stack, value| { + match value.parse::() { + Ok(threads) => { + if threads > 0 { + args.num_threads = NonZeroUsize::new(threads); + } + Ok(()) + } + Err(_) => { + crate::bail!("Invalid thread count: {}", value); + } + } + }); + // /CLRIMAGETYPE - Sets the type (IJW, pure, or safe) of a CLR image. + parser + .declare_with_param() + .long("CLRIMAGETYPE") + .help("/CLRIMAGETYPE - Sets the type (IJW, pure, or safe) of a CLR image.") + .execute(|_, _, _| unimplemented_option("/CLRIMAGETYPE")); + // /CLRSUPPORTLASTERROR - Preserves the last error code of functions that are called through the P/Invoke mechanism. + parser + .declare() + .long("CLRSUPPORTLASTERROR") + .help("/CLRSUPPORTLASTERROR - Preserves the last error code of functions that are called through the P/Invoke mechanism.") + .execute(|_, _| unimplemented_option("/CLRSUPPORTLASTERROR")); + // /CLRTHREADATTRIBUTE - Specifies the threading attribute to apply to the entry point of your CLR program. + parser + .declare_with_param() + .long("CLRTHREADATTRIBUTE") + .help("/CLRTHREADATTRIBUTE - Specifies the threading attribute to apply to the entry point of your CLR program.") + .execute(|_, _, _| unimplemented_option("/CLRTHREADATTRIBUTE")); + // /CLRUNMANAGEDCODECHECK - Specifies whether the linker applies the SuppressUnmanagedCodeSecurity attribute to linker-generated P/Invoke stubs that call from managed code into native DLLs. + parser + .declare() + .long("CLRUNMANAGEDCODECHECK") + .help("/CLRUNMANAGEDCODECHECK - Specifies whether the linker applies the SuppressUnmanagedCodeSecurity attribute to linker-generated P/Invoke stubs that call from managed code into native DLLs.") + .execute(|_, _| unimplemented_option("/CLRUNMANAGEDCODECHECK")); + // /DEBUG - Creates debugging information. + parser + .declare_with_optional_param() + .long("DEBUG") + .help("/DEBUG - Creates debugging information.") + .sub_option("FULL", "Full debugging information.", |args, _| { + args.debug_info = true; + Ok(()) + }) + .sub_option( + "FASTLINK", + "Produces a PDB with limited debug information.", + |args, _| { + args.debug_info = true; + Ok(()) + }, + ) + .execute(|args, _, _value| { + args.debug_info = true; + Ok(()) + }); + // /DEBUGTYPE - Specifies which data to include in debugging information. + parser + .declare_with_param() + .long("DEBUGTYPE") + .help("/DEBUGTYPE - Specifies which data to include in debugging information.") + .execute(|_, _, _| unimplemented_option("/DEBUGTYPE")); + // /DEF - Passes a module-definition (.def) file to the linker. + parser + .declare_with_param() + .long("DEF") + .help("/DEF - Passes a module-definition (.def) file to the linker.") + .execute(|args, _modifier_stack, value| { + args.def_file = Some(PathBuf::from(value)); + Ok(()) + }); + // /DEFAULTLIB - Searches the specified library when external references are resolved. + parser + .declare_with_optional_param() + .long("DEFAULTLIB") // Add lowercase version for case-insensitive matching + .help("/DEFAULTLIB - Searches the specified library when external references are resolved.") + .execute(|args, _modifier_stack, value| { + if let Some(lib_name) = value { + // Add library to inputs + args.inputs.push(Input { + spec: InputSpec::Lib(lib_name.into()), + search_first: None, + modifiers: Modifiers::default(), + }); + } + Ok(()) + }); + // /DELAY - Controls the delayed loading of DLLs. + parser + .declare_with_optional_param() + .long("DELAY") + .help("/DELAY - Controls the delayed loading of DLLs.") + .execute(|_, _, _| unimplemented_option("/DELAY")); + // /DELAYLOAD - Causes the delayed loading of the specified DLL. + parser + .declare_with_optional_param() + .long("DELAYLOAD") + .help("/DELAYLOAD - Causes the delayed loading of the specified DLL.") + .execute(|_, _, _| unimplemented_option("/DELAYLOAD")); + // /DELAYSIGN - Partially signs an assembly. + parser + .declare_with_optional_param() + .long("DELAYSIGN") + .help("/DELAYSIGN - Partially signs an assembly.") + .execute(|_, _, _| unimplemented_option("/DELAYSIGN")); + // /DEPENDENTLOADFLAG - Sets default flags on dependent DLL loads. + parser + .declare_with_optional_param() + .long("DEPENDENTLOADFLAG") + .help("/DEPENDENTLOADFLAG - Sets default flags on dependent DLL loads.") + .execute(|_, _, _| unimplemented_option("/DEPENDENTLOADFLAG")); + // /DLL - Builds a DLL. + parser + .declare() + .long("DLL") + .help("/DLL - Builds a DLL.") + .execute(|args, _modifier_stack| { + args.is_dll = true; + args.output_kind = OutputKind::SharedObject; + Ok(()) + }); + // /DRIVER - Creates a kernel mode driver. + parser + .declare_with_param() + .long("DRIVER") + .help("/DRIVER - Creates a kernel mode driver.") + .sub_option( + "UPONLY", + "Runs only on a uniprocessor system.", + |_, _| unimplemented_option("/DRIVER:UPONLY"), + ) + .sub_option( + "WDM", + "Creates a Windows Driver Model driver.", + |_, _| unimplemented_option("/DRIVER:WDM"), + ) + .execute(|_, _, _| unimplemented_option("/DRIVER")); + // /DYNAMICBASE - Specifies whether to generate an executable image that's rebased at load time by using the address space layout randomization (ASLR) feature. + parser + .declare_with_optional_param() + .long("DYNAMICBASE") + .help("/DYNAMICBASE - Specifies whether to generate an executable image that's rebased at load time by using the address space layout randomization (ASLR) feature.") + .execute(|args, _modifier_stack, value| { + match value { + Some("NO") => args.dynamic_base = false, + _ => args.dynamic_base = true, + } + Ok(()) + }); + // /DYNAMICDEOPT - Enable C++ Dynamic Debugging (Preview) and step in anywhere with on-demand function deoptimization. + parser + .declare_with_optional_param() + .long("DYNAMICDEOPT") + .help("/DYNAMICDEOPT - Enable C++ Dynamic Debugging (Preview) and step in anywhere with on-demand function deoptimization.") + .execute(|_, _, _| unimplemented_option("/DYNAMICDEOPT")); + // /ENTRY - Sets the starting address. + parser + .declare_with_param() + .long("ENTRY") + .help("/ENTRY - Sets the starting address.") + .execute(|args, _modifier_stack, value| { + args.entry_point = Some(value.to_string()); + Ok(()) + }); + // /ERRORREPORT - Deprecated. Error reporting is controlled by Windows Error Reporting (WER) settings. + parser + .declare_with_optional_param() + .long("ERRORREPORT") + .help("/ERRORREPORT - Deprecated. Error reporting is controlled by Windows Error Reporting (WER) settings.") + .execute(|_, _, _| unimplemented_option("/ERRORREPORT")); + // /EXPORT - Exports a function. + parser + .declare_with_param() + .long("EXPORT") + .help("/EXPORT - Exports a function.") + .execute(|_args, _modifier_stack, _value| unimplemented_option("/EXPORT")); + // /FILEALIGN - Aligns sections within the output file on multiples of a specified value. + parser + .declare_with_param() + .long("FILEALIGN") + .help("/FILEALIGN - Aligns sections within the output file on multiples of a specified value.") + .execute(|_args, _modifier_stack, _value| unimplemented_option("/FILEALIGN")); + // /FIXED - Creates a program that can be loaded only at its preferred base address. + parser + .declare_with_optional_param() + .long("FIXED") + .help("/FIXED - Creates a program that can be loaded only at its preferred base address.") + .execute(|_, _, _| unimplemented_option("/FIXED")); + // /FORCE - Forces a link to complete even with unresolved symbols or symbols defined more than once. + parser + .declare_with_optional_param() + .long("FORCE") + .help("/FORCE - Forces a link to complete even with unresolved symbols or symbols defined more than once.") + .execute(|_, _, _| unimplemented_option("/FORCE")); + // /FUNCTIONPADMIN - Creates an image that can be hot patched. + parser + .declare_with_optional_param() + .long("FUNCTIONPADMIN") + .help("/FUNCTIONPADMIN - Creates an image that can be hot patched.") + .execute(|_, _, _| unimplemented_option("/FUNCTIONPADMIN")); + // /GENPROFILE , /FASTGENPROFILE - Both of these options specify generation of a .pgd file by the linker to support profile-guided optimization (PGO). /GENPROFILE and /FASTGENPROFILE use different default parameters. + parser + .declare_with_optional_param() + .long("GENPROFILE") + .help("/GENPROFILE , /FASTGENPROFILE - Both of these options specify generation of a .pgd file by the linker to support profile-guided optimization (PGO). /GENPROFILE and /FASTGENPROFILE use different default parameters.") + .execute(|_, _, _| unimplemented_option("/GENPROFILE")); + // /GUARD - Enables Control Flow Guard protection. + parser + .declare_with_optional_param() + .long("GUARD") + .help("/GUARD - Enables Control Flow Guard protection.") + .execute(|_, _, _| unimplemented_option("/GUARD")); + // /HEAP - Sets the size of the heap, in bytes. + parser + .declare_with_optional_param() + .long("HEAP") + .help("/HEAP - Sets the size of the heap, in bytes.") + .execute(|args, _modifier_stack, value| { + if let Some(heap_value) = value { + // Parse heap size format: size[,reserve] + let heap_size_str = heap_value.split(',').next().unwrap_or(heap_value); + match heap_size_str.parse::() { + Ok(size) => { + args.heap_size = Some(size); + Ok(()) + } + Err(_) => { + crate::bail!("Invalid heap size: {}", heap_value); + } + } + } else { + // Default heap size or just enable heap specification + Ok(()) + } + }); + // /HIGHENTROPYVA - Specifies support for high-entropy 64-bit address space layout randomization (ASLR). + parser + .declare_with_optional_param() + .long("HIGHENTROPYVA") + .help("/HIGHENTROPYVA - Specifies support for high-entropy 64-bit address space layout randomization (ASLR).") + .execute(|args, _modifier_stack, value| { + match value { + Some("NO") => args.high_entropy_va = false, + _ => args.high_entropy_va = true, + } + Ok(()) + }); + // /IDLOUT - Specifies the name of the .idl file and other MIDL output files. + parser + .declare_with_optional_param() + .long("IDLOUT") + .help("/IDLOUT - Specifies the name of the .idl file and other MIDL output files.") + .execute(|_, _, _| unimplemented_option("/IDLOUT")); + // /IGNORE - Suppresses output of specified linker warnings. + parser + .declare_with_optional_param() + .long("IGNORE") + .help("/IGNORE - Suppresses output of specified linker warnings.") + .execute(|_, _, _| unimplemented_option("/IGNORE")); + // /IGNOREIDL - Prevents the processing of attribute information into an .idl file. + parser + .declare_with_optional_param() + .long("IGNOREIDL") + .help("/IGNOREIDL - Prevents the processing of attribute information into an .idl file.") + .execute(|_, _, _| unimplemented_option("/IGNOREIDL")); + // /ILK - Overrides the default incremental database file name. + parser + .declare_with_optional_param() + .long("ILK") + .help("/ILK - Overrides the default incremental database file name.") + .execute(|_, _, _| unimplemented_option("/ILK")); + // /IMPLIB - Overrides the default import library name. + parser + .declare_with_param() + .long("IMPLIB") + .help("/IMPLIB - Overrides the default import library name.") + .execute(|args, _modifier_stack, value| { + args.import_lib = Some(PathBuf::from(value)); + Ok(()) + }); + // /INCLUDE - Forces symbol references. + parser + .declare_with_param() + .long("INCLUDE") + .help("/INCLUDE - Forces symbol references.") + .execute(|_args, _modifier_stack, _value| { + // TODO: Implement symbol forcing + Ok(()) + }); + // /INCREMENTAL - Controls incremental linking. + parser + .declare_with_optional_param() + .long("INCREMENTAL") + .help("/INCREMENTAL - Controls incremental linking.") + .sub_option("NO", "Disable incremental linking.", |_, _| { + unimplemented_option("/INCREMENTAL:NO") + }) + .sub_option("YES", "Enable incremental linking.", |_, _| { + unimplemented_option("/INCREMENTAL:YES") + }) + .execute(|_, _, _| unimplemented_option("/INCREMENTAL")); + // /INFERASANLIBS - Uses inferred sanitizer libraries. + parser + .declare_with_optional_param() + .long("INFERASANLIBS") + .help("/INFERASANLIBS - Uses inferred sanitizer libraries.") + .execute(|_, _, _| unimplemented_option("/INFERASANLIBS")); + // /INTEGRITYCHECK - Specifies that the module requires a signature check at load time. + parser + .declare_with_optional_param() + .long("INTEGRITYCHECK") + .help( + "/INTEGRITYCHECK - Specifies that the module requires a signature check at load time.", + ) + .execute(|_, _, _| unimplemented_option("/INTEGRITYCHECK")); + // /KERNEL - Create a kernel mode binary. + parser + .declare_with_optional_param() + .long("KERNEL") + .help("/KERNEL - Create a kernel mode binary.") + .execute(|_, _, _| unimplemented_option("/KERNEL")); + // /KEYCONTAINER - Specifies a key container to sign an assembly. + parser + .declare_with_optional_param() + .long("KEYCONTAINER") + .help("/KEYCONTAINER - Specifies a key container to sign an assembly.") + .execute(|_, _, _| unimplemented_option("/KEYCONTAINER")); + // /KEYFILE - Specifies a key or key pair to sign an assembly. + parser + .declare_with_optional_param() + .long("KEYFILE") + .help("/KEYFILE - Specifies a key or key pair to sign an assembly.") + .execute(|_, _, _| unimplemented_option("/KEYFILE")); + // /LARGEADDRESSAWARE - Tells the compiler that the application supports addresses larger than 2 gigabytes + parser + .declare_with_optional_param() + .long("LARGEADDRESSAWARE") + .help("/LARGEADDRESSAWARE - Tells the compiler that the application supports addresses larger than 2 gigabytes") + .execute(|args, _modifier_stack, value| { + match value { + Some("NO") => args.large_address_aware = false, + _ => args.large_address_aware = true, + } + Ok(()) + }); + // /LIBPATH - Specifies a path to search before the environmental library path. + parser + .declare_with_param() + .long("LIBPATH") + .help("/LIBPATH - Specifies a path to search before the environmental library path.") + .execute(|args, _modifier_stack, value| { + let path = Path::new(value).into(); + args.lib_search_path.push(path); + Ok(()) + }); + // /LINKREPRO - Specifies a path to generate link repro artifacts in. + parser + .declare_with_optional_param() + .long("LINKREPRO") + .help("/LINKREPRO - Specifies a path to generate link repro artifacts in.") + .execute(|_, _, _| unimplemented_option("/LINKREPRO")); + // /LINKREPROFULLPATHRSP - Generates a response file containing the absolute paths to all the files that the linker took as input. + parser + .declare_with_optional_param() + .long("LINKREPROFULLPATHRSP") + .help("/LINKREPROFULLPATHRSP - Generates a response file containing the absolute paths to all the files that the linker took as input.") + .execute(|_, _, _| unimplemented_option("/LINKREPROFULLPATHRSP")); + // /LINKREPROTARGET - Generates a link repro only when producing the specified target. 16.1 + parser + .declare_with_optional_param() + .long("LINKREPROTARGET") + .help("/LINKREPROTARGET - Generates a link repro only when producing the specified target. 16.1") + .execute(|_, _, _| unimplemented_option("/LINKREPROTARGET")); + // /LTCG - Specifies link-time code generation. + parser + .declare_with_optional_param() + .long("LTCG") + .help("/LTCG - Specifies link-time code generation.") + .sub_option("NOSTATUS", "Do not display progress.", |_, _| { + unimplemented_option("/LTCG:NOSTATUS") + }) + .sub_option("STATUS", "Display progress.", |_, _| { + unimplemented_option("/LTCG:STATUS") + }) + .sub_option("INCREMENTAL", "Enable incremental LTCG.", |_, _| { + unimplemented_option("/LTCG:INCREMENTAL") + }) + .execute(|_, _, _| unimplemented_option("/LTCG")); + // /MACHINE - Specifies the target platform. + parser + .declare_with_param() + .long("MACHINE") + .help("/MACHINE - Specifies the target platform.") + .sub_option("ARM", "ARM", |args, _| { + args.arch = Architecture::AArch64; + Ok(()) + }) + .sub_option("ARM64", "ARM64", |args, _| { + args.arch = Architecture::AArch64; + Ok(()) + }) + .sub_option("ARM64EC", "ARM64EC", |args, _| { + args.arch = Architecture::AArch64; + Ok(()) + }) + .sub_option("EBC", "EBC", |_args, _| { + // EFI Byte Code - not commonly supported + Ok(()) + }) + .sub_option("X64", "X64", |args, _| { + args.arch = Architecture::X86_64; + Ok(()) + }) + .sub_option("X86", "X86", |args, _| { + args.arch = Architecture::X86_64; // Treat as X86_64 for simplicity + Ok(()) + }) + .execute(|args, _, value| { + // Handle direct architecture specification + match value.to_uppercase().as_str() { + "ARM" | "ARM64" | "ARM64EC" => args.arch = Architecture::AArch64, + "X64" | "X86" => args.arch = Architecture::X86_64, + _ => {} // Ignore unknown architectures + } + Ok(()) + }); + // /MANIFEST - Creates a side-by-side manifest file and optionally embeds it in the binary. + parser + .declare_with_optional_param() + .long("MANIFEST") + .help("/MANIFEST - Creates a side-by-side manifest file and optionally embeds it in the binary.") + .execute(|_, _, _| unimplemented_option("/MANIFEST")); + // /MANIFESTDEPENDENCY - Specifies a section in the manifest file. + parser + .declare_with_optional_param() + .long("MANIFESTDEPENDENCY") + .help("/MANIFESTDEPENDENCY - Specifies a section in the manifest file.") + .execute(|_, _, _| unimplemented_option("/MANIFESTDEPENDENCY")); + // /MANIFESTFILE - Changes the default name of the manifest file. + parser + .declare_with_param() + .long("MANIFESTFILE") + .help("/MANIFESTFILE - Changes the default name of the manifest file.") + .execute(|args, _modifier_stack, value| { + args.manifest_file = Some(PathBuf::from(value)); + Ok(()) + }); + // /MANIFESTINPUT - Specifies a manifest input file for the linker to process and embed in the binary. You can use this option multiple times to specify more than one manifest input file. + parser + .declare_with_optional_param() + .long("MANIFESTINPUT") + .help("/MANIFESTINPUT - Specifies a manifest input file for the linker to process and embed in the binary. You can use this option multiple times to specify more than one manifest input file.") + .execute(|_, _, _| unimplemented_option("/MANIFESTINPUT")); + // /MANIFESTUAC - Specifies whether User Account Control (UAC) information is embedded in the program manifest. + parser + .declare_with_optional_param() + .long("MANIFESTUAC") + .help("/MANIFESTUAC - Specifies whether User Account Control (UAC) information is embedded in the program manifest.") + .execute(|_, _, _| unimplemented_option("/MANIFESTUAC")); + // /MAP - Creates a mapfile. + parser + .declare_with_optional_param() + .long("MAP") + .help("/MAP - Creates a mapfile.") + .execute(|args, _modifier_stack, value| { + match value { + Some(filename) => args.map_file = Some(PathBuf::from(filename)), + None => { + // Default map file name based on output name + let output_stem = args + .output + .file_stem() + .unwrap_or_else(|| std::ffi::OsStr::new("output")); + let mut map_name = output_stem.to_os_string(); + map_name.push(".map"); + args.map_file = Some(PathBuf::from(map_name)); + } + } + Ok(()) + }); + // /MAPINFO - Includes the specified information in the mapfile. + parser + .declare_with_optional_param() + .long("MAPINFO") + .help("/MAPINFO - Includes the specified information in the mapfile.") + .execute(|_, _, _| unimplemented_option("/MAPINFO")); + // /MERGE - Combines sections. + parser + .declare_with_optional_param() + .long("MERGE") + .help("/MERGE - Combines sections.") + .execute(|_, _, _| unimplemented_option("/MERGE")); + // /MIDL - Specifies MIDL command-line options. + parser + .declare_with_optional_param() + .long("MIDL") + .help("/MIDL - Specifies MIDL command-line options.") + .execute(|_, _, _| unimplemented_option("/MIDL")); + // /NATVIS - Adds debugger visualizers from a Natvis file to the program database (PDB). + parser + .declare_with_optional_param() + .long("NATVIS") + .help( + "/NATVIS - Adds debugger visualizers from a Natvis file to the program database (PDB).", + ) + .execute(|_, _, _| unimplemented_option("/NATVIS")); + // /NOASSEMBLY - Suppresses the creation of a .NET Framework assembly. + parser + .declare_with_optional_param() + .long("NOASSEMBLY") + .help("/NOASSEMBLY - Suppresses the creation of a .NET Framework assembly.") + .execute(|_, _, _| unimplemented_option("/NOASSEMBLY")); + // /NODEFAULTLIB - Ignores all (or the specified) default libraries when external references are resolved. + parser + .declare_with_optional_param() + .long("NODEFAULTLIB") + .help("/NODEFAULTLIB - Ignores all (or the specified) default libraries when external references are resolved.") + .execute(|args, _modifier_stack, value| { + match value { + Some(lib_name) => { + // Ignore specific library + args.no_default_libs.push(lib_name.to_string()); + } + None => { + // Ignore all default libraries + args.ignore_all_default_libs = true; + } + } + Ok(()) + }); + // /NOENTRY - Creates a resource-only DLL. + parser + .declare_with_optional_param() + .long("NOENTRY") + .help("/NOENTRY - Creates a resource-only DLL.") + .execute(|_, _, _| unimplemented_option("/NOENTRY")); + // /NOFUNCTIONPADSECTION - Disables function padding for functions in the specified section. 17.8 + parser + .declare_with_optional_param() + .long("NOFUNCTIONPADSECTION") + .help("/NOFUNCTIONPADSECTION - Disables function padding for functions in the specified section. 17.8") + .execute(|_, _, _| unimplemented_option("/NOFUNCTIONPADSECTION")); + // /NOLOGO - Suppresses the startup banner. + parser + .declare_with_optional_param() + .long("NOLOGO") + .help("/NOLOGO - Suppresses the startup banner.") + .execute(|_, _, _| unimplemented_option("/NOLOGO")); + // /NXCOMPAT - Marks an executable as verified to be compatible with the Windows Data Execution Prevention feature. + parser + .declare_with_optional_param() + .long("NXCOMPAT") + .help("/NXCOMPAT - Marks an executable as verified to be compatible with the Windows Data Execution Prevention feature.") + .execute(|args, _modifier_stack, value| { + match value { + Some("NO") => args.nx_compat = false, + _ => args.nx_compat = true, + } + Ok(()) + }); + // /OPT - Controls LINK optimizations. + parser + .declare_with_param() + .long("OPT") + .help("/OPT - Controls LINK optimizations.") + .sub_option( + "REF", + "Eliminate unreferenced functions and data.", + |_, _| unimplemented_option("/OPT:REF"), + ) + .sub_option( + "NOREF", + "Keep unreferenced functions and data.", + |_, _| unimplemented_option("/OPT:NOREF"), + ) + .sub_option("ICF", "Fold identical COMDATs.", |_, _| { + unimplemented_option("/OPT:ICF") + }) + .sub_option("NOICF", "Disable identical COMDAT folding.", |_, _| { + unimplemented_option("/OPT:NOICF") + }) + .sub_option( + "LBR", + "Enable profile guided optimizations (LBR).", + |_, _| unimplemented_option("/OPT:LBR"), + ) + .sub_option( + "NOLBR", + "Disable profile guided optimizations (no LBR).", + |_, _| unimplemented_option("/OPT:NOLBR"), + ) + .execute(|_, _, _| unimplemented_option("/OPT")); + // /ORDER - Places COMDATs into the image in a predetermined order. + parser + .declare_with_optional_param() + .long("ORDER") + .help("/ORDER - Places COMDATs into the image in a predetermined order.") + .execute(|_, _, _| unimplemented_option("/ORDER")); + // /OUT - Specifies the output file name. + parser + .declare_with_param() + .long("OUT") + .help("/OUT - Specifies the output file name.") + .execute(|args, _modifier_stack, value| { + args.output = Arc::from(Path::new(value)); + Ok(()) + }); + // /PDB - Creates a PDB file. + parser + .declare_with_optional_param() + .long("PDB") + .help("/PDB - Creates a PDB file.") + .execute(|args, _modifier_stack, value| { + match value { + Some(filename) => args.pdb_file = Some(PathBuf::from(filename)), + None => { + // Default PDB file name based on output name + let output_stem = args + .output + .file_stem() + .unwrap_or_else(|| std::ffi::OsStr::new("output")); + let mut pdb_name = output_stem.to_os_string(); + pdb_name.push(".pdb"); + args.pdb_file = Some(PathBuf::from(pdb_name)); + } + } + Ok(()) + }); + // /PDBALTPATH - Uses an alternate location to save a PDB file. + parser + .declare_with_optional_param() + .long("PDBALTPATH") + .help("/PDBALTPATH - Uses an alternate location to save a PDB file.") + .execute(|_, _, _| unimplemented_option("/PDBALTPATH")); + // /PDBSTRIPPED - Creates a PDB file that has no private symbols. + parser + .declare_with_optional_param() + .long("PDBSTRIPPED") + .help("/PDBSTRIPPED - Creates a PDB file that has no private symbols.") + .execute(|_, _, _| unimplemented_option("/PDBSTRIPPED")); + // /PGD - Specifies a .pgd file for profile-guided optimizations. + parser + .declare_with_optional_param() + .long("PGD") + .help("/PGD - Specifies a .pgd file for profile-guided optimizations.") + .execute(|_, _, _| unimplemented_option("/PGD")); + // /POGOSAFEMODE - Obsolete Creates a thread-safe PGO instrumented build. + parser + .declare_with_optional_param() + .long("POGOSAFEMODE") + .help("/POGOSAFEMODE - Obsolete Creates a thread-safe PGO instrumented build.") + .execute(|_, _, _| unimplemented_option("/POGOSAFEMODE")); + // /PROFILE - Produces an output file that can be used with the Performance Tools profiler. + parser + .declare_with_optional_param() + .long("PROFILE") + .help("/PROFILE - Produces an output file that can be used with the Performance Tools profiler.") + .execute(|_, _, _| unimplemented_option("/PROFILE")); + // /RELEASE - Sets the Checksum in the .exe header. + parser + .declare_with_optional_param() + .long("RELEASE") + .help("/RELEASE - Sets the Checksum in the .exe header.") + .execute(|_, _, _| unimplemented_option("/RELEASE")); + // /SAFESEH - Specifies that the image will contain a table of safe exception handlers. + parser + .declare_with_optional_param() + .long("SAFESEH") + .help( + "/SAFESEH - Specifies that the image will contain a table of safe exception handlers.", + ) + .execute(|_, _, _| unimplemented_option("/SAFESEH")); + // /SECTION - Overrides the attributes of a section. + parser + .declare_with_optional_param() + .long("SECTION") + .help("/SECTION - Overrides the attributes of a section.") + .execute(|_, _, _| unimplemented_option("/SECTION")); + // /SOURCELINK - Specifies a SourceLink file to add to the PDB. + parser + .declare_with_optional_param() + .long("SOURCELINK") + .help("/SOURCELINK - Specifies a SourceLink file to add to the PDB.") + .execute(|_, _, _| unimplemented_option("/SOURCELINK")); + // /STACK - Sets the size of the stack in bytes. + parser + .declare_with_optional_param() + .long("STACK") + .help("/STACK - Sets the size of the stack in bytes.") + .execute(|args, _modifier_stack, value| { + if let Some(stack_value) = value { + // Parse stack size format: size[,reserve] + let stack_size_str = stack_value.split(',').next().unwrap_or(stack_value); + match stack_size_str.parse::() { + Ok(size) => { + args.stack_size = Some(size); + Ok(()) + } + Err(_) => { + crate::bail!("Invalid stack size: {}", stack_value); + } + } + } else { + // Default stack size or just enable stack specification + Ok(()) + } + }); + // /STUB - Attaches an MS-DOS stub program to a Win32 program. + parser + .declare_with_optional_param() + .long("STUB") + .help("/STUB - Attaches an MS-DOS stub program to a Win32 program.") + .execute(|_, _, _| unimplemented_option("/STUB")); + // /SUBSYSTEM - Tells the operating system how to run the .exe file. + parser + .declare_with_param() + .long("SUBSYSTEM") + .help("/SUBSYSTEM - Tells the operating system how to run the .exe file.") + .sub_option("BOOT_APPLICATION", "Boot application", |args, _| { + args.subsystem = Some(WindowsSubsystem::BootApplication); + Ok(()) + }) + .sub_option("CONSOLE", "Console", |args, _| { + args.subsystem = Some(WindowsSubsystem::Console); + Ok(()) + }) + .sub_option("WINDOWS", "Windows GUI", |args, _| { + args.subsystem = Some(WindowsSubsystem::Windows); + Ok(()) + }) + .sub_option("NATIVE", "Native", |args, _| { + args.subsystem = Some(WindowsSubsystem::Native); + Ok(()) + }) + .sub_option("POSIX", "POSIX", |args, _| { + args.subsystem = Some(WindowsSubsystem::Posix); + Ok(()) + }) + .sub_option("EFI_APPLICATION", "EFI application", |args, _| { + args.subsystem = Some(WindowsSubsystem::EfiApplication); + Ok(()) + }) + .sub_option( + "EFI_BOOT_SERVICE_DRIVER", + "EFI boot service driver", + |args, _| { + args.subsystem = Some(WindowsSubsystem::EfiBootServiceDriver); + Ok(()) + }, + ) + .sub_option("EFI_ROM", "EFI ROM", |args, _| { + args.subsystem = Some(WindowsSubsystem::EfiRom); + Ok(()) + }) + .sub_option("EFI_RUNTIME_DRIVER", "EFI runtime driver", |args, _| { + args.subsystem = Some(WindowsSubsystem::EfiRuntimeDriver); + Ok(()) + }) + .execute(|args, _, value| { + // Handle direct subsystem specification + match value.to_uppercase().as_str() { + "BOOT_APPLICATION" => args.subsystem = Some(WindowsSubsystem::BootApplication), + "CONSOLE" => args.subsystem = Some(WindowsSubsystem::Console), + "WINDOWS" => args.subsystem = Some(WindowsSubsystem::Windows), + "NATIVE" => args.subsystem = Some(WindowsSubsystem::Native), + "POSIX" => args.subsystem = Some(WindowsSubsystem::Posix), + "EFI_APPLICATION" => args.subsystem = Some(WindowsSubsystem::EfiApplication), + "EFI_BOOT_SERVICE_DRIVER" => { + args.subsystem = Some(WindowsSubsystem::EfiBootServiceDriver) + } + "EFI_ROM" => args.subsystem = Some(WindowsSubsystem::EfiRom), + "EFI_RUNTIME_DRIVER" => args.subsystem = Some(WindowsSubsystem::EfiRuntimeDriver), + _ => {} // Ignore unknown subsystems + } + Ok(()) + }); + // /SWAPRUN - Tells the operating system to copy the linker output to a swap file before it's run. + parser + .declare_with_optional_param() + .long("SWAPRUN") + .help("/SWAPRUN - Tells the operating system to copy the linker output to a swap file before it's run.") + .execute(|_, _, _| unimplemented_option("/SWAPRUN")); + // /TIME - Output linker pass timing information. + parser + .declare_with_optional_param() + .long("TIME") + .help("/TIME - Output linker pass timing information.") + .execute(|_, _, _| unimplemented_option("/TIME")); + // /TLBID - Specifies the resource ID of the linker-generated type library. + parser + .declare_with_optional_param() + .long("TLBID") + .help("/TLBID - Specifies the resource ID of the linker-generated type library.") + .execute(|_, _, _| unimplemented_option("/TLBID")); + // /TLBOUT - Specifies the name of the .tlb file and other MIDL output files. + parser + .declare_with_optional_param() + .long("TLBOUT") + .help("/TLBOUT - Specifies the name of the .tlb file and other MIDL output files.") + .execute(|_, _, _| unimplemented_option("/TLBOUT")); + // /TSAWARE - Creates an application that is designed specifically to run under Terminal Server. + parser + .declare_with_optional_param() + .long("TSAWARE") + .help("/TSAWARE - Creates an application that is designed specifically to run under Terminal Server.") + .execute(|args, _modifier_stack, value| { + match value { + Some("NO") => args.terminal_server_aware = false, + _ => args.terminal_server_aware = true, + } + Ok(()) + }); + // /USEPROFILE - Uses profile-guided optimization training data to create an optimized image. + parser + .declare_with_optional_param() + .long("USEPROFILE") + .help("/USEPROFILE - Uses profile-guided optimization training data to create an optimized image.") + .execute(|_, _, _| unimplemented_option("/USEPROFILE")); + // /VERBOSE - Prints linker progress messages. + parser + .declare_with_optional_param() + .long("VERBOSE") + .help("/VERBOSE - Prints linker progress messages.") + .execute(|_, _, _| unimplemented_option("/VERBOSE")); + // /VERSION - Assigns a version number. + parser + .declare_with_param() + .long("VERSION") + .help("/VERSION - Assigns a version number.") + .execute(|args, _modifier_stack, value| { + args.version = Some(value.to_string()); + Ok(()) + }); + // /WHOLEARCHIVE - Includes every object file from specified static libraries. + parser + .declare_with_optional_param() + .long("WHOLEARCHIVE") + .help("/WHOLEARCHIVE - Includes every object file from specified static libraries.") + .execute(|_, _, _| unimplemented_option("/WHOLEARCHIVE")); + // /WINMD - Enables generation of a Windows Runtime Metadata file. + parser + .declare_with_optional_param() + .long("WINMD") + .help("/WINMD - Enables generation of a Windows Runtime Metadata file.") + .execute(|_, _, _| unimplemented_option("/WINMD")); + // /WINMDFILE - Specifies the file name for the Windows Runtime Metadata (winmd) output file that's generated by the /WINMD linker option. + parser + .declare_with_optional_param() + .long("WINMDFILE") + .help("/WINMDFILE - Specifies the file name for the Windows Runtime Metadata (winmd) output file that's generated by the /WINMD linker option.") + .execute(|_, _, _| unimplemented_option("/WINMDFILE")); + // /WINMDKEYFILE - Specifies a key or key pair to sign a Windows Runtime Metadata file. + parser + .declare_with_optional_param() + .long("WINMDKEYFILE") + .help( + "/WINMDKEYFILE - Specifies a key or key pair to sign a Windows Runtime Metadata file.", + ) + .execute(|_, _, _| unimplemented_option("/WINMDKEYFILE")); + // /WINMDKEYCONTAINER - Specifies a key container to sign a Windows Metadata file. + parser + .declare_with_optional_param() + .long("WINMDKEYCONTAINER") + .help("/WINMDKEYCONTAINER - Specifies a key container to sign a Windows Metadata file.") + .execute(|_, _, _| unimplemented_option("/WINMDKEYCONTAINER")); + // /WINMDDELAYSIGN - Partially signs a Windows Runtime Metadata ( .winmd ) file by placing the public key in the winmd file. + parser + .declare_with_optional_param() + .long("WINMDDELAYSIGN") + .help("/WINMDDELAYSIGN - Partially signs a Windows Runtime Metadata ( .winmd ) file by placing the public key in the winmd file.") + .execute(|_, _, _| unimplemented_option("/WINMDDELAYSIGN")); + // /WX - Treats linker warnings as errors. + parser + .declare_with_optional_param() + .long("WX") + .help("/WX - Treats linker warnings as errors.") + .execute(|_args: &mut PeArgs, _modifier_stack, _value| { + unimplemented_option("/WX") + }); + + add_silently_ignored_flags(&mut parser); + add_default_flags(&mut parser); + + parser +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::args::InputSpec; + use std::path::Path; + + // Example Windows linker flags from Rust compilation + const WINDOWS_LINKER_ARGS: &[&str] = &[ + "--target=x86_64-pc-windows-msvc", + r#"C:\Users\Samuel\AppData\Local\Temp\rustc7RL5Io\symbols.o"#, + "dummy.dummy.6cfbe55db138f4b-cgu.0.rcgu.o", + "dummy.3wxfnlvokcqcl6j45c8xeicgz.rcgu.o", + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libstd-efa6c7783284bd31.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libpanic_unwind-43468c47cff21662.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libwindows_targets-3935b75a1bd1c449.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\librustc_demangle-cc0fa0adec36251f.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libstd_detect-22f2c46a93af1174.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libhashbrown-c835068eb56f6efb.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\librustc_std_workspace_alloc-abe24411cb8f5bd4.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libunwind-b5e24931eb1ae1bd.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libcfg_if-8dc64876e32b9d07.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\librustc_std_workspace_core-214bcacef209824d.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\liballoc-3e14ad51a3206bab.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libcore-a55e6b132b0b5f5d.rlib"#, + r#"C:\Users\Samuel\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib\libcompiler_builtins-b994e165f6ecc9e9.rlib"#, + "kernel32.lib", + "kernel32.lib", + "kernel32.lib", + "ntdll.lib", + "userenv.lib", + "ws2_32.lib", + "dbghelp.lib", + "/defaultlib:msvcrt", + "/NXCOMPAT", + "/OUT:dummy.exe", + "/DEBUG", + ]; + + #[track_caller] + fn assert_contains_file(inputs: &[Input], file_path: &str) { + assert!(inputs.iter().any(|input| match &input.spec { + InputSpec::File(path) => path.as_ref() == Path::new(file_path), + _ => false, + })); + } + + #[track_caller] + fn assert_contains_lib(inputs: &[Input], lib_name: &str) { + assert!(inputs.iter().any(|input| match &input.spec { + InputSpec::Lib(name) => name.as_ref() == lib_name, + _ => false, + })); + } + + /// Extract PeArgs from unified Args, panicking if it's not the Pe variant. + #[track_caller] + fn unwrap_pe(args: crate::args::Args) -> PeArgs { + match args.target_args { + crate::args::TargetArgs::Pe(pe) => pe, + other => panic!("Expected Pe variant, got {:?}", std::mem::discriminant(&other)), + } + } + + #[test] + fn test_parse_windows_linker_args() { + let args = unwrap_pe(crate::args::parse(|| WINDOWS_LINKER_ARGS.iter()) + .unwrap()); + + // Test that key flags were parsed correctly + assert!(args.debug_info); // /DEBUG flag + assert!(args.nx_compat); // /NXCOMPAT flag + + // Test that output file was set + assert_eq!(args.output.as_ref(), Path::new("dummy.exe")); + + // Test that input files were collected + assert_contains_file(&args.inputs, "dummy.dummy.6cfbe55db138f4b-cgu.0.rcgu.o"); + assert_contains_file(&args.inputs, "dummy.3wxfnlvokcqcl6j45c8xeicgz.rcgu.o"); + + // Test that library files were collected + assert_contains_file(&args.inputs, "kernel32.lib"); + assert_contains_file(&args.inputs, "ntdll.lib"); + assert_contains_file(&args.inputs, "userenv.lib"); + assert_contains_file(&args.inputs, "ws2_32.lib"); + assert_contains_file(&args.inputs, "dbghelp.lib"); + + // Test that rlib files were collected + assert!(args.inputs.iter().any(|input| { + match &input.spec { + InputSpec::File(path) => path + .to_string_lossy() + .contains("libstd-efa6c7783284bd31.rlib"), + _ => false, + } + })); + assert!(args.inputs.iter().any(|input| { + match &input.spec { + InputSpec::File(path) => path + .to_string_lossy() + .contains("libcore-a55e6b132b0b5f5d.rlib"), + _ => false, + } + })); + + // Test that /defaultlib was handled and added library to inputs + assert_contains_lib(&args.inputs, "msvcrt"); + + // Verify some key libraries are present + let lib_names: Vec<&str> = args + .inputs + .iter() + .filter_map(|input| match &input.spec { + InputSpec::Lib(lib_name) => Some(lib_name.as_ref()), + _ => None, + }) + .collect(); + assert!(lib_names.contains(&"msvcrt")); + } + + #[test] + fn test_minimal_windows_args() { + let minimal_args = &[ + "--target=x86_64-pc-windows-msvc", + "/OUT:test.exe", + "/DEBUG", + "test.obj", + ]; + + let args = unwrap_pe(crate::args::parse(|| minimal_args.iter()) + .unwrap()); + + assert_eq!(args.output.as_ref(), Path::new("test.exe")); + println!("Debug info value: {}", args.debug_info); + assert!(args.debug_info); + assert_contains_file(&args.inputs, "test.obj"); + } + + #[test] + fn test_debug_flag_simple() { + let minimal_args = &["--target=x86_64-pc-windows-msvc","/DEBUG"]; + + let result = crate::args::parse(|| minimal_args.iter()); + match result { + Ok(args) => { + let windows_args = unwrap_pe(args); + println!( + "Simple debug test - Debug info value: {}", + windows_args.debug_info + ); + println!( + "Unrecognized options: {:?}", + windows_args.unrecognized_options + ); + assert!(windows_args.debug_info); + } + Err(e) => { + println!("Parse error: {:?}", e); + panic!("Failed to parse arguments: {:?}", e); + } + } + } + + #[test] + fn test_defaultlib_parsing() { + let minimal_args = &["--target=x86_64-pc-windows-msvc","/defaultlib:msvcrt"]; + + let args = unwrap_pe(crate::args::parse(|| minimal_args.iter()) + .unwrap()); + + let lib_names: Vec<&str> = args + .inputs + .iter() + .filter_map(|input| match &input.spec { + InputSpec::Lib(lib_name) => Some(lib_name.as_ref()), + _ => None, + }) + .collect(); + + println!("Found libraries: {:?}", lib_names); + println!("Unrecognized options: {:?}", args.unrecognized_options); + + assert_contains_lib(&args.inputs, "msvcrt"); + } + + #[test] + fn test_required_parameters() { + // Test that IMPLIB requires a parameter + let implib_args = &["--target=x86_64-pc-windows-msvc","/IMPLIB"]; + + let result = crate::args::parse(|| implib_args.iter()); + match result { + Ok(_) => panic!("Expected error for IMPLIB without parameter"), + Err(e) => { + let error_msg = format!("{:?}", e); + assert!( + error_msg.contains("Missing argument") || error_msg.contains("IMPLIB"), + "Error should mention missing argument for IMPLIB: {}", + error_msg + ); + } + } + + // Test that EXPORT requires a parameter + let export_args = &["--target=x86_64-pc-windows-msvc","/EXPORT"]; + + let result = crate::args::parse(|| export_args.iter()); + match result { + Ok(_) => panic!("Expected error for EXPORT without parameter"), + Err(e) => { + let error_msg = format!("{:?}", e); + assert!( + error_msg.contains("Missing argument") || error_msg.contains("EXPORT"), + "Error should mention missing argument for EXPORT: {}", + error_msg + ); + } + } + + // Test that VERSION requires a parameter + let version_args = &["--target=x86_64-pc-windows-msvc","/VERSION"]; + + let result = crate::args::parse(|| version_args.iter()); + match result { + Ok(_) => panic!("Expected error for VERSION without parameter"), + Err(e) => { + let error_msg = format!("{:?}", e); + assert!( + error_msg.contains("Missing argument") || error_msg.contains("VERSION"), + "Error should mention missing argument for VERSION: {}", + error_msg + ); + } + } + } + + #[test] + fn test_unimplemented_options() { + // Test that unimplemented options return proper error messages + let appcontainer_args = &["--target=x86_64-pc-windows-msvc","/APPCONTAINER"]; + + let result = crate::args::parse(|| appcontainer_args.iter()); + match result { + Ok(_) => panic!("Expected error for unimplemented APPCONTAINER option"), + Err(e) => { + let error_msg = format!("{:?}", e); + assert!( + error_msg.contains("not yet implemented") && error_msg.contains("APPCONTAINER"), + "Error should mention APPCONTAINER is not implemented: {}", + error_msg + ); + } + } + + // Test another unimplemented option + let assemblydebug_args = &["--target=x86_64-pc-windows-msvc","/ASSEMBLYDEBUG"]; + + let result = crate::args::parse(|| assemblydebug_args.iter()); + match result { + Ok(_) => panic!("Expected error for unimplemented ASSEMBLYDEBUG option"), + Err(e) => { + let error_msg = format!("{:?}", e); + assert!( + error_msg.contains("not yet implemented") + && error_msg.contains("ASSEMBLYDEBUG"), + "Error should mention ASSEMBLYDEBUG is not implemented: {}", + error_msg + ); + } + } + } + + #[test] + fn test_case_insensitive_parsing() { + // Test uppercase /ENTRY:main and /OUT:test.exe + let args_upper = &["--target=x86_64-pc-windows-msvc","/ENTRY:main", "/OUT:test.exe"]; + let result_upper = unwrap_pe(crate::args::parse(|| args_upper.iter()) + .unwrap()); + assert_eq!(result_upper.entry_point, Some("main".to_string())); + assert_eq!(result_upper.output.as_ref(), Path::new("test.exe")); + + // Test lowercase /entry:main and /out:test.exe + let args_lower = &["--target=x86_64-pc-windows-msvc","/entry:main", "/out:test.exe"]; + let result_lower = unwrap_pe(crate::args::parse(|| args_lower.iter()) + .unwrap()); + assert_eq!(result_lower.entry_point, Some("main".to_string())); + assert_eq!(result_lower.output.as_ref(), Path::new("test.exe")); + + // Test mixed case /Entry:main and /Out:test.exe + let args_mixed = &["--target=x86_64-pc-windows-msvc","/Entry:main", "/Out:test.exe"]; + let result_mixed = unwrap_pe(crate::args::parse(|| args_mixed.iter()) + .unwrap()); + assert_eq!(result_mixed.entry_point, Some("main".to_string())); + assert_eq!(result_mixed.output.as_ref(), Path::new("test.exe")); + } + + #[test] + fn test_nodefaultlib_parsing() { + // Test /NODEFAULTLIB without parameter (ignore all default libraries) + let args_all = &["--target=x86_64-pc-windows-msvc","/NODEFAULTLIB"]; + let result_all = unwrap_pe(crate::args::parse(|| args_all.iter()) + .unwrap()); + assert!(result_all.ignore_all_default_libs); + assert!(result_all.no_default_libs.is_empty()); + + // Test /NODEFAULTLIB with specific library name + let args_specific = &["--target=x86_64-pc-windows-msvc","/NODEFAULTLIB:msvcrt"]; + let result_specific = unwrap_pe(crate::args::parse(|| args_specific.iter()) + .unwrap()); + assert!(!result_specific.ignore_all_default_libs); + assert_eq!(result_specific.no_default_libs, vec!["msvcrt"]); + + // Test multiple specific libraries + let args_multiple = &[ + "--target=x86_64-pc-windows-msvc", + "/NODEFAULTLIB:msvcrt", + "/NODEFAULTLIB:kernel32", + ]; + let result_multiple = unwrap_pe(crate::args::parse(|| args_multiple.iter()) + .unwrap()); + assert!(!result_multiple.ignore_all_default_libs); + assert_eq!(result_multiple.no_default_libs, vec!["msvcrt", "kernel32"]); + + // Test case-insensitive matching + let args_case_insensitive = &["--target=x86_64-pc-windows-msvc","/nodefaultlib:msvcrt"]; + let result_case_insensitive = unwrap_pe(crate::args::parse(|| args_case_insensitive.iter()) + .unwrap()); + assert!(!result_case_insensitive.ignore_all_default_libs); + assert_eq!(result_case_insensitive.no_default_libs, vec!["msvcrt"]); + } + + #[test] + fn test_nodefaultlib_helper_methods() { + // Test helper methods for ignore all default libraries + let args_all = &["--target=x86_64-pc-windows-msvc","/NODEFAULTLIB"]; + let result_all = unwrap_pe(crate::args::parse(|| args_all.iter()) + .unwrap()); + + assert!(result_all.ignores_all_default_libs()); + assert!(result_all.should_ignore_default_lib("msvcrt")); + assert!(result_all.should_ignore_default_lib("kernel32")); + assert!(result_all.ignored_default_libs().is_empty()); + + // Test helper methods for specific libraries + let args_specific = &[ + "--target=x86_64-pc-windows-msvc", + "/NODEFAULTLIB:msvcrt", + "/NODEFAULTLIB:kernel32", + ]; + let result_specific = unwrap_pe(crate::args::parse(|| args_specific.iter()) + .unwrap()); + + assert!(!result_specific.ignores_all_default_libs()); + assert!(result_specific.should_ignore_default_lib("msvcrt")); + assert!(result_specific.should_ignore_default_lib("kernel32")); + assert!(!result_specific.should_ignore_default_lib("user32")); + assert_eq!( + result_specific.ignored_default_libs(), + &["msvcrt", "kernel32"] + ); + } +} diff --git a/libwild/src/dwarf_address_info.rs b/libwild/src/dwarf_address_info.rs index 65c0b3e07..bb46364d6 100644 --- a/libwild/src/dwarf_address_info.rs +++ b/libwild/src/dwarf_address_info.rs @@ -15,8 +15,10 @@ use object::LittleEndian; use object::read::elf::Crel; use object::read::elf::RelocationSections; use std::borrow::Cow; +#[cfg(unix)] use std::ffi::OsStr; use std::fmt::Display; +#[cfg(unix)] use std::os::unix::ffi::OsStrExt; use std::path::Path; use std::path::PathBuf; @@ -60,7 +62,17 @@ pub(crate) fn get_source_info<'data, P: Platform<'data>>( let comp_dir = unit .comp_dir .as_ref() - .map(|dir| Path::new(OsStr::from_bytes(dir)).to_owned()) + .map(|dir| { + Path::new({ + #[cfg(not(unix))] + { + std::str::from_utf8(dir).expect("DWARF comp_dir is not valid UTF-8") + } + #[cfg(unix)] + OsStr::from_bytes(dir) + }) + .to_owned() + }) .unwrap_or_default(); let mut rows = program.rows(); @@ -78,9 +90,16 @@ pub(crate) fn get_source_info<'data, P: Platform<'data>>( if let Some(file) = row.file(header) { path = comp_dir.clone(); - path.push(OsStr::from_bytes( - &dwarf.attr_string(&unit, file.path_name())?, - )); + let file_path_name = dwarf.attr_string(&unit, file.path_name())?; + path.push({ + #[cfg(not(unix))] + { + std::str::from_utf8(&file_path_name) + .expect("DWARF file path is not valid UTF-8") + } + #[cfg(unix)] + OsStr::from_bytes(&file_path_name) + }); } let line = row.line().map_or(0, |l| l.get()); diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index 2699fc2d5..399f9ddef 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -1,4 +1,4 @@ -use crate::Args; +use crate::args::ElfArgs; use crate::alignment::Alignment; use crate::arch::Architecture; use crate::bail; @@ -246,7 +246,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { type GroupLayoutExt = GroupLayoutExt; type CommonGroupStateExt = CommonGroupStateExt; - fn parse(input: &InputBytes<'data>, args: &Args) -> Result { + fn parse(input: &InputBytes<'data>, args: &ElfArgs) -> Result { let is_dynamic = input.kind == FileKind::ElfDynamic; let file = Self::parse_bytes(input.data, is_dynamic)?; @@ -655,7 +655,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, + args: &ElfArgs, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -824,7 +824,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn new_epilogue_layout( - args: &Args, + args: &ElfArgs, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout { @@ -1103,7 +1103,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { .sum::(), "resolved relocations"); } - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args) { + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &ElfArgs) { if args.should_write_eh_frame_hdr { common.allocate(part_id::EH_FRAME_HDR, size_of::() as u64); } @@ -1929,7 +1929,7 @@ impl ElfLayoutProperties { pub(crate) fn new<'files, 'states, 'data: 'files + 'states, P: Platform<'data>>( objects: impl Iterator>, states: impl Iterator> + Clone, - args: &Args, + args: &ElfArgs, ) -> Result { let gnu_property_notes = merge_gnu_property_notes::

(states.clone(), args.z_isa)?; let riscv_attributes = merge_riscv_attributes::

(states)?; @@ -2543,7 +2543,7 @@ pub(crate) struct GnuHashLayout { } fn create_gnu_hash_layout( - args: &Args, + args: &ElfArgs, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Option { diff --git a/libwild/src/elf_writer.rs b/libwild/src/elf_writer.rs index bce3e3445..4bec49f55 100644 --- a/libwild/src/elf_writer.rs +++ b/libwild/src/elf_writer.rs @@ -4,7 +4,7 @@ use self::elf::NoteProperty; use self::elf::get_page_mask; use crate::OutputKind; use crate::alignment; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::BuildIdOption; use crate::bail; use crate::debug_assert_bail; @@ -4228,7 +4228,7 @@ struct DynamicEntryWriter { } struct DynamicEntryInputs<'layout> { - args: &'layout Args, + args: &'layout ElfArgs, has_static_tls: bool, has_variant_pcs: bool, section_layouts: &'layout OutputSectionMap, diff --git a/libwild/src/file_writer.rs b/libwild/src/file_writer.rs index 715be7d4e..6829943bb 100644 --- a/libwild/src/file_writer.rs +++ b/libwild/src/file_writer.rs @@ -1,5 +1,5 @@ use crate::OutputKind; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::FileWriteMode; use crate::args::WRITE_VERIFY_ALLOCATIONS_ENV; use crate::error; @@ -110,7 +110,7 @@ struct SectionAllocation { } impl Output { - pub(crate) fn new(args: &Args, output_kind: OutputKind) -> Output { + pub(crate) fn new(args: &ElfArgs, output_kind: OutputKind) -> Output { let file_write_mode = args .file_write_mode .unwrap_or_else(|| default_file_write_mode(args, output_kind)); @@ -230,7 +230,7 @@ impl Output { } /// Returns the file write mode that we should use to write to the specified path. -fn default_file_write_mode(args: &Args, output_kind: OutputKind) -> FileWriteMode { +fn default_file_write_mode(args: &ElfArgs, output_kind: OutputKind) -> FileWriteMode { if output_kind.is_shared_object() { return FileWriteMode::UnlinkAndReplace; } diff --git a/libwild/src/fs.rs b/libwild/src/fs.rs index 2c96862ec..2fe2292d1 100644 --- a/libwild/src/fs.rs +++ b/libwild/src/fs.rs @@ -1,6 +1,15 @@ use crate::error::Result; use std::fs::File; +#[inline(always)] +#[cfg(windows)] +/// On Windows, we don't need to do anything special to make a file executable. +pub(crate) fn make_executable(_: &File) -> Result { + Ok(()) +} + +#[inline(always)] +#[cfg(unix)] pub(crate) fn make_executable(file: &File) -> Result { use std::os::unix::prelude::PermissionsExt; diff --git a/libwild/src/gc_stats.rs b/libwild/src/gc_stats.rs index e19af3667..0bec4c77e 100644 --- a/libwild/src/gc_stats.rs +++ b/libwild/src/gc_stats.rs @@ -16,7 +16,7 @@ //! cargo rustc --bin rg -- -Clinker=/usr/bin/clang-15 -Clink-arg=--ld-path=wild -Clink-arg=-Wl,--write-gc-stats=/tmp/gc-stats.txt -Clink-arg=-Wl,--verbose-gc-stats //! ``` -use crate::args::Args; +use crate::args::ElfArgs; use crate::error::Context as _; use crate::error::Result; use crate::layout::FileLayout; @@ -28,7 +28,7 @@ use hashbrown::HashMap; use itertools::Itertools; use std::path::PathBuf; -pub(crate) fn maybe_write_gc_stats(group_layouts: &[GroupLayout], args: &Args) -> Result { +pub(crate) fn maybe_write_gc_stats(group_layouts: &[GroupLayout], args: &ElfArgs) -> Result { let Some(stats_file) = args.write_gc_stats.as_ref() else { return Ok(()); }; @@ -46,7 +46,7 @@ struct InputFile<'data> { fn write_gc_stats( group_layouts: &[GroupLayout], stats_file: &std::path::Path, - args: &Args, + args: &ElfArgs, ) -> Result { use std::io::Write as _; diff --git a/libwild/src/grouping.rs b/libwild/src/grouping.rs index ae055886c..bcbd4b274 100644 --- a/libwild/src/grouping.rs +++ b/libwild/src/grouping.rs @@ -1,4 +1,4 @@ -use crate::args::Args; +use crate::args::ElfArgs; use crate::error::Result; use crate::input_data::FileId; use crate::input_data::MAX_FILES_PER_GROUP; @@ -189,7 +189,7 @@ pub(crate) fn create_groups<'data, O: ObjectFile<'data>>( } /// Decides after how many symbols, we should start a new group. -fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usize { +fn determine_symbols_per_group(num_symbols: usize, args: &ElfArgs) -> usize { let num_threads = args.available_threads.get(); // If we're running with a single thread, then we might as well put everything into a single @@ -213,7 +213,7 @@ fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usize { } /// Decides the maximum number of files that we'll put into one group. -fn determine_max_files_per_group(args: &Args) -> usize { +fn determine_max_files_per_group(args: &ElfArgs) -> usize { if let Some(v) = args.files_per_group { return v as usize; } diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index a1cbb2b3e..952850c9f 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -4,7 +4,7 @@ use crate::archive; use crate::archive::ArchiveEntry; use crate::archive::ArchiveIterator; use crate::archive::EntryMeta; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::Input; use crate::args::InputSpec; use crate::args::Modifiers; @@ -130,7 +130,7 @@ pub(crate) struct InputLinkerScript<'data> { } struct TemporaryState<'data, O: ObjectFile<'data>> { - args: &'data Args, + args: &'data ElfArgs, /// Mapping from paths to the index in `files` at which we'll place the result. path_to_load_index: Mutex>, @@ -205,7 +205,7 @@ pub(crate) struct AuxiliaryFiles<'data> { } impl<'data> AuxiliaryFiles<'data> { - pub(crate) fn new(args: &'data Args, inputs_arena: &'data Arena) -> Result { + pub(crate) fn new(args: &'data ElfArgs, inputs_arena: &'data Arena) -> Result { let resolve_script_path = |path: &Path| -> PathBuf { if path.exists() { path.to_owned() @@ -243,7 +243,7 @@ impl<'data> FileLoader<'data> { pub(crate) fn load_inputs>( &mut self, inputs: &[Input], - args: &'data Args, + args: &'data ElfArgs, plugin: &mut Option>, ) -> Result> { timing_phase!("Open input files"); @@ -408,7 +408,7 @@ impl<'data> FileLoader<'data> { fn process_linker_script<'data>( input_file: &'data InputFile, - args: &Args, + args: &ElfArgs, ) -> Result> { let bytes = input_file.data(); let script = LinkerScript::parse(bytes, &input_file.filename)?; @@ -698,7 +698,7 @@ fn read_script_data<'data>( } impl Input { - fn path(&self, args: &Args) -> Result { + fn path(&self, args: &ElfArgs) -> Result { match &self.spec { InputSpec::File(p) => { if self.search_first.is_some() diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs index 1b445f8ed..97bfd886c 100644 --- a/libwild/src/layout.rs +++ b/libwild/src/layout.rs @@ -8,7 +8,7 @@ use self::elf::Symbol; use crate::OutputKind; use crate::alignment; use crate::alignment::Alignment; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::BuildIdOption; use crate::args::Strip; use crate::bail; @@ -1456,7 +1456,7 @@ impl<'data> Layout<'data> { i } - pub(crate) fn args(&self) -> &'data Args { + pub(crate) fn args(&self) -> &'data ElfArgs { self.symbol_db.args } @@ -1737,7 +1737,7 @@ fn compute_segment_layout( output_order: &OutputOrder, program_segments: &ProgramSegments, header_info: &HeaderInfo, - args: &Args, + args: &ElfArgs, ) -> Result { #[derive(Clone)] struct Record { @@ -3171,7 +3171,7 @@ impl<'data> PreludeLayoutState<'data> { &mut self, common: &mut CommonGroupState, uses_tlsld: &AtomicBool, - args: &Args, + args: &ElfArgs, output_kind: OutputKind, ) { if uses_tlsld.load(atomic::Ordering::Relaxed) { @@ -3649,7 +3649,7 @@ fn should_emit_undefined_error( sym_file_id: FileId, sym_def_file_id: FileId, flags: ValueFlags, - args: &Args, + args: &ElfArgs, output_kind: OutputKind, ) -> bool { if (output_kind.is_shared_object() && !args.no_undefined) || symbol.is_weak() { @@ -3722,7 +3722,7 @@ impl<'data> SyntheticSymbolsLayoutState<'data> { impl EpilogueLayoutState { fn new( - args: &Args, + args: &ElfArgs, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition], ) -> EpilogueLayoutState { @@ -5215,7 +5215,7 @@ fn layout_section_parts( output_sections: &OutputSections, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &Args, + args: &ElfArgs, ) -> OutputSectionPartMap { let segment_alignments = compute_segment_alignments(sizes, program_segments, output_order, args); @@ -5332,7 +5332,7 @@ fn compute_segment_alignments( sizes: &OutputSectionPartMap, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &Args, + args: &ElfArgs, ) -> HashMap { timing_phase!("Computing segment alignments"); @@ -5917,7 +5917,7 @@ fn test_no_disallowed_overlaps() { let mut output_sections = OutputSections::with_base_address(0x1000); let (output_order, program_segments) = output_sections.output_order(); - let args = Args::default(); + let args = ElfArgs::default(); let section_part_sizes = output_sections.new_part_map::().map(|_, _| 7); let section_part_layouts = layout_section_parts( diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index c850d0994..ced519d99 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -62,6 +62,7 @@ pub(crate) mod subprocess; pub(crate) mod subprocess; pub(crate) mod symbol; pub(crate) mod symbol_db; +pub(crate) mod target_os; pub(crate) mod timing; pub(crate) mod validation; pub(crate) mod value_flags; @@ -78,6 +79,7 @@ use crate::platform::Platform; use crate::value_flags::PerSymbolFlags; use crate::version_script::VersionScript; pub use args::Args; +use args::ElfArgs; use colosseum::sync::Arena; use crossbeam_utils::atomic::AtomicCell; use error::AlreadyInitialised; @@ -89,15 +91,33 @@ use output_section_id::OutputSections; use std::io::BufWriter; use std::io::Write; use std::path::Path; -pub use subprocess::run_in_subprocess; use tracing_subscriber::EnvFilter; use tracing_subscriber::fmt; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -/// Runs the linker and cleans up associated resources. Only use this function if you've OK with -/// waiting for cleanup. -pub fn run(args: Args) -> error::Result { +/// Runs the linker. Dispatches to the appropriate format-specific linker based on `target_args`. +pub fn run(args: args::Args) -> error::Result { + match args.target_args { + args::TargetArgs::Elf(elf_args) => run_elf(elf_args), + args::TargetArgs::Pe(_) => Err(anyhow::anyhow!("PE linking not yet implemented").into()), + } +} + +/// # Safety +/// Must not be called once threads have been spawned. +pub unsafe fn run_in_subprocess(args: args::Args) -> ! { + match args.target_args { + args::TargetArgs::Elf(elf_args) => unsafe { subprocess::run_in_subprocess(elf_args) }, + args::TargetArgs::Pe(_) => { + eprintln!("PE linking does not support fork mode"); + std::process::exit(1); + } + } +} + +/// Runs the ELF linker and cleans up associated resources. +pub(crate) fn run_elf(args: ElfArgs) -> error::Result { // Note, we need to setup tracing before we activate the thread pool. In particular, we need to // initialise the timing module before the worker threads are started, otherwise the threads // won't contribute to counters such as --time=cycles,instructions etc. @@ -113,7 +133,7 @@ pub fn run(args: Args) -> error::Result { /// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be /// called once and only if nothing else has already set the global tracing dispatcher. Calling this /// is optional. If it isn't called, no tracing-based features will function. e.g. --time. -pub fn setup_tracing(args: &Args) -> Result<(), AlreadyInitialised> { +pub fn setup_tracing(args: &ElfArgs) -> Result<(), AlreadyInitialised> { if let Some(opts) = args.time_phase_options.as_ref() { timing::init_tracing(opts) } else if args.print_allocations.is_some() { @@ -207,7 +227,7 @@ impl Linker { fn link_for_arch<'data, P: Platform<'data, File = crate::elf::File<'data>>>( &'data self, - args: &'data Args, + args: &'data ElfArgs, ) -> error::Result> { let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); @@ -236,7 +256,7 @@ impl Linker { fn load_inputs_and_link<'data, P: Platform<'data, File = crate::elf::File<'data>>>( &'data self, file_loader: &mut FileLoader<'data>, - args: &'data Args, + args: &'data ElfArgs, ) -> error::Result> { let mut plugin = linker_plugins::LinkerPlugin::from_args(args, &self.linker_plugin_arena, &self.herd)?; diff --git a/libwild/src/linker_plugins.rs b/libwild/src/linker_plugins.rs index 98509e283..8434ce1e0 100644 --- a/libwild/src/linker_plugins.rs +++ b/libwild/src/linker_plugins.rs @@ -9,7 +9,7 @@ //! up having to make quite a bit of use of thread locals in order to get state to where it needs to //! be. -use crate::Args; +use crate::args::ElfArgs; use crate::args::Input; use crate::args::Modifiers; use crate::bail; @@ -68,7 +68,7 @@ enum Store<'data> { } struct LoadInfo<'data> { - args: &'data Args, + args: &'data ElfArgs, arena: &'data Arena, } @@ -128,7 +128,7 @@ pub(crate) struct PluginOutputs { impl<'data> LinkerPlugin<'data> { pub(crate) fn from_args( - args: &'data crate::Args, + args: &'data crate::ElfArgs, arena: &'data Arena, herd: &'data Herd, ) -> Result>> { @@ -319,7 +319,7 @@ impl<'data> WrapSymbols<'data> { } impl LoadedPlugin { - fn new(plugin_path: &Path, args: &Args) -> Result { + fn new(plugin_path: &Path, args: &ElfArgs) -> Result { timing_phase!("Load linker plugin"); if cfg!(target_feature = "crt-static") { diff --git a/libwild/src/linker_plugins_disabled.rs b/libwild/src/linker_plugins_disabled.rs index 7570c686b..585504e09 100644 --- a/libwild/src/linker_plugins_disabled.rs +++ b/libwild/src/linker_plugins_disabled.rs @@ -35,7 +35,7 @@ impl<'data> LinkerPlugin<'data> { } pub(crate) fn from_args( - _args: &'data crate::Args, + _args: &'data crate::args::ElfArgs, _linker_plugin_arena: &colosseum::sync::Arena, _herd: &bumpalo_herd::Herd, ) -> Result> { diff --git a/libwild/src/output_kind.rs b/libwild/src/output_kind.rs index e4c988671..70babbcc8 100644 --- a/libwild/src/output_kind.rs +++ b/libwild/src/output_kind.rs @@ -1,4 +1,4 @@ -use crate::Args; +use crate::args::ElfArgs; use crate::args::RelocationModel; use crate::input_data::FileLoader; @@ -10,7 +10,7 @@ pub(crate) enum OutputKind { } impl OutputKind { - pub(crate) fn new(args: &Args, input_data: &FileLoader<'_>) -> OutputKind { + pub(crate) fn new(args: &ElfArgs, input_data: &FileLoader<'_>) -> OutputKind { if !args.should_output_executable { OutputKind::SharedObject } else if args.dynamic_linker.is_some() diff --git a/libwild/src/output_section_id.rs b/libwild/src/output_section_id.rs index c5d139dbf..48509dcc5 100644 --- a/libwild/src/output_section_id.rs +++ b/libwild/src/output_section_id.rs @@ -18,7 +18,7 @@ use crate::alignment; use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; -use crate::args::Args; +use crate::args::ElfArgs; use crate::elf; use crate::elf::DynamicEntry; use crate::elf::GLOBAL_POINTER_SYMBOL_NAME; @@ -1016,7 +1016,7 @@ impl<'data> OutputSections<'data> { &mut self, custom_sections: &[CustomSectionDetails<'data>], sections: &mut [SectionSlot], - args: &Args, + args: &ElfArgs, ) { for custom in custom_sections { let name_str = std::str::from_utf8(custom.name.bytes()).ok(); diff --git a/libwild/src/parsing.rs b/libwild/src/parsing.rs index 85671aa8c..bc29b9c49 100644 --- a/libwild/src/parsing.rs +++ b/libwild/src/parsing.rs @@ -1,6 +1,6 @@ use crate::OutputKind; use crate::OutputSections; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::DefsymValue; use crate::args::Modifiers; use crate::args::RelocationModel; @@ -190,7 +190,7 @@ impl<'data> InternalSymDefInfo<'data> { } impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { - pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { + pub(crate) fn new(input: &InputBytes<'data>, args: &ElfArgs) -> Result> { verbose_timing_phase!("Parse file"); let object = O::parse(input, args) @@ -213,7 +213,7 @@ impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { } impl<'data> Prelude<'data> { - pub(crate) fn new(args: &'data Args, output_kind: OutputKind) -> Self { + pub(crate) fn new(args: &'data ElfArgs, output_kind: OutputKind) -> Self { verbose_timing_phase!("Construct prelude"); // The undefined symbol must always be symbol 0. diff --git a/libwild/src/part_id.rs b/libwild/src/part_id.rs index 9135e7623..26ad8b5b6 100644 --- a/libwild/src/part_id.rs +++ b/libwild/src/part_id.rs @@ -1,6 +1,6 @@ use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; -use crate::args::Args; +use crate::args::ElfArgs; use crate::output_section_id::BuiltInSectionDetails; use crate::output_section_id::FINI; use crate::output_section_id::INIT; @@ -60,7 +60,7 @@ pub(crate) const CUSTOM_PLACEHOLDER: PartId = PartId(u32::MAX); pub(crate) fn should_merge_sections( section_flags: S, section_alignment: u64, - args: &Args, + args: &ElfArgs, ) -> bool { if !args.merge_sections { return false; diff --git a/libwild/src/platform.rs b/libwild/src/platform.rs index ee689f06d..ee23f143e 100644 --- a/libwild/src/platform.rs +++ b/libwild/src/platform.rs @@ -1,4 +1,4 @@ -use crate::Args; +use crate::args::ElfArgs; use crate::OutputKind; use crate::Result; use crate::bail; @@ -183,7 +183,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// As for `parse_bytes` but also validates that the file architecture matches what is expected /// based on `args`. - fn parse(input: &InputBytes<'data>, args: &Args) -> Result; + fn parse(input: &InputBytes<'data>, args: &ElfArgs) -> Result; fn is_dynamic(&self) -> bool; @@ -267,7 +267,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Self::DynamicLayout; fn new_epilogue_layout( - args: &Args, + args: &ElfArgs, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout; @@ -368,7 +368,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Result; fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, + args: &ElfArgs, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -401,7 +401,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// Called after GC phase has completed. Mostly useful for platform-specific logging. fn finalise_find_required_sections(groups: &[layout::GroupState]); - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args); + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &ElfArgs); fn finalise_object_sizes( object: &mut layout::ObjectLayoutState<'data>, diff --git a/libwild/src/resolution.rs b/libwild/src/resolution.rs index dea0c4c8b..ceb6b4022 100644 --- a/libwild/src/resolution.rs +++ b/libwild/src/resolution.rs @@ -4,7 +4,7 @@ use crate::LayoutRules; use crate::alignment::Alignment; -use crate::args::Args; +use crate::args::ElfArgs; use crate::bail; use crate::debug_assert_bail; use crate::elf::RawSymbolName; @@ -688,7 +688,7 @@ pub(crate) struct ResolvedLtoInput { fn assign_section_ids<'data, O: ObjectFile<'data>>( resolved: &mut [ResolvedGroup<'data, O>], output_sections: &mut OutputSections<'data>, - args: &Args, + args: &ElfArgs, ) { timing_phase!("Assign section IDs"); @@ -1123,7 +1123,7 @@ impl<'data, O: ObjectFile<'data>> ResolvedDynamic<'data, O> { fn resolve_sections_for_object<'data, O: ObjectFile<'data>>( obj: &mut ResolvedObject<'data, O>, - args: &Args, + args: &ElfArgs, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, @@ -1151,7 +1151,7 @@ fn resolve_section<'data, O: ObjectFile<'data>>( input_section_index: SectionIndex, input_section: &O::SectionHeader, obj: &mut ResolvedObject<'data, O>, - args: &Args, + args: &ElfArgs, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, diff --git a/libwild/src/save_dir.rs b/libwild/src/save_dir.rs index 32d9bebc2..69fca2e40 100644 --- a/libwild/src/save_dir.rs +++ b/libwild/src/save_dir.rs @@ -1,6 +1,6 @@ //! Support for saving inputs for later use. -use crate::Args; +use crate::args::ElfArgs; use crate::archive::ArchiveEntry; use crate::archive::ArchiveIterator; use crate::args::Modifiers; @@ -48,7 +48,7 @@ impl SaveDir { )))) } - pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &Args) -> Result { + pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &ElfArgs) -> Result { if let Some(state) = self.0.as_ref() { let mut files_to_copy = state.files_to_copy.clone(); files_to_copy.extend( @@ -132,7 +132,7 @@ impl SaveDirState { fn finish<'a, I: Iterator>( &self, filenames: I, - parsed_args: &Args, + parsed_args: &ElfArgs, ) -> Result { for filename in filenames { self.copy_file(&std::path::absolute(filename)?, parsed_args)?; @@ -148,7 +148,7 @@ impl SaveDirState { Ok(()) } - fn write_args_file(&self, run_file: &Path, args: &Args) -> Result { + fn write_args_file(&self, run_file: &Path, args: &ElfArgs) -> Result { let mut file = std::fs::File::create(run_file)?; let mut out = BufWriter::new(&mut file); out.write_all(PRELUDE.as_bytes())?; @@ -229,7 +229,7 @@ impl SaveDirState { } /// Copies `source_path` to our output directory. - fn copy_file(&self, source_path: &Path, parsed_args: &Args) -> Result { + fn copy_file(&self, source_path: &Path, parsed_args: &ElfArgs) -> Result { let dest_path = self.output_path(source_path); if dest_path.exists() || !source_path.exists() { @@ -273,6 +273,15 @@ impl SaveDirState { self.copy_file(&absolute_target, parsed_args)?; } + #[cfg(windows)] + std::os::windows::fs::symlink_file(&target, &dest_path).with_context(|| { + format!( + "Failed to symlink {} to {}", + dest_path.display(), + target.display() + ) + })?; + #[cfg(unix)] std::os::unix::fs::symlink(&target, &dest_path).with_context(|| { format!( "Failed to symlink {} to {}", @@ -331,7 +340,7 @@ impl SaveDirState { } /// Copies the files listed by the thin archive. - fn handle_thin_archive(&self, path: &Path, parsed_args: &Args) -> Result { + fn handle_thin_archive(&self, path: &Path, parsed_args: &ElfArgs) -> Result { let file_bytes = std::fs::read(path)?; let parent_path = path.parent().unwrap(); @@ -459,7 +468,7 @@ fn to_output_relative_path(path: &Path) -> PathBuf { /// Saves certain environment variables into the script. We only propagate environment variables /// that are known to be used for communication between the compiler and say linker plugins. -fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &Args) -> Result { +fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &ElfArgs) -> Result { for var in &["COLLECT_GCC", "COLLECT_GCC_OPTIONS"] { if let Ok(mut value) = std::env::var(var) { // COLLECT_GCC_OPTIONS has things like "-o /path/to/output-file" in it. Update these so diff --git a/libwild/src/string_merging.rs b/libwild/src/string_merging.rs index 887b4ad80..853bcb528 100644 --- a/libwild/src/string_merging.rs +++ b/libwild/src/string_merging.rs @@ -26,7 +26,7 @@ //! in our primary offset map. use crate::alignment; -use crate::args::Args; +use crate::args::ElfArgs; use crate::args::Experiment; use crate::bail; use crate::error::Context as _; @@ -215,7 +215,7 @@ pub(crate) struct MergeStringsSectionBucket<'data> { pub(crate) fn merge_strings<'data>( inputs: &StringMergeInputs<'data>, output_sections: &OutputSections, - args: &Args, + args: &ElfArgs, ) -> Result>> { timing_phase!("Merge strings"); @@ -426,7 +426,7 @@ impl<'data> MergedStringsSection<'data> { &mut self, input_sections: &[StringMergeInputSection<'data>], reuse_pool: &ReusePool, - args: &Args, + args: &ElfArgs, ) -> Result { let mut resources = create_split_resources(&mut self.string_offsets, input_sections, reuse_pool, args); @@ -587,7 +587,7 @@ fn create_split_resources<'data, 'offsets, 'scope>( string_offsets: &'offsets mut OffsetMap, input_sections: &'scope [StringMergeInputSection<'data>], reuse_pool: &'scope ReusePool, - args: &Args, + args: &ElfArgs, ) -> SplitResources<'data, 'offsets, 'scope> { verbose_timing_phase!("Create input section groups"); diff --git a/libwild/src/subprocess.rs b/libwild/src/subprocess/linux.rs similarity index 96% rename from libwild/src/subprocess.rs rename to libwild/src/subprocess/linux.rs index 61ed90e48..12fabeff3 100644 --- a/libwild/src/subprocess.rs +++ b/libwild/src/subprocess/linux.rs @@ -1,4 +1,4 @@ -use crate::Args; +use crate::args::ElfArgs; use crate::bail; use crate::error::Context as _; use crate::error::Result; @@ -20,7 +20,7 @@ use std::ffi::c_void; /// # Safety /// Must not be called once threads have been spawned. Calling this function from main is generally /// the best way to ensure this. -pub unsafe fn run_in_subprocess(args: Args) -> ! { +pub unsafe fn run_in_subprocess(args: ElfArgs) -> ! { let exit_code = match subprocess_result(args) { Ok(code) => code, Err(error) => crate::error::report_error_and_exit(&error), @@ -28,7 +28,7 @@ pub unsafe fn run_in_subprocess(args: Args) -> ! { std::process::exit(exit_code); } -fn subprocess_result(args: Args) -> Result { +fn subprocess_result(args: ElfArgs) -> Result { let mut fds: [c_int; 2] = [0; 2]; // create the pipe used to communicate between the parent and child processes - exit on failure make_pipe(&mut fds).context("make_pipe")?; @@ -51,7 +51,7 @@ fn subprocess_result(args: Args) -> Result { -1 => { // Fork failure in the parent - Fallback to running linker in this process - crate::run(args)?; + crate::run_elf(args)?; Ok(0) } pid => { diff --git a/libwild/src/subprocess/mod.rs b/libwild/src/subprocess/mod.rs new file mode 100644 index 000000000..646343ba0 --- /dev/null +++ b/libwild/src/subprocess/mod.rs @@ -0,0 +1,18 @@ +#[cfg(target_os = "linux")] +mod linux; +#[cfg(target_os = "windows")] +mod windows; + +#[cfg(target_os = "linux")] +pub use linux::run_in_subprocess; +#[cfg(target_os = "windows")] +pub use windows::run_in_subprocess; + +#[cfg(not(any(target_os = "linux", target_os = "windows")))] +pub unsafe fn run_in_subprocess(args: crate::args::ElfArgs) -> ! { + let exit_code = match crate::run_elf(args) { + Ok(()) => 0, + Err(error) => crate::error::report_error_and_exit(&error), + }; + std::process::exit(exit_code); +} diff --git a/libwild/src/subprocess/windows.rs b/libwild/src/subprocess/windows.rs new file mode 100644 index 000000000..771ac8f62 --- /dev/null +++ b/libwild/src/subprocess/windows.rs @@ -0,0 +1,168 @@ +use crate::args::ElfArgs as OsArgs; +use crate::bail; +use crate::error::Result; +use phnt::ffi::HANDLE; +use phnt::ffi::NtClose; +use phnt::ffi::NtCreateUserProcess; +use phnt::ffi::NtTerminateProcess; +use phnt::ffi::NtWaitForSingleObject; +use phnt::ffi::PROCESS_CREATE_FLAGS_INHERIT_HANDLES; +use phnt::ffi::PS_CREATE_INFO; +use std::ptr; +use windows_sys::Win32::Foundation::CloseHandle; +use windows_sys::Win32::Foundation::FALSE; +use windows_sys::Win32::Foundation::STATUS_PROCESS_CLONED; +use windows_sys::Win32::Foundation::TRUE; +use windows_sys::Win32::Security::SECURITY_ATTRIBUTES; +use windows_sys::Win32::Storage::FileSystem::ReadFile; +use windows_sys::Win32::Storage::FileSystem::WriteFile; +use windows_sys::Win32::System::Console::ATTACH_PARENT_PROCESS; +use windows_sys::Win32::System::Console::AttachConsole; +use windows_sys::Win32::System::Console::FreeConsole; +use windows_sys::Win32::System::Pipes::CreatePipe; +use windows_sys::Win32::System::Threading::PROCESS_ALL_ACCESS; +use windows_sys::Win32::System::Threading::THREAD_ALL_ACCESS; + +/// Runs the linker, in a subprocess if possible, prints any errors, then exits. +/// +/// This is done by forking a sub-process which runs the linker and waits for communication back +/// from the sub-process (via a pipe) when the main link task is done (the output file has been +/// written, but some shutdown tasks remain. +/// +/// Don't call `setup_tracing` or `setup_thread_pool` if using this function, these will be called +/// for you in the subprocess. +/// +/// # Safety +/// Must not be called once threads have been spawned. Calling this function from main is generally +/// the best way to ensure this. +pub unsafe fn run_in_subprocess(args: OsArgs) -> ! { + let exit_code = match subprocess_result(args) { + Ok(code) => code, + Err(error) => crate::error::report_error_and_exit(&error), + }; + std::process::exit(exit_code); +} + +#[allow(non_upper_case_globals)] +pub const NtCurrentProcess: HANDLE = -1isize as *mut std::ffi::c_void; + +fn subprocess_result(args: OsArgs) -> Result { + let (read_end, write_end) = make_pipe()?; + + let mut hprocess: HANDLE = std::ptr::null_mut(); + let mut hthread: HANDLE = std::ptr::null_mut(); + + match unsafe { fork(&mut hprocess, &mut hthread) } { + STATUS_PROCESS_CLONED => { + // executing inside the clone + + // re attach to the parent's console to be able to write to it + unsafe { + FreeConsole(); + AttachConsole(ATTACH_PARENT_PROCESS); + }; + + crate::setup_tracing(&args)?; + let args = args.activate_thread_pool()?; + let linker = crate::Linker::new(); + let _outputs = linker.run(&args)?; + inform_parent_done(write_end); + unsafe { NtTerminateProcess(NtCurrentProcess, STATUS_PROCESS_CLONED) }; + Ok(0) + } + 0 => { + let exit_status = wait_for_child_done(read_end, hprocess, hthread); + Ok(exit_status) + } + _ => { + // Fork failure in the parent - Fallback to running linker in this process + crate::run_elf(args)?; + Ok(0) + } + } +} + +fn inform_parent_done(write_end: HANDLE) { + let mut bytes_written = 0; + + unsafe { + WriteFile( + write_end, + "X".as_ptr(), + 1, + &mut bytes_written, + std::ptr::null_mut(), + ); + CloseHandle(write_end); + FreeConsole(); + } +} + +fn wait_for_child_done(read_end: HANDLE, hprocess: HANDLE, hthread: HANDLE) -> i32 { + let mut response: [u8; 1] = [0u8; 1]; + let mut bytes_read = 0; + match unsafe { + ReadFile( + read_end, + response.as_mut_ptr(), + 1, + &mut bytes_read, + std::ptr::null_mut(), + ) + } { + TRUE => { + // Child sent a byte, which indicates that it succeeded and is now shutting down in + // the background. + 0 + } + _ => { + // Child closed pipe without sending a byte - get the process exit_status + let status = unsafe { NtWaitForSingleObject(hprocess, FALSE as _, ptr::null_mut()) }; + unsafe { + NtClose(hprocess); + NtClose(hthread); + }; + status + } + } +} + +unsafe fn fork(hprocess: &mut HANDLE, hthread: &mut HANDLE) -> i32 { + let mut create_info: PS_CREATE_INFO = unsafe { std::mem::zeroed() }; + create_info.Size = std::mem::size_of::() as _; + + unsafe { + NtCreateUserProcess( + hprocess, + hthread, + PROCESS_ALL_ACCESS, + THREAD_ALL_ACCESS, + std::ptr::null_mut(), + std::ptr::null_mut(), + PROCESS_CREATE_FLAGS_INHERIT_HANDLES, + 0, + std::ptr::null_mut(), + &mut create_info, + std::ptr::null_mut(), + ) + } +} + +fn make_pipe() -> Result<(HANDLE, HANDLE)> { + let mut read_end: HANDLE = std::ptr::null_mut(); + let mut write_end: HANDLE = std::ptr::null_mut(); + + let security_attributes = SECURITY_ATTRIBUTES { + nLength: std::mem::size_of::() as u32, + lpSecurityDescriptor: std::ptr::null_mut(), + bInheritHandle: TRUE, // The crucial part! + }; + + match unsafe { CreatePipe(&mut read_end, &mut write_end, &security_attributes, 0) } { + TRUE => Ok((read_end, write_end)), + _ => bail!( + "Error creating pipe. Errno = {:?}", + std::io::Error::last_os_error().raw_os_error().unwrap_or(-1) + ), + } +} diff --git a/libwild/src/subprocess_unsupported.rs b/libwild/src/subprocess_unsupported.rs index 4ee4862f7..933fc378b 100644 --- a/libwild/src/subprocess_unsupported.rs +++ b/libwild/src/subprocess_unsupported.rs @@ -1,7 +1,7 @@ /// # Safety /// See function of the same name in `subprocess.rs` -pub unsafe fn run_in_subprocess(args: crate::Args) -> ! { - let exit_code = match crate::run(args) { +pub unsafe fn run_in_subprocess(args: crate::args::ElfArgs) -> ! { + let exit_code = match crate::run_elf(args) { Ok(()) => 0, Err(error) => { eprintln!("{}", error.to_string()); diff --git a/libwild/src/symbol_db.rs b/libwild/src/symbol_db.rs index 6adc44263..f74ce4090 100644 --- a/libwild/src/symbol_db.rs +++ b/libwild/src/symbol_db.rs @@ -4,7 +4,7 @@ use crate::InputLinkerScript; use crate::OutputKind; use crate::args; -use crate::args::Args; +use crate::args::ElfArgs; use crate::bail; use crate::elf::RawSymbolName; use crate::error; @@ -71,7 +71,7 @@ use symbolic_demangle::demangle; #[derive(Debug)] pub struct SymbolDb<'data, O: ObjectFile<'data>> { - pub(crate) args: &'data Args, + pub(crate) args: &'data ElfArgs, pub(crate) groups: Vec>, @@ -321,7 +321,7 @@ impl<'data, O: ObjectFile<'data>> SymbolDb<'data, O> { } pub(crate) fn new( - args: &'data Args, + args: &'data ElfArgs, output_kind: OutputKind, auxiliary: &AuxiliaryFiles<'data>, herd: &'data bumpalo_herd::Herd, @@ -1393,7 +1393,7 @@ pub(crate) fn is_mapping_symbol_name(name: &[u8]) -> bool { fn read_symbols<'data, O: ObjectFile<'data>>( version_script: &VersionScript, shards: &mut [SymbolWriterShard<'_, '_, 'data, O>], - args: &Args, + args: &ElfArgs, export_list: &Option>, output_kind: OutputKind, ) -> Result>> { @@ -1421,7 +1421,7 @@ fn read_symbols_for_group<'data, O: ObjectFile<'data>>( version_script: &VersionScript, export_list: &Option>, num_buckets: usize, - args: &Args, + args: &ElfArgs, output_kind: OutputKind, ) -> Result> { verbose_timing_phase!( @@ -1558,7 +1558,7 @@ fn load_symbols_from_file<'data, O: ObjectFile<'data>>( version_script: &VersionScript, symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, outputs: &mut SymbolLoadOutputs<'data>, - args: &Args, + args: &ElfArgs, export_list: &Option>, output_kind: OutputKind, ) -> Result { @@ -1685,7 +1685,7 @@ trait SymbolLoader<'data, O: ObjectFile<'data>> { struct RegularObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { object: &'a O, - args: &'a Args, + args: &'a ElfArgs, version_script: &'a VersionScript<'a>, archive_semantics: bool, lib_name: &'data [u8], @@ -2070,7 +2070,7 @@ impl<'data> PendingVersionedSymbol<'data> { } /// Decides how many buckets we should use for symbol names. -fn num_symbol_hash_buckets(args: &Args) -> usize { +fn num_symbol_hash_buckets(args: &ElfArgs) -> usize { args.available_threads.get() } diff --git a/libwild/src/target_os.rs b/libwild/src/target_os.rs new file mode 100644 index 000000000..39d0f44d1 --- /dev/null +++ b/libwild/src/target_os.rs @@ -0,0 +1,57 @@ +use std::{fmt::Display, str::FromStr}; + +use crate::bail; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum Os { + Linux, + Windows, + MacOS, +} + +impl Os { + pub const DEFAULT: Self = const { + #[cfg(target_os = "linux")] + { + Os::Linux + } + #[cfg(target_os = "windows")] + { + Os::Windows + } + #[cfg(target_os = "macos")] + { + Os::MacOS + } + }; +} + +impl Default for Os { + fn default() -> Self { + Os::DEFAULT + } +} + +impl FromStr for Os { + type Err = crate::error::Error; + + fn from_str(s: &str) -> Result { + match s { + "linux" => Ok(Os::Linux), + "windows" => Ok(Os::Windows), + "macos" => Ok(Os::MacOS), + _ => bail!("-m {s} is not yet supported"), + } + } +} + +impl Display for Os { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let os = match self { + Os::Linux => "linux", + Os::Windows => "windows", + Os::MacOS => "macos", + }; + write!(f, "{os}") + } +} diff --git a/wild/src/main.rs b/wild/src/main.rs index 4095d4610..01789fcf7 100644 --- a/wild/src/main.rs +++ b/wild/src/main.rs @@ -20,7 +20,7 @@ fn run() -> libwild::error::Result { let args = libwild::Args::parse(|| std::env::args().skip(1))?; - if args.should_fork() { + if args.should_fork { // Safety: We haven't spawned any threads yet. unsafe { libwild::run_in_subprocess(args) }; } else { diff --git a/windows/wlibwild/Cargo.toml b/windows/wlibwild/Cargo.toml new file mode 100644 index 000000000..8333a3a2f --- /dev/null +++ b/windows/wlibwild/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "wlibwild" +repository.workspace = true +license.workspace = true +version.workspace = true +rust-version.workspace = true +edition.workspace = true + +[dependencies] +anyhow = { workspace = true } +bytemuck = { workspace = true } +bytesize = { workspace = true } +colored = { workspace = true } +indexmap = { workspace = true } +itertools = { workspace = true } +rayon = { workspace = true } +tracing = { workspace = true } +object = { workspace = true } +tracing-subscriber = { workspace = true, features = ["ansi"] } +walkdir = "2" + + +[target.'cfg(target_os = "windows")'.dependencies] +phnt = { workspace = true } + +[target.'cfg(target_os = "windows")'.dependencies.windows-sys] +workspace = true +features = [ + "Win32_System_Threading", + "Win32_System_Console", + "Win32_System_Pipes", + "Win32_Security", + "Win32_Storage_FileSystem", + "Win32_System_IO", +] + + +[lints] +workspace = true diff --git a/windows/wlibwild/done.txzt b/windows/wlibwild/done.txzt new file mode 100644 index 000000000..e7eec290e --- /dev/null +++ b/windows/wlibwild/done.txzt @@ -0,0 +1,3 @@ +Linker has finished running at SystemTime { + intervals: 134000631526992380, +} \ No newline at end of file diff --git a/windows/wlibwild/example-linkerflags-rust.txt b/windows/wlibwild/example-linkerflags-rust.txt new file mode 100644 index 000000000..cd3aabdf7 --- /dev/null +++ b/windows/wlibwild/example-linkerflags-rust.txt @@ -0,0 +1,35 @@ +"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\link.exe" +"/NOLOGO" +"C:\\Users\\Samuel\\AppData\\Local\\Temp\\rustc7RL5Io\\symbols.o" +"dummy.dummy.6cfbe55db138f4b-cgu.0.rcgu.o" +"dummy.3wxfnlvokcqcl6j45c8xeicgz.rcgu.o" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-efa6c7783284bd31.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-43468c47cff21662.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libwindows_targets-3935b75a1bd1c449.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-cc0fa0adec36251f.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-22f2c46a93af1174.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-c835068eb56f6efb.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-abe24411cb8f5bd4.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-b5e24931eb1ae1bd.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-8dc64876e32b9d07.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-214bcacef209824d.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-3e14ad51a3206bab.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-a55e6b132b0b5f5d.rlib" +"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-b994e165f6ecc9e9.rlib" +"kernel32.lib" +"kernel32.lib" +"kernel32.lib" +"ntdll.lib" +"userenv.lib" +"ws2_32.lib" +"dbghelp.lib" +"/defaultlib:msvcrt" +"/NXCOMPAT" +"/OUT:dummy.exe" +"/OPT:REF,NOICF" +"/DEBUG" +"/PDBALTPATH:%_PDB%" +"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" +"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" +"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" +"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis" \ No newline at end of file diff --git a/windows/wlibwild/src/bin/main.rs b/windows/wlibwild/src/bin/main.rs new file mode 100644 index 000000000..f5764a5c5 --- /dev/null +++ b/windows/wlibwild/src/bin/main.rs @@ -0,0 +1,3 @@ +fn main() { + unsafe { wlibwild::run_in_subprocess() } +} diff --git a/windows/wlibwild/src/lib.rs b/windows/wlibwild/src/lib.rs new file mode 100644 index 000000000..3a3e9d015 --- /dev/null +++ b/windows/wlibwild/src/lib.rs @@ -0,0 +1,201 @@ +use object::LittleEndian as LE; +use object::coff::CoffHeader; +use object::coff::SectionTable; +use object::coff::SymbolTable; +use object::pe::ImageFileHeader; +use std::io::Write; +use std::path::PathBuf; +use tracing::debug; +use tracing::info; +use tracing::warn; +mod subprocess; +use tracing_subscriber::{ + Layer as _, fmt::format::FmtSpan, layer::SubscriberExt as _, util::SubscriberInitExt, +}; +mod paths; + +pub fn setup_logging() { + tracing_subscriber::registry() + .with( + tracing_subscriber::fmt::layer() + .with_line_number(true) + .with_file(true) + .with_span_events(FmtSpan::CLOSE) + .with_filter( + tracing_subscriber::EnvFilter::try_from_default_env() + .unwrap_or("wlibwild=info,warn".into()), + ), + ) + .init(); +} + +pub struct Linker; + +impl Linker { + pub fn new() -> Self { + Linker + } + + pub fn run(&self) -> anyhow::Result { + // This is where the linking logic would go + info!("Linker is running"); + let files = vec![ + PathBuf::from("basic_objs/function.o"), + PathBuf::from("basic_objs/main.o"), + ]; + link_files(files).unwrap(); + + Ok(LinkerDrop) + } +} + +pub struct LinkerDrop; + +impl Drop for LinkerDrop { + fn drop(&mut self) { + info!("Linker has finished running"); + std::thread::sleep(std::time::Duration::from_secs(5)); + std::fs::write( + "./done.txzt", + format!( + "Linker has finished running at {:#?}", + std::time::SystemTime::now() + ), + ) + .expect("Failed to write done file"); + } +} + +pub use subprocess::run_in_subprocess; + +pub fn run() -> Result<(), anyhow::Error> { + let linker = Linker::new(); + + linker.run()?; + Ok(()) +} + +fn link_files(files: Vec) -> anyhow::Result<()> { + info!("Starting to link files: {:?}", files); + for file in files { + let debug_output = std::fs::File::create(file.with_extension("debug"))?; + let mut writer = std::io::BufWriter::new(debug_output); + let data = std::fs::read(file)?; + parse_object(&mut writer, &data)?; + } + + Ok(()) +} + +fn parse_object(debug_output: &mut impl Write, data: &[u8]) -> anyhow::Result<()> { + let kind = object::FileKind::parse(data)?; + + match kind { + object::FileKind::Coff => { + debug!("COFF file detected"); + writeln!(debug_output, "COFF file detected")?; + print_coff(debug_output, data)?; + } + object::FileKind::Pe32 => { + info!("PE32 file detected"); + } + object::FileKind::Pe64 => { + info!("PE64 file detected"); + } + kind => { + warn!("Unsupported file kind: {:?}", kind); + return Err(anyhow::anyhow!("Unsupported file kind: {:?}", kind)); + } + } + + // If parsing is successful + Ok(()) +} + +pub fn print_coff(debug_output: &mut impl Write, data: &[u8]) -> anyhow::Result<()> { + let mut offset = 0; + let header = ImageFileHeader::parse(data, &mut offset)?; + + let sections = header.sections(data, offset)?; + + let symbols = header.symbols(data); + print_sections( + debug_output, + data, + header.machine.get(LE), + symbols.as_ref().ok(), + §ions, + )?; + let symbols = symbols?; + // print_symbols(p, sections.as_ref(), symbols); + + Ok(()) +} + +fn print_sections<'data, Coff: CoffHeader>( + debug_output: &mut impl Write, + data: &[u8], + machine: u16, + symbols: Option<&SymbolTable<'data, &'data [u8], Coff>>, + sections: &SectionTable, +) -> anyhow::Result<()> { + for (index, section) in sections.iter().enumerate() { + if let Some(name) = symbols.and_then(|symbols| section.name(symbols.strings()).ok()) { + writeln!( + debug_output, + "Section {}: {}", + index, + str::from_utf8(name).unwrap_or(&format!("{:x?}", name)) + )?; + } else { + writeln!(debug_output, "Section {}: {:?}", index, section.raw_name())?; + } + writeln!( + debug_output, + " Virtual Size: {:#x}", + section.virtual_size.get(LE) + )?; + writeln!( + debug_output, + " Virtual Address: {:#x}", + section.virtual_address.get(LE) + )?; + writeln!( + debug_output, + " Size Of Raw Data: {:#x}", + section.size_of_raw_data.get(LE) + )?; + writeln!( + debug_output, + " Pointer To Raw Data: {:#x}", + section.pointer_to_raw_data.get(LE) + )?; + writeln!( + debug_output, + " Pointer To Relocations: {:#x}", + section.pointer_to_relocations.get(LE) + )?; + writeln!( + debug_output, + " Pointer To Linenumbers: {:#x}", + section.pointer_to_linenumbers.get(LE) + )?; + writeln!( + debug_output, + " Number Of Relocations: {}", + section.number_of_relocations.get(LE) + )?; + writeln!( + debug_output, + " Number Of Linenumbers: {}", + section.number_of_linenumbers.get(LE) + )?; + writeln!( + debug_output, + " Characteristics: {:#x}", + section.characteristics.get(LE) + )?; + } + + Ok(()) +} diff --git a/windows/wlibwild/src/paths.rs b/windows/wlibwild/src/paths.rs new file mode 100644 index 000000000..84a14c1c8 --- /dev/null +++ b/windows/wlibwild/src/paths.rs @@ -0,0 +1,204 @@ +//! A robust, self-contained module to find Windows and MSVC library paths. +//! +//! It combines two discovery methods for maximum reliability: +//! 1. **Primary:** Uses `vswhere.exe` and `vcvarsall.bat` to get the exact library +//! paths configured for the Visual Studio C++ environment. +//! 2. **Fallback:** Manually scans the standard `Windows Kits` directory. +//! +//! The results are cached in a `LazyLock` static for efficient, repeated lookups. + +use std::collections::HashMap; +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::sync::LazyLock; + +use anyhow::Context; +use rayon::iter::IntoParallelIterator; +use rayon::iter::ParallelIterator; +use walkdir::WalkDir; + +/// The lazily-initialized, thread-safe cache of library paths. +/// The closure inside is executed only once, the first time this static is accessed. +static LIBRARY_CACHE: LazyLock> = LazyLock::new(|| { + let mut all_search_paths = Vec::new(); + + // --- Primary Method: Use vswhere and vcvarsall.bat --- + // This is the most accurate way to get all MSVC and SDK paths. + match get_vc_lib_paths() { + Ok(paths) => all_search_paths.extend(paths), + Err(e) => { + eprintln!("Warning: Failed to get VC lib paths: {:?}", e); + } + }; + + // --- Fallback Method: Manually scan the Windows Kits directory --- + // This is a great backup if vswhere fails or the installation is unusual. + match get_manual_sdk_paths() { + Ok(paths) => all_search_paths.extend(paths), + Err(e) => { + eprintln!("Warning: Failed to get manual SDK paths: {:?}", e); + } + }; + + // Remove duplicate search paths to avoid scanning the same directory twice. + all_search_paths.sort(); + all_search_paths.dedup(); + + // --- Populate the cache by scanning all discovered directories --- + let cache = all_search_paths + .into_par_iter() + .fold( + || HashMap::new(), + |mut acc, search_dir| { + for entry in WalkDir::new(search_dir) + .into_iter() + .filter_map(Result::ok) + .filter(|e| { + e.file_type().is_file() && { + if let Some(name) = e.file_name().to_str() { + name.ends_with(".lib") || name.ends_with(".Lib") + } else { + false + } + } + }) + { + let path = entry.into_path(); + let file_name = path.file_name().unwrap().to_str().unwrap().to_lowercase(); + acc.insert(file_name, path); + } + + acc + }, + ) + .reduce_with(|mut acc, map| { + acc.extend(map); + acc + }) + .unwrap_or_default(); + + cache +}); + +// --- Public API --- + +/// Finds the absolute path for a given library filename. +/// +/// The first time this function is called, it will use `vswhere` and other +/// methods to discover all relevant MSVC and Windows SDK library directories, +/// scan them, and build a static, in-memory cache. All subsequent calls are +/// fast, case-insensitive lookups. +/// +/// # Returns +/// An `Option` containing a static reference to the absolute `Path`. +pub fn find_lib(lib_name: &str) -> Option<&'static Path> { + LIBRARY_CACHE + .get(&lib_name.to_lowercase()) + .map(|p| p.as_path()) +} + +// --- Private Helper Functions --- + +/// Gets library search paths by running `vcvarsall.bat` from a VS installation. +fn get_vc_lib_paths() -> anyhow::Result> { + let vcvars_path = vs_path()? + .join("VC") + .join("Auxiliary") + .join("Build") + .join("vcvarsall.bat"); + + if !vcvars_path.exists() { + anyhow::bail!( + "vcvarsall.bat not found at expected path: {}", + vcvars_path.display() + ); + } + + // The trick: run the batch script, and then immediately run the `set` command + // in the same command prompt process. This prints all environment variables. + let output = Command::new("cmd") + .arg("/C") + .arg(&vcvars_path) + .arg("x64") + .arg("&&") + .arg("set") + .output()?; + + if !output.status.success() { + anyhow::bail!( + "Failed to run vcvarsall.bat {}: {}", + output.status, + String::from_utf8_lossy(&output.stderr) + ); + } + + let env_output = String::from_utf8(output.stdout)?; + + for line in env_output.lines() { + if line.starts_with("LIB=") { + let lib_line = &line[4..]; + return Ok(env::split_paths(lib_line).collect()); + } + } + anyhow::bail!("LIB environment variable not found after running vcvarsall.bat"); +} + +fn vs_where() -> Command { + Command::new("C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe") +} +/// Finds the Visual Studio installation path using a hardcoded `vswhere` path. +fn vs_path() -> anyhow::Result { + let output = vs_where() + .args(&[ + "-latest", + "-property", + "installationPath", + "-requires", + "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + ]) + .output()?; + + let path = String::from_utf8_lossy(&output.stdout); + let path = path + .lines() + .next() + .context("Failed to find VS installation path")? + .trim(); + Ok(PathBuf::from(path)) +} + +/// Gets SDK search paths by manually scanning the `Windows Kits` directory. +fn get_manual_sdk_paths() -> anyhow::Result> { + let prog_files = + env::var("ProgramFiles(x86)").context("Failed to get ProgramFiles(x86) path")?; + let sdk_lib_path = PathBuf::from(prog_files).join("Windows Kits/10/Lib"); + + let latest_version = fs::read_dir(&sdk_lib_path) + .context("Failed to read SDK lib directory")? + .filter_map(Result::ok) + .map(|entry| entry.path()) + .filter(|path| path.is_dir()) + .max() + .ok_or_else(|| { + anyhow::anyhow!( + "No SDK version directories found in {}", + sdk_lib_path.display() + ) + })?; // max() on PathBufs works lexicographically. + + Ok(vec![ + latest_version.join("um/x64"), // User-Mode libraries + latest_version.join("ucrt/x64"), // Universal C Runtime + ]) +} + +#[test] +fn find_kernel32() { + let lib = "kernel32.lib"; + match find_lib(lib) { + Some(path) => println!("Found {} at {}", lib, path.display()), + None => println!("{} not found", lib), + } +} diff --git a/windows/wlibwild/src/subprocess.rs b/windows/wlibwild/src/subprocess.rs new file mode 100644 index 000000000..a94b098a8 --- /dev/null +++ b/windows/wlibwild/src/subprocess.rs @@ -0,0 +1,179 @@ +use phnt::ffi::HANDLE; +use phnt::ffi::NtClose; +use phnt::ffi::NtCreateUserProcess; +use phnt::ffi::NtTerminateProcess; +use phnt::ffi::NtWaitForSingleObject; +use phnt::ffi::PROCESS_CREATE_FLAGS_INHERIT_HANDLES; +use phnt::ffi::PS_CREATE_INFO; +use std::ptr; +use windows_sys::Win32::Foundation::CloseHandle; +use windows_sys::Win32::Foundation::FALSE; +use windows_sys::Win32::Foundation::STATUS_PROCESS_CLONED; +use windows_sys::Win32::Foundation::TRUE; +use windows_sys::Win32::Security::SECURITY_ATTRIBUTES; +use windows_sys::Win32::Storage::FileSystem::ReadFile; +use windows_sys::Win32::Storage::FileSystem::WriteFile; +use windows_sys::Win32::System::Console::ATTACH_PARENT_PROCESS; +use windows_sys::Win32::System::Console::AttachConsole; +use windows_sys::Win32::System::Console::FreeConsole; +use windows_sys::Win32::System::Pipes::CreatePipe; +use windows_sys::Win32::System::Threading::PROCESS_ALL_ACCESS; +use windows_sys::Win32::System::Threading::THREAD_ALL_ACCESS; + +use crate::setup_logging; + +type Result = std::result::Result>; + +/// Runs the linker, in a subprocess if possible, prints any errors, then exits. +/// +/// This is done by forking a sub-process which runs the linker and waits for communication back +/// from the sub-process (via a pipe) when the main link task is done (the output file has been +/// written, but some shutdown tasks remain. +/// +/// Don't call `setup_tracing` or `setup_thread_pool` if using this function, these will be called +/// for you in the subprocess. +/// +/// # Safety +/// Must not be called once threads have been spawned. Calling this function from main is generally +/// the best way to ensure this. +pub unsafe fn run_in_subprocess() -> ! { + let exit_code = match subprocess_result() { + Ok(code) => code, + Err(error) => { + eprintln!("{}", error.to_string()); + 1 + } + }; + std::process::exit(exit_code); +} + +#[allow(non_upper_case_globals)] +pub const NtCurrentProcess: HANDLE = -1isize as *mut std::ffi::c_void; + +fn subprocess_result() -> Result { + let (read_end, write_end) = make_pipe()?; + + let mut hprocess: HANDLE = std::ptr::null_mut(); + let mut hthread: HANDLE = std::ptr::null_mut(); + + match unsafe { fork(&mut hprocess, &mut hthread) } { + STATUS_PROCESS_CLONED => { + // executing inside the clone + + // re attach to the parent's console to be able to write to it + unsafe { + FreeConsole(); + AttachConsole(ATTACH_PARENT_PROCESS); + }; + + { + setup_logging(); + let linker = crate::Linker::new(); + let _outputs = linker.run()?; + println!("Linker has finished running, notifying parent..."); + inform_parent_done(write_end); + } + unsafe { NtTerminateProcess(NtCurrentProcess, STATUS_PROCESS_CLONED) }; + Ok(0) + } + 0 => { + println!("Waiting for child to finish..."); + let exit_status = wait_for_child_done(read_end, hprocess, hthread); + Ok(exit_status) + } + _ => { + eprintln!("Fork failure in the parent - Fallback to running linker in this process"); + // Fork failure in the parent - Fallback to running linker in this process + crate::run()?; + Ok(0) + } + } +} + +fn inform_parent_done(write_end: HANDLE) { + let mut bytes_written = 0; + + unsafe { + WriteFile( + write_end, + "X".as_ptr(), + 1, + &mut bytes_written, + std::ptr::null_mut(), + ); + println!("Parent informed that the linker has finished."); + CloseHandle(write_end); + println!("Closing write end of the pipe."); + // FreeConsole(); + } +} + +fn wait_for_child_done(read_end: HANDLE, hprocess: HANDLE, hthread: HANDLE) -> i32 { + let mut response: [u8; 1] = [0u8; 1]; + let mut bytes_read = 0; + match unsafe { + ReadFile( + read_end, + response.as_mut_ptr(), + 1, + &mut bytes_read, + std::ptr::null_mut(), + ) + } { + TRUE => { + println!( + "Child sent a byte, which indicates that it succeeded and is now shutting down in the background." + ); + // Child sent a byte, which indicates that it succeeded and is now shutting down in + // the background. + 0 + } + _ => { + eprintln!("Child closed pipe without sending a byte - getting process exit status"); + // Child closed pipe without sending a byte - get the process exit_status + let status = unsafe { NtWaitForSingleObject(hprocess, FALSE as _, ptr::null_mut()) }; + unsafe { + NtClose(hprocess); + NtClose(hthread); + }; + status + } + } +} + +unsafe fn fork(hprocess: &mut HANDLE, hthread: &mut HANDLE) -> i32 { + let mut create_info: PS_CREATE_INFO = unsafe { std::mem::zeroed() }; + create_info.Size = std::mem::size_of::() as _; + + unsafe { + NtCreateUserProcess( + hprocess, + hthread, + PROCESS_ALL_ACCESS, + THREAD_ALL_ACCESS, + std::ptr::null_mut(), + std::ptr::null_mut(), + PROCESS_CREATE_FLAGS_INHERIT_HANDLES, + 0, + std::ptr::null_mut(), + &mut create_info, + std::ptr::null_mut(), + ) + } +} + +fn make_pipe() -> Result<(HANDLE, HANDLE)> { + let mut read_end: HANDLE = std::ptr::null_mut(); + let mut write_end: HANDLE = std::ptr::null_mut(); + + let security_attributes = SECURITY_ATTRIBUTES { + nLength: std::mem::size_of::() as u32, + lpSecurityDescriptor: std::ptr::null_mut(), + bInheritHandle: TRUE, // The crucial part! + }; + + match unsafe { CreatePipe(&mut read_end, &mut write_end, &security_attributes, 0) } { + TRUE => Ok((read_end, write_end)), + _ => Err(Box::new(std::io::Error::last_os_error())), + } +} diff --git a/windows/wlibwild/w.just b/windows/wlibwild/w.just new file mode 100644 index 000000000..3ca2f9af8 --- /dev/null +++ b/windows/wlibwild/w.just @@ -0,0 +1,23 @@ +link: + cargo run -p wlibwild --bin main + +build-wild: + cargo build -p wild-linker --bin wild -r + +build-objs: + clang -c basic_objs/main.c -o basic_objs/main.o + clang -c basic_objs/function.c -o basic_objs/function.o + clang -c basic_objs/basic.c -o basic_objs/basic.o + +link-lld: + nu -c "lld-link basic_objs/main.o basic_objs/function.o /SUBSYSTEM:CONSOLE /entry:main /nodefaultlib kernel32.lib /OUT:myprogram.exe" + +wild-link: build-wild + nu -c "../../target/release/wild.exe basic_objs/main.o basic_objs/function.o /SUBSYSTEM:CONSOLE /entry:main /nodefaultlib kernel32.lib /OUT:myprogram.exe" + + +dump-exe: + @llvm-objdump --demangle --syms -C -D myprogram.exe + +run-myprogram: + nu -c "myprogram.exe" \ No newline at end of file From a0a4642bc0f0dcca843027c1c9dd3d321bedf108 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Tue, 3 Mar 2026 15:29:18 +1300 Subject: [PATCH 02/10] add generic args with support for pe --- libwild/src/args/linux.rs | 1415 +++--------------------- libwild/src/args/mod.rs | 1303 ++++++++++++++++++++-- libwild/src/args/windows.rs | 151 +-- libwild/src/diff.rs | 2 +- libwild/src/elf.rs | 15 +- libwild/src/elf_writer.rs | 7 +- libwild/src/file_writer.rs | 9 +- libwild/src/gc_stats.rs | 7 +- libwild/src/grouping.rs | 7 +- libwild/src/input_data.rs | 13 +- libwild/src/layout.rs | 25 +- libwild/src/lib.rs | 84 +- libwild/src/linker_plugins.rs | 9 +- libwild/src/linker_plugins_disabled.rs | 2 +- libwild/src/output_kind.rs | 5 +- libwild/src/output_section_id.rs | 5 +- libwild/src/parsing.rs | 7 +- libwild/src/part_id.rs | 5 +- libwild/src/platform.rs | 11 +- libwild/src/resolution.rs | 9 +- libwild/src/save_dir.rs | 15 +- libwild/src/string_merging.rs | 9 +- libwild/src/subprocess/linux.rs | 10 +- libwild/src/subprocess/mod.rs | 4 +- libwild/src/subprocess/windows.rs | 10 +- libwild/src/subprocess_unsupported.rs | 4 +- libwild/src/symbol_db.rs | 17 +- wild/src/main.rs | 60 +- 28 files changed, 1599 insertions(+), 1621 deletions(-) diff --git a/libwild/src/args/linux.rs b/libwild/src/args/linux.rs index f2a86eb3a..c8a92b9cf 100644 --- a/libwild/src/args/linux.rs +++ b/libwild/src/args/linux.rs @@ -12,29 +12,40 @@ //! Basically, we need to be able to parse arguments in the same way as the other linkers on the //! platform that we're targeting. +use super::ArgumentParser; +use super::BSymbolicKind; +use super::CopyRelocations; +use super::CopyRelocationsDisabledReason; +use super::CounterKind; +use super::DefsymValue; +use super::ExcludeLibs; +use super::FileWriteMode; +use super::Input; +use super::InputSpec; +use super::Modifiers; +use super::RelocationModel; +use super::Strip; +use super::UnresolvedSymbols; +use super::VersionMode; +use super::warn_unsupported; use crate::alignment::Alignment; +use hashbrown::HashSet; use crate::arch::Architecture; use crate::bail; use crate::ensure; use crate::error::Context as _; use crate::error::Result; -use crate::input_data::FileId; use crate::linker_script::maybe_forced_sysroot; use crate::save_dir::SaveDir; use crate::timing_phase; -use hashbrown::HashMap; -use hashbrown::HashSet; use indexmap::IndexSet; use itertools::Itertools; -use jobserver::Acquired; use jobserver::Client; use object::elf::GNU_PROPERTY_X86_ISA_1_BASELINE; use object::elf::GNU_PROPERTY_X86_ISA_1_V2; use object::elf::GNU_PROPERTY_X86_ISA_1_V3; use object::elf::GNU_PROPERTY_X86_ISA_1_V4; -use rayon::ThreadPoolBuilder; use std::ffi::CString; -use std::fmt::Display; use std::mem::take; use std::num::NonZero; use std::num::NonZeroU32; @@ -46,158 +57,36 @@ use std::str::FromStr; use std::sync::Arc; use std::sync::atomic::AtomicI64; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum VersionMode { - /// Don't print version - None, - /// Print version and continue linking (-v) - Verbose, - /// Print version and exit immediately (--version) - ExitAfterPrint, -} - -#[derive(Debug)] -pub(crate) enum DefsymValue { - /// A numeric value (address) - Value(u64), - /// Reference to another symbol with an optional offset - SymbolWithOffset(String, i64), -} +/// ELF-specific linker arguments. Common fields (output, arch, strip, gc_sections, etc.) +/// live on `Args`. Access them via direct field access on `Args`, +/// and ELF-specific fields are accessible via `Deref`/`DerefMut`. #[derive(Debug)] pub struct ElfArgs { - pub(crate) unrecognized_options: Vec, - - pub(crate) arch: Architecture, - pub(crate) lib_search_path: Vec>, - pub(crate) inputs: Vec, - pub(crate) output: Arc, pub(crate) dynamic_linker: Option>, - pub num_threads: Option, - pub(crate) strip: Strip, - pub(crate) prepopulate_maps: bool, - pub(crate) sym_info: Option, - pub(crate) merge_sections: bool, - pub(crate) debug_fuel: Option, - pub(crate) validate_output: bool, pub(crate) version_script_path: Option, - pub(crate) debug_address: Option, - pub(crate) write_layout: bool, pub(crate) should_write_eh_frame_hdr: bool, - pub(crate) write_trace: bool, - pub(crate) wrap: Vec, pub(crate) rpath: Option, pub(crate) soname: Option, - pub(crate) files_per_group: Option, - pub(crate) exclude_libs: ExcludeLibs, - pub(crate) gc_sections: bool, - pub(crate) should_fork: bool, - pub(crate) mmap_output_file: bool, + pub(crate) enable_new_dtags: bool, pub(crate) build_id: BuildIdOption, - pub(crate) file_write_mode: Option, - pub(crate) no_undefined: bool, - pub(crate) allow_shlib_undefined: bool, pub(crate) needs_origin_handling: bool, pub(crate) needs_nodelete_handling: bool, - pub(crate) copy_relocations: CopyRelocations, - pub(crate) sysroot: Option>, - pub(crate) undefined: Vec, pub(crate) relro: bool, - pub(crate) entry: Option, - pub(crate) export_all_dynamic_symbols: bool, + pub(crate) b_symbolic: BSymbolicKind, pub(crate) export_list: Vec, pub(crate) export_list_path: Option, pub(crate) auxiliary: Vec, - pub(crate) enable_new_dtags: bool, - pub(crate) plugin_path: Option, - pub(crate) plugin_args: Vec, - - /// Symbol definitions from `--defsym` options. Each entry is (symbol_name, value_or_symbol). - pub(crate) defsym: Vec<(String, DefsymValue)>, - - /// Section start addresses from `--section-start` options. Maps section name to address. - pub(crate) section_start: HashMap, - - /// If set, GC stats will be written to the specified filename. - pub(crate) write_gc_stats: Option, - - /// If set, and we're writing GC stats, then ignore any input files that contain any of the - /// specified substrings. - pub(crate) gc_stats_ignore: Vec, - - /// If `Some`, then we'll time how long each phase takes. We'll also measure the specified - /// counters, if any. - pub(crate) time_phase_options: Option>, - - pub(crate) verbose_gc_stats: bool, - - pub(crate) save_dir: SaveDir, - pub(crate) dependency_file: Option, - pub(crate) print_allocations: Option, - pub(crate) execstack: bool, - pub(crate) verify_allocation_consistency: bool, - pub(crate) version_mode: VersionMode, - pub(crate) demangle: bool, pub(crate) got_plt_syms: bool, - pub(crate) b_symbolic: BSymbolicKind, - pub(crate) relax: bool, - pub(crate) should_write_linker_identity: bool, pub(crate) hash_style: HashStyle, - pub(crate) unresolved_symbols: UnresolvedSymbols, - pub(crate) error_unresolved_symbols: bool, - pub(crate) allow_multiple_definitions: bool, pub(crate) z_interpose: bool, pub(crate) z_isa: Option, pub(crate) z_stack_size: Option, - pub(crate) max_page_size: Option, - - pub(crate) relocation_model: RelocationModel, - pub(crate) should_output_executable: bool, - - - /// The number of actually available threads (considering jobserver) - pub(crate) available_threads: NonZeroUsize, - - pub(crate) numeric_experiments: Vec>, - + pub(crate) plugin_path: Option, + pub(crate) plugin_args: Vec, rpath_set: IndexSet, - - jobserver_client: Option, -} - -#[derive(Debug)] -pub(crate) enum Strip { - Nothing, - Debug, - All, - Retain(HashSet>), } -#[derive(Debug, Clone, Copy)] -pub enum CounterKind { - Cycles, - Instructions, - CacheMisses, - BranchMisses, - PageFaults, - PageFaultsMinor, - PageFaultsMajor, - L1dRead, - L1dMiss, -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocations { - Allowed, - Disallowed(CopyRelocationsDisabledReason), -} - -/// Represents a command-line argument that specifies the number of threads to use, -/// triggering activation of the thread pool. -pub struct ActivatedArgs { - pub args: ElfArgs, - _jobserver_tokens: Vec, -} #[derive(Debug)] pub(crate) enum BuildIdOption { @@ -214,27 +103,6 @@ pub(crate) enum HashStyle { Both, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum ExcludeLibs { - None, - All, - Some(HashSet>), -} - -impl ExcludeLibs { - pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { - match self { - ExcludeLibs::None => false, - ExcludeLibs::All => true, - ExcludeLibs::Some(libs) => { - let lib_path_str = String::from_utf8_lossy(lib_path); - let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); - - libs.contains(lib_name) - } - } - } -} impl HashStyle { pub(crate) const fn includes_gnu(self) -> bool { @@ -246,203 +114,42 @@ impl HashStyle { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum RelocationModel { - NonRelocatable, - Relocatable, -} - -#[derive(Debug, Copy, Clone)] -pub(crate) enum Experiment { - /// How much parallelism to allow when splitting string-merge sections. - MergeStringSplitParallelism = 0, - - /// Number of bytes of string-merge sections before we'll break to a new group. - MergeStringMinGroupBytes = 1, - - GroupsPerThread = 2, - - MinGroups = 3, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum FileWriteMode { - /// The existing output file, if any, will be unlinked (deleted) and a new file with the same - /// name put in its place. Any hard links to the file will not be affected. - UnlinkAndReplace, - - /// The existing output file, if any, will be edited in-place. Any hard links to the file will - /// update accordingly. If the file is locked due to currently being executed, then our write - /// will fail. - UpdateInPlace, - - /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to - /// unlinking and replacing. - UpdateInPlaceWithFallback, -} - -#[derive(Debug, Eq, PartialEq, Clone, Copy)] -pub struct Modifiers { - /// Whether shared objects should only be linked if they're referenced. - pub(crate) as_needed: bool, - - /// Whether we're currently allowed to link against shared libraries. - pub(crate) allow_shared: bool, - - /// Whether object files in archives should be linked even if they do not contain symbols that - /// are referenced. - pub(crate) whole_archive: bool, - - /// Whether archive semantics should be applied even for regular objects. - pub(crate) archive_semantics: bool, - - /// Whether the file is known to be a temporary file that will be deleted when the linker - /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is - /// stored in the layout file if written so that linker-diff knows not to error if the file - /// is missing. - pub(crate) temporary: bool, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) struct Input { - pub(crate) spec: InputSpec, - /// A directory to search first. Only present when the input came from a linker script, in - /// which case this is the directory containing the linker script. - pub(crate) search_first: Option, - pub(crate) modifiers: Modifiers, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum InputSpec { - /// Path (possibly just a filename) to the file. - File(Box), - /// Name of the library, without prefix and suffix. - Lib(Box), - /// Name of the library, including prefix and suffix. - Search(Box), -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub(crate) enum BSymbolicKind { - None, - All, - Functions, - NonWeakFunctions, - NonWeak, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum UnresolvedSymbols { - /// Report all unresolved symbols. - ReportAll, - - /// Ignore unresolved symbols in shared libraries. - IgnoreInSharedLibs, - - /// Ignore unresolved symbols in object files. - IgnoreInObjectFiles, - - /// Ignore all unresolved symbols. - IgnoreAll, -} use super::consts::*; impl Default for ElfArgs { fn default() -> Self { ElfArgs { - arch: default_target_arch(), - unrecognized_options: Vec::new(), - - lib_search_path: Vec::new(), - inputs: Vec::new(), - output: Arc::from(Path::new("a.out")), - should_output_executable: true, dynamic_linker: None, - time_phase_options: None, - num_threads: None, - strip: Strip::Nothing, - // For now, we default to --gc-sections. This is different to other linkers, but other - // than being different, there doesn't seem to be any downside to doing - // this. We don't currently do any less work if we're not GCing sections, - // but do end up writing more, so --no-gc-sections will almost always be as - // slow or slower than --gc-sections. For that reason, the latter is - // probably a good default. - gc_sections: true, - prepopulate_maps: false, - sym_info: None, - merge_sections: true, - copy_relocations: CopyRelocations::Allowed, - debug_fuel: None, - validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), - write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), - write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), - verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) - .is_ok_and(|v| v == "1"), - print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") - .ok() - .and_then(|s| s.parse().ok()) - .map(FileId::from_encoded), - relocation_model: RelocationModel::NonRelocatable, version_script_path: None, - debug_address: None, should_write_eh_frame_hdr: false, - write_gc_stats: None, - wrap: Vec::new(), - gc_stats_ignore: Vec::new(), - verbose_gc_stats: false, rpath: None, soname: None, enable_new_dtags: true, - execstack: false, - should_fork: true, - mmap_output_file: true, + build_id: BuildIdOption::None, needs_origin_handling: false, needs_nodelete_handling: false, - should_write_linker_identity: true, - file_write_mode: None, - build_id: BuildIdOption::None, - files_per_group: None, - exclude_libs: ExcludeLibs::None, - no_undefined: false, - allow_shlib_undefined: false, - version_mode: VersionMode::None, - sysroot: None, - save_dir: Default::default(), - dependency_file: None, - demangle: true, - undefined: Vec::new(), relro: true, - entry: None, b_symbolic: BSymbolicKind::None, - export_all_dynamic_symbols: false, export_list: Vec::new(), export_list_path: None, - defsym: Vec::new(), - section_start: HashMap::new(), + auxiliary: Vec::new(), got_plt_syms: false, - relax: true, hash_style: HashStyle::Both, - jobserver_client: None, - available_threads: NonZeroUsize::new(1).unwrap(), - unresolved_symbols: UnresolvedSymbols::ReportAll, - error_unresolved_symbols: true, - allow_multiple_definitions: false, z_interpose: false, - z_stack_size: None, z_isa: None, - max_page_size: None, - auxiliary: Vec::new(), - numeric_experiments: Vec::new(), - rpath_set: Default::default(), + z_stack_size: None, plugin_path: None, plugin_args: Vec::new(), + rpath_set: Default::default(), } } } // Parse the supplied input arguments, which should not include the program name. -pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { +pub(crate) fn parse I, S: AsRef, I: Iterator>( + input: F, +) -> Result> { use crate::input_data::MAX_FILES_PER_GROUP; // SAFETY: Should be called early before other descriptors are opened and @@ -461,7 +168,7 @@ pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F ); } - let mut args = ElfArgs { + let mut args = super::Args:: { files_per_group, jobserver_client, ..Default::default() @@ -507,76 +214,14 @@ pub(crate) fn parse I, S: AsRef, I: Iterator>(input: F Ok(args) } -const fn default_target_arch() -> Architecture { - // We default to targeting the architecture that we're running on. We don't support running on - // architectures that we can't target. - #[cfg(target_arch = "x86_64")] - { - Architecture::X86_64 - } - #[cfg(target_arch = "aarch64")] - { - Architecture::AArch64 - } - #[cfg(target_arch = "riscv64")] - { - Architecture::RISCV64 - } - #[cfg(target_arch = "loongarch64")] - { - Architecture::LoongArch64 - } -} - -pub(crate) fn read_args_from_file(path: &Path) -> Result> { - let contents = std::fs::read_to_string(path) - .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; - arguments_from_string(&contents) -} - -impl ElfArgs { - pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { +impl super::Args { + pub fn parse_elf I, S: AsRef, I: Iterator>( + input: F, + ) -> Result> { timing_phase!("Parse args"); parse(input) } - /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when - /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the - /// caller should take a different branch depending on whether the value is still positive. You - /// can then do a binary search. - pub(crate) fn use_debug_fuel(&self) -> i64 { - let Some(fuel) = self.debug_fuel.as_ref() else { - return i64::MAX; - }; - fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 - } - - /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls - /// `last_cb`. - #[allow(unused)] - pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { - match self.use_debug_fuel() { - 1.. => true, - 0 => { - last_cb(); - true - } - _ => false, - } - } - - pub(crate) fn trace_span_for_file( - &self, - file_id: FileId, - ) -> Option { - let should_trace = self.print_allocations == Some(file_id); - should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) - } - - pub fn should_fork(&self) -> bool { - self.should_fork - } - pub(crate) fn loadable_segment_alignment(&self) -> Alignment { if let Some(max_page_size) = self.max_page_size { return max_page_size; @@ -600,53 +245,6 @@ impl ElfArgs { }); } - /// Sets up the thread pool, using the explicit number of threads if specified, - /// or falling back to the jobserver protocol if available. - /// - /// - pub fn activate_thread_pool(mut self) -> Result { - timing_phase!("Activate thread pool"); - - let mut tokens = Vec::new(); - self.available_threads = self.num_threads.unwrap_or_else(|| { - if let Some(client) = &self.jobserver_client { - while let Ok(Some(acquired)) = client.try_acquire() { - tokens.push(acquired); - } - tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); - // Our parent "holds" one jobserver token, add it. - NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() - } else { - std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) - } - }); - - // The pool might be already initialized, suppress the error intentionally. - let _ = ThreadPoolBuilder::new() - .num_threads(self.available_threads.get()) - .build_global(); - - Ok(ActivatedArgs { - args: self, - _jobserver_tokens: tokens, - }) - } - - pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { - self.numeric_experiments - .get(exp as usize) - .copied() - .flatten() - .unwrap_or(default) - } - - pub(crate) fn strip_all(&self) -> bool { - matches!(self.strip, Strip::All) - } - - pub(crate) fn strip_debug(&self) -> bool { - matches!(self.strip, Strip::All | Strip::Debug) - } } fn parse_number(s: &str) -> Result { @@ -665,669 +263,6 @@ fn parse_defsym_expression(s: &str) -> DefsymValue { } } -impl Default for Modifiers { - fn default() -> Self { - Self { - as_needed: false, - allow_shared: true, - whole_archive: false, - archive_semantics: false, - temporary: false, - } - } -} - -/// Parses arguments from a string, handling quoting, escapes etc. -/// All arguments must be surrounded by a white space. -fn arguments_from_string(input: &str) -> Result> { - const QUOTES: [char; 2] = ['\'', '"']; - - let mut out = Vec::new(); - let mut chars = input.chars(); - let mut heap = None; - let mut quote = None; - let mut expect_whitespace = false; - - loop { - let Some(mut ch) = chars.next() else { - if let Some(quote) = quote.take() { - bail!("Missing closing '{quote}'"); - } - if let Some(arg) = heap.take() { - out.push(arg); - } - break; - }; - - ensure!( - !expect_whitespace || ch.is_whitespace(), - "Expected white space after quoted argument" - ); - expect_whitespace = false; - - if QUOTES.contains(&ch) { - if let Some(qchr) = quote { - if qchr == ch { - // close the argument - if let Some(arg) = heap.take() { - out.push(arg); - } - quote = None; - expect_whitespace = true; - } else { - // accept the other quoting character as normal char - heap.get_or_insert(String::new()).push(ch); - } - } else { - // beginning of a new argument - ensure!(heap.is_none(), "Missing opening quote '{ch}'"); - quote = Some(ch); - } - } else if ch.is_whitespace() { - if quote.is_none() { - if let Some(arg) = heap.take() { - out.push(arg); - } - } else { - heap.get_or_insert(String::new()).push(ch); - } - } else { - if ch == '\\' { - ch = chars.next().context("Invalid escape")?; - } - heap.get_or_insert(String::new()).push(ch); - } - } - - Ok(out) -} - -fn warn_unsupported(opt: &str) -> Result { - match std::env::var(WILD_UNSUPPORTED_ENV) - .unwrap_or_default() - .as_str() - { - "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), - "ignore" => {} - "error" => bail!("{opt} is not yet supported"), - other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), - } - Ok(()) -} - -pub(crate) struct ArgumentParser { - options: HashMap<&'static str, OptionHandler>, - short_options: HashMap<&'static str, OptionHandler>, - prefix_options: HashMap<&'static str, PrefixOptionHandler>, - case_insensitive: bool, -} - -struct OptionHandler { - help_text: &'static str, - handler: OptionHandlerFn, - short_names: Vec<&'static str>, -} - -impl Clone for OptionHandler { - fn clone(&self) -> Self { - Self { - help_text: self.help_text, - handler: self.handler, - short_names: self.short_names.clone(), - } - } -} - -struct PrefixOptionHandler { - help_text: &'static str, - handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>, - sub_options: HashMap<&'static str, SubOption>, -} - -#[allow(clippy::enum_variant_names)] -enum OptionHandlerFn { - NoParam(fn(&mut ArgsType, &mut Vec) -> Result<()>), - WithParam(fn(&mut ArgsType, &mut Vec, &str) -> Result<()>), - OptionalParam(fn(&mut ArgsType, &mut Vec, Option<&str>) -> Result<()>), -} - -impl Clone for OptionHandlerFn { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for OptionHandlerFn {} - -impl OptionHandlerFn { - fn help_suffix_long(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => "=", - OptionHandlerFn::OptionalParam(_) => "[=]", - } - } - - fn help_suffix_short(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => " ", - OptionHandlerFn::OptionalParam(_) => " []", - } - } -} - -pub(crate) struct OptionDeclaration<'a, ArgsType, T> { - parser: &'a mut ArgumentParser, - long_names: Vec<&'static str>, - short_names: Vec<&'static str>, - prefixes: Vec<&'static str>, - sub_options: HashMap<&'static str, SubOption>, - help_text: &'static str, - _phantom: std::marker::PhantomData, -} - -pub struct NoParam; -pub struct WithParam; -pub struct WithOptionalParam; - -enum SubOptionHandler { - /// Handler without value parameter (exact match) - NoValue(fn(&mut ArgsType, &mut Vec) -> Result<()>), - /// Handler with value parameter (prefix match) - WithValue(fn(&mut ArgsType, &mut Vec, &str) -> Result<()>), -} - -impl Clone for SubOptionHandler { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOptionHandler {} - -struct SubOption { - help: &'static str, - handler: SubOptionHandler, -} - -impl Clone for SubOption { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOption {} - -impl SubOption { - fn with_value(&self) -> bool { - matches!(self.handler, SubOptionHandler::WithValue(_)) - } -} - -impl Default for ArgumentParser { - fn default() -> Self { - Self::new() - } -} - -impl ArgumentParser { - #[must_use] - pub fn new() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: false, - } - } - - #[must_use] - pub fn new_case_insensitive() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: true, - } - } - - pub fn declare(&mut self) -> OptionDeclaration<'_, ArgsType, NoParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, ArgsType, WithParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_optional_param( - &mut self, - ) -> OptionDeclaration<'_, ArgsType, WithOptionalParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { - if self.case_insensitive { - if let Some(handler) = self.options.get(option_name) { - return Some(handler); - } - for (key, handler) in &self.options { - if key.eq_ignore_ascii_case(option_name) { - return Some(handler); - } - } - None - } else { - self.options.get(option_name) - } - } - - pub(crate) fn handle_argument, I: Iterator>( - &self, - args: &mut ArgsType, - modifier_stack: &mut Vec, - arg: &str, - input: &mut I, - ) -> Result<()> - where - ArgsType: super::PrivateArgs, - { - // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. - // Handle `@file`option (recursively) - merging in the options contained in the file - if let Some(path) = arg.strip_prefix('@') { - let file_args = read_args_from_file(Path::new(path))?; - let mut file_arg_iter = file_args.iter(); - while let Some(file_arg) = file_arg_iter.next() { - self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; - } - return Ok(()); - } - - if let Some(stripped) = ArgsType::strip_option(arg) { - // Check for option with separator syntax - if let Some(eq_pos) = ArgsType::find_separator(stripped) { - let option_name = &stripped[..eq_pos]; - let value = &stripped[eq_pos + 1..]; - - if let Some(handler) = self.get_option_handler(option_name) { - match &handler.handler { - OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, - OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, - OptionHandlerFn::NoParam(_) => return Ok(()), - } - return Ok(()); - } - } else { - if stripped == "build-id" - && let Some(handler) = self.get_option_handler(stripped) - && let OptionHandlerFn::WithParam(f) = &handler.handler - { - f(args, modifier_stack, "fast")?; - return Ok(()); - } - - if let Some(handler) = self.get_option_handler(stripped) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - } - - if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { - let option_name = &arg[1..]; - if let Some(handler) = self.short_options.get(option_name) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - - // Prefix options. These should be handled after processing long and short options, - // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. - for (prefix, handler) in &self.prefix_options { - if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { - let value = if rest.is_empty() { - let next_arg = input - .next() - .context(format!("Missing argument to -{prefix}"))?; - next_arg.as_ref().to_owned() - } else { - rest.to_owned() - }; - - if let Some((key, param_value)) = value.split_once('=') { - // Value has '=', look up key with trailing '=' - if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { - match sub.handler { - SubOptionHandler::NoValue(_) => { - (handler.handler)(args, modifier_stack, &value)?; - } - SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } else { - // No '=' in value, look up exact match - if let Some(sub) = handler.sub_options.get(value.as_str()) { - match sub.handler { - SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, - SubOptionHandler::WithValue(_) => { - bail!("Option -{prefix} {value} requires a value"); - } - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } - return Ok(()); - } - } - - if ArgsType::has_option_prefix(arg) { - if let Some(stripped) = ArgsType::strip_option(arg) - && IGNORED_FLAGS.contains(&stripped) - { - warn_unsupported(arg)?; - return Ok(()); - } - - args.unrecognized_options_mut().push(arg.to_owned()); - return Ok(()); - } - - args.save_dir_mut().handle_file(arg); - args.inputs_mut().push(Input { - spec: InputSpec::File(Box::from(Path::new(arg))), - search_first: None, - modifiers: *modifier_stack.last().unwrap(), - }); - - Ok(()) - } - - #[must_use] - fn generate_help(&self) -> String { - let mut help = String::new(); - help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); - - let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); - prefix_options.sort_by_key(|(prefix, _)| *prefix); - - // TODO: This is ad-hoc - help.push_str(&format!( - " {:<31} Read options from a file\n", - format!("@"), - )); - - let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); - let mut processed_short_options: HashSet<&str> = HashSet::new(); - - // Collect all long options and their associated short options - for (long_name, handler) in &self.options { - if !handler.help_text.is_empty() { - let long_suffix = handler.handler.help_suffix_long(); - let mut option_names = vec![format!("--{long_name}{long_suffix}")]; - - // Add associated short options - let short_suffix = handler.handler.help_suffix_short(); - for short_char in &handler.short_names { - option_names.push(format!("-{short_char}{short_suffix}")); - } - - help_to_options - .entry(handler.help_text) - .or_default() - .extend(option_names); - } - - // Mark short options of help-less handlers as processed - for short_name in &handler.short_names { - processed_short_options.insert(short_name); - } - } - - for (prefix, handler) in prefix_options { - if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { - help.push_str(&format!( - " -{:<30} {}\n", - format!("{prefix} "), - handler.help_text - )); - - // Add sub-options if they exist - let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); - sub_options.sort_by_key(|(name, _)| *name); - - for (sub_name, sub) in sub_options { - let display_name = if sub.with_value() && sub_name.ends_with('=') { - // sub_name ends with '=' (e.g., "max-page-size="), so add - format!("{sub_name}") - } else { - sub_name.to_string() - }; - help.push_str(&format!( - " -{prefix} {display_name:<30} {sub_help}\n", - sub_help = sub.help - )); - } - } - } - - // Add short-only options - for (short_char, handler) in &self.short_options { - if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { - let short_suffix = handler.handler.help_suffix_short(); - help_to_options - .entry(handler.help_text) - .or_default() - .push(format!("-{short_char}{short_suffix}")); - } - } - - let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); - sorted_help_groups.sort_by_key(|(_, option_names)| { - option_names.iter().min().unwrap_or(&String::new()).clone() - }); - - for (help_text, mut option_names) in sorted_help_groups { - option_names.sort_by(|a, b| { - let a_is_short = a.len() == 2 && a.starts_with('-'); - let b_is_short = b.len() == 2 && b.starts_with('-'); - match (a_is_short, b_is_short) { - (true, false) => std::cmp::Ordering::Less, // short options first - (false, true) => std::cmp::Ordering::Greater, // long options after - _ => a.cmp(b), // same type, alphabetical - } - }); - - let option_names_str = option_names.join(", "); - help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); - } - - help - } -} - -impl<'a, ArgsType, T> OptionDeclaration<'a, ArgsType, T> { - #[must_use] - pub fn long(mut self, name: &'static str) -> Self { - self.long_names.push(name); - self - } - - #[must_use] - pub fn short(mut self, option: &'static str) -> Self { - self.short_names.push(option); - self - } - - #[must_use] - pub fn help(mut self, text: &'static str) -> Self { - self.help_text = text; - self - } - - pub fn prefix(mut self, prefix: &'static str) -> Self { - self.prefixes.push(prefix); - self - } - - #[must_use] - pub fn sub_option( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut ArgsType, &mut Vec) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::NoValue(handler), - }, - ); - self - } - - #[must_use] - pub fn sub_option_with_value( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::WithValue(handler), - }, - ); - self - } -} - -impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, NoParam> { - pub fn execute(self, handler: fn(&mut ArgsType, &mut Vec) -> Result<()>) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::NoParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} - -impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, WithParam> { - pub fn execute(self, handler: fn(&mut ArgsType, &mut Vec, &str) -> Result<()>) { - let mut short_names = self.short_names.clone(); - short_names.extend_from_slice(&self.prefixes); - - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::WithParam(handler), - short_names, - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - - for prefix in self.prefixes { - let prefix_handler = PrefixOptionHandler { - help_text: self.help_text, - sub_options: self.sub_options.clone(), - handler, - }; - - self.parser.prefix_options.insert(prefix, prefix_handler); - } - } -} - -impl<'a, ArgsType> OptionDeclaration<'a, ArgsType, WithOptionalParam> { - pub fn execute( - self, - handler: fn(&mut ArgsType, &mut Vec, Option<&str>) -> Result<()>, - ) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::OptionalParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} fn setup_argument_parser() -> ArgumentParser { let mut parser = ArgumentParser::new(); @@ -1336,7 +271,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .prefix("L") .help("Add directory to library search path") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { let handle_sysroot = |path| { args.sysroot .as_ref() @@ -1381,7 +316,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|args: &mut ElfArgs, modifier_stack, value| { + .execute(|args: &mut super::Args, modifier_stack, value| { let spec = if let Some(stripped) = value.strip_prefix(':') { InputSpec::Search(Box::from(stripped)) } else { @@ -1399,7 +334,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .prefix("u") .help("Force resolution of the symbol") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.undefined.push(value.to_owned()); Ok(()) }); @@ -1443,7 +378,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|_args: &mut ElfArgs, _modifier_stack, value| { + .execute(|_args: &mut super::Args, _modifier_stack, value| { bail!("-m {value} is not yet supported"); }); @@ -1577,7 +512,7 @@ fn setup_argument_parser() -> ArgumentParser { Ok(()) }, ) - .execute(|_args: &mut ElfArgs, _modifier_stack, value| { + .execute(|_args: &mut super::Args, _modifier_stack, value| { warn_unsupported(&("-z ".to_owned() + value))?; Ok(()) }); @@ -1586,7 +521,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .prefix("R") .help("Add runtime library search path") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { if Path::new(value).is_file() { args.unrecognized_options .push(format!("-R,{value}(filename)")); @@ -1599,7 +534,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare_with_param() .prefix("O") - .execute(|_args: &mut ElfArgs, _modifier_stack, _value| + .execute(|_args: &mut super::Args, _modifier_stack, _value| // We don't use opt-level for now. Ok(())); @@ -1608,7 +543,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("static") .long("Bstatic") .help("Disallow linking of shared libraries") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().allow_shared = false; Ok(()) }); @@ -1617,7 +552,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bdynamic") .help("Allow linking of shared libraries") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().allow_shared = true; Ok(()) }); @@ -1627,7 +562,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("output") .short("o") .help("Set the output filename") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.output = Arc::from(Path::new(value)); Ok(()) }); @@ -1637,7 +572,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("strip-all") .short("s") .help("Strip all symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.strip = Strip::All; Ok(()) }); @@ -1647,7 +582,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("strip-debug") .short("S") .help("Strip debug symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.strip = Strip::Debug; Ok(()) }); @@ -1656,7 +591,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("gc-sections") .help("Enable removal of unused sections") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.gc_sections = true; Ok(()) }); @@ -1665,7 +600,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-gc-sections") .help("Disable removal of unused sections") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.gc_sections = false; Ok(()) }); @@ -1675,7 +610,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("shared") .long("Bshareable") .help("Create a shared library") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.should_output_executable = false; Ok(()) }); @@ -1685,7 +620,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("pie") .long("pic-executable") .help("Create a position-independent executable") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.relocation_model = RelocationModel::Relocatable; args.should_output_executable = true; Ok(()) @@ -1695,7 +630,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-pie") .help("Do not create a position-dependent executable (default)") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.relocation_model = RelocationModel::NonRelocatable; args.should_output_executable = true; Ok(()) @@ -1705,7 +640,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("pack-dyn-relocs") .help("Specify dynamic relocation packing format") - .execute(|_args: &mut ElfArgs, _modifier_stack, value| { + .execute(|_args: &mut super::Args, _modifier_stack, value| { if value != "none" { warn_unsupported(&format!("--pack-dyn-relocs={value}"))?; } @@ -1716,7 +651,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("help") .help("Show this help message") - .execute(|_args: &mut ElfArgs, _modifier_stack| { + .execute(|_args: &mut super::Args, _modifier_stack| { let parser = setup_argument_parser(); println!("{}", parser.generate_help()); @@ -1731,7 +666,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("version") .help("Show version information and exit") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.version_mode = VersionMode::ExitAfterPrint; Ok(()) }); @@ -1740,7 +675,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .short("v") .help("Print version and continue linking") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.version_mode = VersionMode::Verbose; Ok(()) }); @@ -1749,7 +684,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("demangle") .help("Enable symbol demangling") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.demangle = true; Ok(()) }); @@ -1758,7 +693,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-demangle") .help("Disable symbol demangling") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.demangle = false; Ok(()) }); @@ -1767,7 +702,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("time") .help("Show timing information") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { match value { Some(v) => args.time_phase_options = Some(parse_time_phase_options(v)?), None => args.time_phase_options = Some(Vec::new()), @@ -1779,7 +714,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dynamic-linker") .help("Set dynamic linker path") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.dynamic_linker = Some(Box::from(Path::new(value))); Ok(()) }); @@ -1788,7 +723,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-dynamic-linker") .help("Omit the load-time dynamic linker request") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.dynamic_linker = None; Ok(()) }); @@ -1797,7 +732,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("mmap-output-file") .help("Write output file using mmap (default)") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.mmap_output_file = true; Ok(()) }); @@ -1806,7 +741,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-mmap-output-file") .help("Write output file without mmap") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.mmap_output_file = false; Ok(()) }); @@ -1816,7 +751,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("entry") .short("e") .help("Set the entry point") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.entry = Some(value.to_owned()); Ok(()) }); @@ -1825,7 +760,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("threads") .help("Use multiple threads for linking") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { match value { Some(v) => { args.num_threads = Some(NonZeroUsize::try_from(v.parse::()?)?); @@ -1841,7 +776,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-threads") .help("Use a single thread") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.num_threads = Some(NonZeroUsize::new(1).unwrap()); Ok(()) }); @@ -1850,7 +785,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("wild-experiments") .help("List of numbers. Used to tweak internal parameters. '_' keeps default value.") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.numeric_experiments = value .split(',') .map(|p| { @@ -1868,7 +803,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("as-needed") .help("Set DT_NEEDED if used") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().as_needed = true; Ok(()) }); @@ -1877,7 +812,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-as-needed") .help("Always set DT_NEEDED") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().as_needed = false; Ok(()) }); @@ -1886,7 +821,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("whole-archive") .help("Include all objects from archives") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().whole_archive = true; Ok(()) }); @@ -1895,7 +830,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-whole-archive") .help("Disable --whole-archive") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().whole_archive = false; Ok(()) }); @@ -1904,7 +839,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("push-state") .help("Save current linker flags") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.push(*modifier_stack.last().unwrap()); Ok(()) }); @@ -1913,7 +848,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("pop-state") .help("Restore previous linker flags") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.pop(); if modifier_stack.is_empty() { bail!("Mismatched --pop-state"); @@ -1925,7 +860,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("eh-frame-hdr") .help("Create .eh_frame_hdr section") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.should_write_eh_frame_hdr = true; Ok(()) }); @@ -1934,7 +869,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-eh-frame-hdr") .help("Don't create .eh_frame_hdr section") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.should_write_eh_frame_hdr = false; Ok(()) }); @@ -1944,7 +879,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("export-dynamic") .short("E") .help("Export all dynamic symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.export_all_dynamic_symbols = true; Ok(()) }); @@ -1953,7 +888,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-export-dynamic") .help("Do not export dynamic symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.export_all_dynamic_symbols = false; Ok(()) }); @@ -1963,7 +898,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("soname") .prefix("h") .help("Set shared object name") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.soname = Some(value.to_owned()); Ok(()) }); @@ -1972,7 +907,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("rpath") .help("Add directory to runtime library search path") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.rpath_set.insert(value.to_string()); Ok(()) }); @@ -1981,7 +916,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-string-merge") .help("Disable section merging") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.merge_sections = false; Ok(()) }); @@ -1990,7 +925,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-undefined") .help("Do not allow unresolved symbols in object files") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.no_undefined = true; Ok(()) }); @@ -1999,7 +934,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("allow-multiple-definition") .help("Allow multiple definitions of symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.allow_multiple_definitions = true; Ok(()) }); @@ -2008,7 +943,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("relax") .help("Enable target-specific optimization (instruction relaxation)") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.relax = true; Ok(()) }); @@ -2017,7 +952,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-relax") .help("Disable relaxation") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.relax = false; Ok(()) }); @@ -2025,7 +960,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("validate-output") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.validate_output = true; Ok(()) }); @@ -2033,7 +968,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("write-layout") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.write_layout = true; Ok(()) }); @@ -2041,7 +976,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare() .long("write-trace") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.write_trace = true; Ok(()) }); @@ -2050,7 +985,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("got-plt-syms") .help("Write symbol table entries that point to the GOT/PLT entry for symbols") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.got_plt_syms = true; Ok(()) }); @@ -2059,7 +994,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic") .help("Bind global references locally") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.b_symbolic = BSymbolicKind::All; Ok(()) }); @@ -2068,7 +1003,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-functions") .help("Bind global function references locally") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.b_symbolic = BSymbolicKind::Functions; Ok(()) }); @@ -2077,7 +1012,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-non-weak-functions") .help("Bind non-weak global function references locally") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.b_symbolic = BSymbolicKind::NonWeakFunctions; Ok(()) }); @@ -2086,7 +1021,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bsymbolic-non-weak") .help("Bind non-weak global references locally") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.b_symbolic = BSymbolicKind::NonWeak; Ok(()) }); @@ -2095,7 +1030,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("Bno-symbolic") .help("Do not bind global symbol references locally") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.b_symbolic = BSymbolicKind::None; Ok(()) }); @@ -2104,7 +1039,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("thread-count") .help("Set the number of threads to use") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.num_threads = Some(NonZeroUsize::try_from(value.parse::()?)?); Ok(()) }); @@ -2113,7 +1048,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("exclude-libs") .help("Exclude libraries") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { for lib in value.split([',', ':']) { if lib.is_empty() { continue; @@ -2144,7 +1079,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("version-script") .help("Use version script") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.save_dir.handle_file(value); args.version_script_path = Some(PathBuf::from(value)); Ok(()) @@ -2155,7 +1090,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("script") .prefix("T") .help("Use linker script") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.save_dir.handle_file(value); args.add_script(value); Ok(()) @@ -2165,7 +1100,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("export-dynamic-symbol") .help("Export dynamic symbol") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.export_list.push(value.to_owned()); Ok(()) }); @@ -2174,7 +1109,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("export-dynamic-symbol-list") .help("Export dynamic symbol list") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.export_list_path = Some(PathBuf::from(value)); Ok(()) }); @@ -2183,7 +1118,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dynamic-list") .help("Read the dynamic symbol list from a file") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.b_symbolic = BSymbolicKind::All; args.export_list_path = Some(PathBuf::from(value)); Ok(()) @@ -2193,7 +1128,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("write-gc-stats") .help("Write GC statistics") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.write_gc_stats = Some(PathBuf::from(value)); Ok(()) }); @@ -2202,7 +1137,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("gc-stats-ignore") .help("Ignore files in GC stats") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.gc_stats_ignore.push(value.to_owned()); Ok(()) }); @@ -2211,7 +1146,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-identity-comment") .help("Don't write the linker name and version in .comment") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.should_write_linker_identity = false; Ok(()) }); @@ -2220,7 +1155,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("debug-address") .help("Set debug address") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.debug_address = Some(parse_number(value).context("Invalid --debug-address")?); Ok(()) }); @@ -2228,7 +1163,7 @@ fn setup_argument_parser() -> ArgumentParser { parser .declare_with_param() .long("debug-fuel") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.debug_fuel = Some(AtomicI64::new(value.parse()?)); args.num_threads = Some(NonZeroUsize::new(1).unwrap()); Ok(()) @@ -2238,7 +1173,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("unresolved-symbols") .help("Specify how to handle unresolved symbols") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.unresolved_symbols = match value { "report-all" => UnresolvedSymbols::ReportAll, "ignore-in-shared-libs" => UnresolvedSymbols::IgnoreInSharedLibs, @@ -2253,7 +1188,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("undefined") .help("Force resolution of the symbol") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.undefined.push(value.to_owned()); Ok(()) }); @@ -2262,7 +1197,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("wrap") .help("Use a wrapper function") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.wrap.push(value.to_owned()); Ok(()) }); @@ -2271,7 +1206,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("defsym") .help("Define a symbol alias: --defsym=symbol=value") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { let parts: Vec<&str> = value.splitn(2, '=').collect(); if parts.len() != 2 { bail!("Invalid --defsym format. Expected: --defsym=symbol=value"); @@ -2289,7 +1224,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("section-start") .help("Set start address for a section: --section-start=.section=address") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { let parts: Vec<&str> = value.splitn(2, '=').collect(); if parts.len() != 2 { bail!("Invalid --section-start format. Expected: --section-start=.section=address"); @@ -2311,7 +1246,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("hash-style") .help("Set hash style") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.hash_style = match value { "gnu" => HashStyle::Gnu, "sysv" => HashStyle::Sysv, @@ -2325,7 +1260,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("enable-new-dtags") .help("Use DT_RUNPATH and DT_FLAGS/DT_FLAGS_1 (default)") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.enable_new_dtags = true; Ok(()) }); @@ -2334,7 +1269,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("disable-new-dtags") .help("Use DT_RPATH and individual dynamic entries instead of DT_FLAGS") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.enable_new_dtags = false; Ok(()) }); @@ -2346,7 +1281,7 @@ fn setup_argument_parser() -> ArgumentParser { "Filter symtab to contain only symbols listed in the supplied file. \ One symbol per line.", ) - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { // The performance this flag is not especially optimised. For one, we copy each string // to the heap. We also do two lookups in the hashset for each symbol. This is a pretty // obscure flag that we don't expect to be used much, so at this stage, it doesn't seem @@ -2372,7 +1307,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("build-id") .help("Generate build ID") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.build_id = match value { "none" => BuildIdOption::None, "fast" | "md5" | "sha1" => BuildIdOption::Fast, @@ -2394,7 +1329,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("icf") .help("Enable identical code folding (merge duplicate functions)") - .execute(|_args: &mut ElfArgs, _modifier_stack, value| { + .execute(|_args: &mut super::Args, _modifier_stack, value| { match value { "none" => {} other => warn_unsupported(&format!("--icf={other}"))?, @@ -2406,7 +1341,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("sysroot") .help("Set system root") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.save_dir.handle_file(value); let sysroot = std::fs::canonicalize(value).unwrap_or_else(|_| PathBuf::from(value)); args.sysroot = Some(Box::from(sysroot.as_path())); @@ -2423,7 +1358,7 @@ fn setup_argument_parser() -> ArgumentParser { .long("auxiliary") .short("f") .help("Set DT_AUXILIARY to a given value") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.auxiliary.push(value.to_owned()); Ok(()) }); @@ -2432,7 +1367,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("plugin-opt") .help("Pass options to the plugin") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.plugin_args .push(CString::new(value).context("Invalid --plugin-opt argument")?); Ok(()) @@ -2442,7 +1377,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("dependency-file") .help("Write dependency rules") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.dependency_file = Some(PathBuf::from(value)); Ok(()) }); @@ -2451,7 +1386,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("plugin") .help("Load plugin") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.plugin_path = Some(value.to_owned()); Ok(()) }); @@ -2460,7 +1395,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("rpath-link") .help("Add runtime library search path") - .execute(|_args: &mut ElfArgs, _modifier_stack, _value| { + .execute(|_args: &mut super::Args, _modifier_stack, _value| { // TODO Ok(()) }); @@ -2469,7 +1404,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare_with_param() .long("sym-info") .help("Show symbol information. Accepts symbol name or ID.") - .execute(|args: &mut ElfArgs, _modifier_stack, value| { + .execute(|args: &mut super::Args, _modifier_stack, value| { args.sym_info = Some(value.to_owned()); Ok(()) }); @@ -2478,7 +1413,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("start-lib") .help("Start library group") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().archive_semantics = true; Ok(()) }); @@ -2487,7 +1422,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("end-lib") .help("End library group") - .execute(|_args: &mut ElfArgs, modifier_stack| { + .execute(|_args: &mut super::Args, modifier_stack| { modifier_stack.last_mut().unwrap().archive_semantics = false; Ok(()) }); @@ -2496,7 +1431,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-fork") .help("Do not fork while linking") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.should_fork = false; Ok(()) }); @@ -2505,7 +1440,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("update-in-place") .help("Update file in place") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.file_write_mode = Some(FileWriteMode::UpdateInPlace); Ok(()) }); @@ -2514,7 +1449,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-update-in-place") .help("Delete and recreate the file") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.file_write_mode = Some(FileWriteMode::UnlinkAndReplace); Ok(()) }); @@ -2523,7 +1458,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("EB") .help("Big-endian (not supported)") - .execute(|_args: &mut ElfArgs, _modifier_stack| { + .execute(|_args: &mut super::Args, _modifier_stack| { bail!("Big-endian target is not supported"); }); @@ -2531,7 +1466,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("prepopulate-maps") .help("Prepopulate maps") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.prepopulate_maps = true; Ok(()) }); @@ -2540,7 +1475,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("verbose-gc-stats") .help("Show GC statistics") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.verbose_gc_stats = true; Ok(()) }); @@ -2549,7 +1484,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("allow-shlib-undefined") .help("Allow undefined symbol references in shared libraries") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.allow_shlib_undefined = true; Ok(()) }); @@ -2558,7 +1493,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("no-allow-shlib-undefined") .help("Disallow undefined symbol references in shared libraries") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.allow_shlib_undefined = false; Ok(()) }); @@ -2567,7 +1502,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("error-unresolved-symbols") .help("Treat unresolved symbols as errors") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.error_unresolved_symbols = true; Ok(()) }); @@ -2576,7 +1511,7 @@ fn setup_argument_parser() -> ArgumentParser { .declare() .long("warn-unresolved-symbols") .help("Treat unresolved symbols as warnings") - .execute(|args: &mut ElfArgs, _modifier_stack| { + .execute(|args: &mut super::Args, _modifier_stack| { args.error_unresolved_symbols = false; Ok(()) }); @@ -2618,79 +1553,12 @@ impl FromStr for CounterKind { } } -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocationsDisabledReason { - Flag, - SharedObject, -} - -impl Display for CopyRelocationsDisabledReason { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // Reason should make sense after the word "because". - let reason = match self { - CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", - CopyRelocationsDisabledReason::SharedObject => "output is a shared object", - }; - - Display::fmt(&reason, f) - } -} - -impl super::PrivateArgs for ElfArgs { - fn new_default() -> Self { - Self::default() - } - - fn save_dir_mut(&mut self) -> &mut crate::save_dir::SaveDir { - &mut self.save_dir - } - - fn inputs_mut(&mut self) -> &mut Vec { - &mut self.inputs - } - - fn unrecognized_options_mut(&mut self) -> &mut Vec { - &mut self.unrecognized_options - } - - fn files_per_group_mut(&mut self) -> &mut Option { - &mut self.files_per_group - } - - fn jobserver_client_mut(&mut self) -> &mut Option { - &mut self.jobserver_client - } - - fn write_layout_mut(&mut self) -> &mut bool { - &mut self.write_layout - } - - fn write_trace_mut(&mut self) -> &mut bool { - &mut self.write_trace - } - - fn setup_argument_parser() -> ArgumentParser { - setup_argument_parser() - } - - fn has_option_prefix(arg: &str) -> bool { - arg.starts_with('-') - } - - fn strip_option<'a>(arg: &'a str) -> Option<&'a str> { - arg.strip_prefix("--").or(arg.strip_prefix('-')) - } - - fn find_separator(stripped: &str) -> Option { - stripped.find('=') - } -} #[cfg(test)] mod tests { use super::SILENTLY_IGNORED_FLAGS; use super::VersionMode; - use crate::args::ElfArgs; + use crate::args::linux::ElfArgs; use crate::args::InputSpec; use itertools::Itertools; use std::fs::File; @@ -2835,7 +1703,7 @@ mod tests { assert!(c.iter().any(|p| p.as_ref() == Path::new(v))); } - fn input1_assertions(args: &ElfArgs) { + fn input1_assertions(args: &super::super::Args) { assert_eq!( args.inputs .iter() @@ -2874,7 +1742,7 @@ mod tests { ); } - fn inline_and_file_options_assertions(args: &ElfArgs) { + fn inline_and_file_options_assertions(args: &super::super::Args) { assert_contains(&args.lib_search_path, "/lib"); } @@ -2955,7 +1823,7 @@ mod tests { #[test] fn test_arguments_from_string() { - use super::arguments_from_string; + use crate::args::arguments_from_string; assert!(arguments_from_string("").unwrap().is_empty()); assert!(arguments_from_string("''").unwrap().is_empty()); @@ -2987,7 +1855,10 @@ mod tests { arguments_from_string("'foo \" bar'").unwrap(), ["foo \" bar"] ); + #[cfg(not(target_os = "windows"))] assert!(arguments_from_string("foo\\").is_err()); + #[cfg(target_os = "windows")] + assert_eq!(arguments_from_string("foo\\").unwrap(), ["foo\\"]); assert!(arguments_from_string("'foo").is_err()); assert!(arguments_from_string("foo\"").is_err()); } diff --git a/libwild/src/args/mod.rs b/libwild/src/args/mod.rs index b8b2a696e..51ff02e6d 100644 --- a/libwild/src/args/mod.rs +++ b/libwild/src/args/mod.rs @@ -12,65 +12,814 @@ //! Basically, we need to be able to parse arguments in the same way as the other linkers on the //! platform that we're targeting. -mod consts; +pub mod consts; pub mod linux; pub mod windows; -pub use consts::*; - -// Re-export everything from linux.rs for backward compatibility. -// The rest of the crate uses `crate::args::Args`, `crate::args::FileWriteMode`, etc. -// and this re-export ensures those paths continue to work. -pub use linux::*; - -// Re-export types that sub-modules (windows.rs, parser.rs) need via `super::*`. -pub(crate) use crate::arch::Architecture; -pub(crate) use crate::output_kind::OutputKind; -pub(crate) use crate::save_dir::SaveDir; +use consts::*; +use crate::alignment::Alignment; +use crate::arch::Architecture; use crate::bail; -use crate::save_dir; +use crate::error::Context as _; use crate::error::Result; +use crate::input_data::FileId; +use crate::save_dir::SaveDir; use crate::target_os::Os; +use hashbrown::HashMap; +use hashbrown::HashSet; use jobserver::Client; +use std::fmt::Display; +use std::num::NonZeroUsize; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::atomic::AtomicI64; use target_lexicon::Triple; -#[allow(dead_code)] -/// Trait providing mutable access to shared fields during argument parsing. -/// -/// This trait is used by the generic `ArgumentParser` to access fields -/// that both Linux and Windows argument structs share. It also defines platform-specific -/// parsing helpers (option prefix detection, separator detection). -pub(crate) trait PrivateArgs { - fn new_default() -> Self; - fn save_dir_mut(&mut self) -> &mut save_dir::SaveDir; - fn inputs_mut(&mut self) -> &mut Vec; - fn unrecognized_options_mut(&mut self) -> &mut Vec; - fn files_per_group_mut(&mut self) -> &mut Option; - fn jobserver_client_mut(&mut self) -> &mut Option; - fn write_layout_mut(&mut self) -> &mut bool; - fn write_trace_mut(&mut self) -> &mut bool; - fn setup_argument_parser() -> linux::ArgumentParser - where - Self: Sized; - - /// Check if argument has a valid option prefix for this platform. - /// Linux: `-`, Windows: `/` or `-`. - fn has_option_prefix(arg: &str) -> bool; - - /// Strip the option prefix(es) from an argument. - /// Linux: `--` or `-`, Windows: `/` or `-`. - fn strip_option<'a>(arg: &'a str) -> Option<&'a str>; - - /// Find the key=value separator position in a stripped option. - /// Linux: `=`, Windows: `:` or `=`. - fn find_separator(stripped: &str) -> Option; -} - -pub(crate) fn add_silently_ignored_flags( - parser: &mut linux::ArgumentParser, -) { - fn noop(_args: &mut T, _modifier_stack: &mut Vec) -> Result<()> { +// ── Shared type definitions (format-agnostic) ──────────────────────────────── + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum VersionMode { + /// Don't print version + None, + /// Print version and continue linking (-v) + Verbose, + /// Print version and exit immediately (--version) + ExitAfterPrint, +} + +#[derive(Debug)] +pub(crate) enum DefsymValue { + /// A numeric value (address) + Value(u64), + /// Reference to another symbol with an optional offset + SymbolWithOffset(String, i64), +} + +#[derive(Debug)] +pub(crate) enum Strip { + Nothing, + Debug, + All, + Retain(HashSet>), +} + +#[derive(Debug, Clone, Copy)] +pub enum CounterKind { + Cycles, + Instructions, + CacheMisses, + BranchMisses, + PageFaults, + PageFaultsMinor, + PageFaultsMajor, + L1dRead, + L1dMiss, +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocations { + Allowed, + Disallowed(CopyRelocationsDisabledReason), +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocationsDisabledReason { + Flag, + SharedObject, +} + +impl Display for CopyRelocationsDisabledReason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let reason = match self { + CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", + CopyRelocationsDisabledReason::SharedObject => "output is a shared object", + }; + Display::fmt(&reason, f) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum RelocationModel { + NonRelocatable, + Relocatable, +} + +#[derive(Debug, Copy, Clone)] +pub(crate) enum Experiment { + /// How much parallelism to allow when splitting string-merge sections. + MergeStringSplitParallelism = 0, + + /// Number of bytes of string-merge sections before we'll break to a new group. + MergeStringMinGroupBytes = 1, + + GroupsPerThread = 2, + + MinGroups = 3, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum FileWriteMode { + /// The existing output file, if any, will be unlinked (deleted) and a new file with the same + /// name put in its place. Any hard links to the file will not be affected. + UnlinkAndReplace, + + /// The existing output file, if any, will be edited in-place. Any hard links to the file will + /// update accordingly. If the file is locked due to currently being executed, then our write + /// will fail. + UpdateInPlace, + + /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to + /// unlinking and replacing. + UpdateInPlaceWithFallback, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub(crate) enum BSymbolicKind { + None, + All, + Functions, + NonWeakFunctions, + NonWeak, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum UnresolvedSymbols { + /// Report all unresolved symbols. + ReportAll, + + /// Ignore unresolved symbols in shared libraries. + IgnoreInSharedLibs, + + /// Ignore unresolved symbols in object files. + IgnoreInObjectFiles, + + /// Ignore all unresolved symbols. + IgnoreAll, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum ExcludeLibs { + None, + All, + Some(HashSet>), +} + +impl ExcludeLibs { + pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { + match self { + ExcludeLibs::None => false, + ExcludeLibs::All => true, + ExcludeLibs::Some(libs) => { + let lib_path_str = String::from_utf8_lossy(lib_path); + let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); + + libs.contains(lib_name) + } + } + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub struct Modifiers { + /// Whether shared objects should only be linked if they're referenced. + pub(crate) as_needed: bool, + + /// Whether we're currently allowed to link against shared libraries. + pub(crate) allow_shared: bool, + + /// Whether object files in archives should be linked even if they do not contain symbols that + /// are referenced. + pub(crate) whole_archive: bool, + + /// Whether archive semantics should be applied even for regular objects. + pub(crate) archive_semantics: bool, + + /// Whether the file is known to be a temporary file that will be deleted when the linker + /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is + /// stored in the layout file if written so that linker-diff knows not to error if the file + /// is missing. + pub(crate) temporary: bool, +} + +impl Default for Modifiers { + fn default() -> Self { + Self { + as_needed: false, + allow_shared: true, + whole_archive: false, + archive_semantics: false, + temporary: false, + } + } +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) struct Input { + pub(crate) spec: InputSpec, + /// A directory to search first. Only present when the input came from a linker script, in + /// which case this is the directory containing the linker script. + pub(crate) search_first: Option, + pub(crate) modifiers: Modifiers, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum InputSpec { + /// Path (possibly just a filename) to the file. + File(Box), + /// Name of the library, without prefix and suffix. + Lib(Box), + /// Name of the library, including prefix and suffix. + Search(Box), +} + +// ── End shared type definitions ────────────────────────────────────────────── + +// ── Argument parser infrastructure ─────────────────────────────────────────── + +pub(crate) struct ArgumentParser { + options: HashMap<&'static str, OptionHandler>, + short_options: HashMap<&'static str, OptionHandler>, + prefix_options: HashMap<&'static str, PrefixOptionHandler>, + case_insensitive: bool, + has_option_prefix: fn(&str) -> bool, + strip_option: for<'a> fn(&'a str) -> Option<&'a str>, + find_separator: fn(&str) -> Option, +} + +struct OptionHandler { + help_text: &'static str, + handler: OptionHandlerFn, + short_names: Vec<&'static str>, +} + +impl Clone for OptionHandler { + fn clone(&self) -> Self { + Self { + help_text: self.help_text, + handler: self.handler, + short_names: self.short_names.clone(), + } + } +} + +struct PrefixOptionHandler { + help_text: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + sub_options: HashMap<&'static str, SubOption>, +} + +#[allow(clippy::enum_variant_names)] +enum OptionHandlerFn { + NoParam(fn(&mut Args, &mut Vec) -> Result<()>), + WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), + OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), +} + +impl Clone for OptionHandlerFn { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for OptionHandlerFn {} + +impl OptionHandlerFn { + fn help_suffix_long(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => "=", + OptionHandlerFn::OptionalParam(_) => "[=]", + } + } + + fn help_suffix_short(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => " ", + OptionHandlerFn::OptionalParam(_) => " []", + } + } +} + +pub(crate) struct OptionDeclaration<'a, T, S> { + parser: &'a mut ArgumentParser, + long_names: Vec<&'static str>, + short_names: Vec<&'static str>, + prefixes: Vec<&'static str>, + sub_options: HashMap<&'static str, SubOption>, + help_text: &'static str, + _phantom: std::marker::PhantomData, +} + +pub struct NoParam; +pub struct WithParam; +pub struct WithOptionalParam; + +enum SubOptionHandler { + /// Handler without value parameter (exact match) + NoValue(fn(&mut Args, &mut Vec) -> Result<()>), + /// Handler with value parameter (prefix match) + WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), +} + +impl Clone for SubOptionHandler { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOptionHandler {} + +struct SubOption { + help: &'static str, + handler: SubOptionHandler, +} + +impl Clone for SubOption { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOption {} + +impl SubOption { + fn with_value(&self) -> bool { + matches!(self.handler, SubOptionHandler::WithValue(_)) + } +} + +impl Default for ArgumentParser { + fn default() -> Self { + Self::new() + } +} + +impl ArgumentParser { + #[must_use] + pub fn new() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: false, + has_option_prefix: |arg| arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix("--").or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find('='), + } + } + + #[must_use] + pub fn new_case_insensitive() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: true, + has_option_prefix: |arg| arg.starts_with('/') || arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix('/').or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find(':'), + } + } + + pub fn declare(&mut self) -> OptionDeclaration<'_, T, NoParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, T, WithParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, T, WithOptionalParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { + if self.case_insensitive { + if let Some(handler) = self.options.get(option_name) { + return Some(handler); + } + for (key, handler) in &self.options { + if key.eq_ignore_ascii_case(option_name) { + return Some(handler); + } + } + None + } else { + self.options.get(option_name) + } + } + + pub(crate) fn handle_argument, I: Iterator>( + &self, + args: &mut Args, + modifier_stack: &mut Vec, + arg: &str, + input: &mut I, + ) -> Result<()> { + // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. + // Handle `@file`option (recursively) - merging in the options contained in the file + if let Some(path) = arg.strip_prefix('@') { + let file_args = read_args_from_file(Path::new(path))?; + let mut file_arg_iter = file_args.iter(); + while let Some(file_arg) = file_arg_iter.next() { + self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; + } + return Ok(()); + } + + if let Some(stripped) = (self.strip_option)(arg) { + // Check for option with separator syntax + if let Some(eq_pos) = (self.find_separator)(stripped) { + let option_name = &stripped[..eq_pos]; + let value = &stripped[eq_pos + 1..]; + + if let Some(handler) = self.get_option_handler(option_name) { + match &handler.handler { + OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, + OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, + OptionHandlerFn::NoParam(_) => return Ok(()), + } + return Ok(()); + } + } else { + if stripped == "build-id" + && let Some(handler) = self.get_option_handler(stripped) + && let OptionHandlerFn::WithParam(f) = &handler.handler + { + f(args, modifier_stack, "fast")?; + return Ok(()); + } + + if let Some(handler) = self.get_option_handler(stripped) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + } + + if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { + let option_name = &arg[1..]; + if let Some(handler) = self.short_options.get(option_name) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + + // Prefix options. These should be handled after processing long and short options, + // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. + for (prefix, handler) in &self.prefix_options { + if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { + let value = if rest.is_empty() { + let next_arg = input + .next() + .context(format!("Missing argument to -{prefix}"))?; + next_arg.as_ref().to_owned() + } else { + rest.to_owned() + }; + + if let Some((key, param_value)) = value.split_once('=') { + // Value has '=', look up key with trailing '=' + if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { + match sub.handler { + SubOptionHandler::NoValue(_) => { + (handler.handler)(args, modifier_stack, &value)?; + } + SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } else { + // No '=' in value, look up exact match + if let Some(sub) = handler.sub_options.get(value.as_str()) { + match sub.handler { + SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, + SubOptionHandler::WithValue(_) => { + bail!("Option -{prefix} {value} requires a value"); + } + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } + return Ok(()); + } + } + + if (self.has_option_prefix)(arg) { + if let Some(stripped) = (self.strip_option)(arg) + && IGNORED_FLAGS.contains(&stripped) + { + warn_unsupported(arg)?; + return Ok(()); + } + + args.unrecognized_options.push(arg.to_owned()); + return Ok(()); + } + + args.save_dir.handle_file(arg); + args.inputs.push(Input { + spec: InputSpec::File(Box::from(Path::new(arg))), + search_first: None, + modifiers: *modifier_stack.last().unwrap(), + }); + + Ok(()) + } + + #[must_use] + fn generate_help(&self) -> String { + let mut help = String::new(); + help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); + + let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); + prefix_options.sort_by_key(|(prefix, _)| *prefix); + + // TODO: This is ad-hoc + help.push_str(&format!( + " {:<31} Read options from a file\n", + format!("@"), + )); + + let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); + let mut processed_short_options: HashSet<&str> = HashSet::new(); + + // Collect all long options and their associated short options + for (long_name, handler) in &self.options { + if !handler.help_text.is_empty() { + let long_suffix = handler.handler.help_suffix_long(); + let mut option_names = vec![format!("--{long_name}{long_suffix}")]; + + // Add associated short options + let short_suffix = handler.handler.help_suffix_short(); + for short_char in &handler.short_names { + option_names.push(format!("-{short_char}{short_suffix}")); + } + + help_to_options + .entry(handler.help_text) + .or_default() + .extend(option_names); + } + + // Mark short options of help-less handlers as processed + for short_name in &handler.short_names { + processed_short_options.insert(short_name); + } + } + + for (prefix, handler) in prefix_options { + if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { + help.push_str(&format!( + " -{:<30} {}\n", + format!("{prefix} "), + handler.help_text + )); + + // Add sub-options if they exist + let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); + sub_options.sort_by_key(|(name, _)| *name); + + for (sub_name, sub) in sub_options { + let display_name = if sub.with_value() && sub_name.ends_with('=') { + // sub_name ends with '=' (e.g., "max-page-size="), so add + format!("{sub_name}") + } else { + sub_name.to_string() + }; + help.push_str(&format!( + " -{prefix} {display_name:<30} {sub_help}\n", + sub_help = sub.help + )); + } + } + } + + // Add short-only options + for (short_char, handler) in &self.short_options { + if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { + let short_suffix = handler.handler.help_suffix_short(); + help_to_options + .entry(handler.help_text) + .or_default() + .push(format!("-{short_char}{short_suffix}")); + } + } + + let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); + sorted_help_groups.sort_by_key(|(_, option_names)| { + option_names.iter().min().unwrap_or(&String::new()).clone() + }); + + for (help_text, mut option_names) in sorted_help_groups { + option_names.sort_by(|a, b| { + let a_is_short = a.len() == 2 && a.starts_with('-'); + let b_is_short = b.len() == 2 && b.starts_with('-'); + match (a_is_short, b_is_short) { + (true, false) => std::cmp::Ordering::Less, // short options first + (false, true) => std::cmp::Ordering::Greater, // long options after + _ => a.cmp(b), // same type, alphabetical + } + }); + + let option_names_str = option_names.join(", "); + help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); + } + + help + } +} + +impl<'a, T, S> OptionDeclaration<'a, T, S> { + #[must_use] + pub fn long(mut self, name: &'static str) -> Self { + self.long_names.push(name); + self + } + + #[must_use] + pub fn short(mut self, option: &'static str) -> Self { + self.short_names.push(option); + self + } + + #[must_use] + pub fn help(mut self, text: &'static str) -> Self { + self.help_text = text; + self + } + + pub fn prefix(mut self, prefix: &'static str) -> Self { + self.prefixes.push(prefix); + self + } + + #[must_use] + pub fn sub_option( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::NoValue(handler), + }, + ); + self + } + + #[must_use] + pub fn sub_option_with_value( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::WithValue(handler), + }, + ); + self + } +} + +impl<'a, T> OptionDeclaration<'a, T, NoParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::NoParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { + let mut short_names = self.short_names.clone(); + short_names.extend_from_slice(&self.prefixes); + + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::WithParam(handler), + short_names, + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + + for prefix in self.prefixes { + let prefix_handler = PrefixOptionHandler { + help_text: self.help_text, + sub_options: self.sub_options.clone(), + handler, + }; + + self.parser.prefix_options.insert(prefix, prefix_handler); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithOptionalParam> { + pub fn execute( + self, + handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>, + ) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::OptionalParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +// ── End argument parser infrastructure ─────────────────────────────────────── + +pub(crate) fn add_silently_ignored_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { Ok(()) } for flag in SILENTLY_IGNORED_FLAGS { @@ -81,8 +830,8 @@ pub(crate) fn add_silently_ignored_flags( } } -pub(crate) fn add_default_flags(parser: &mut linux::ArgumentParser) { - fn noop(_args: &mut T, _modifier_stack: &mut Vec) -> Result<()> { +pub(crate) fn add_default_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { Ok(()) } for flag in DEFAULT_FLAGS { @@ -93,6 +842,90 @@ pub(crate) fn add_default_flags(parser: &mut linux::ArgumentParser Result> { + let contents = std::fs::read_to_string(path) + .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; + arguments_from_string(&contents) +} + +/// Parses arguments from a string, handling quoting, escapes etc. +/// All arguments must be surrounded by a white space. +pub(crate) fn arguments_from_string(input: &str) -> Result> { + const QUOTES: [char; 2] = ['\'', '"']; + + let mut out = Vec::new(); + let mut chars = input.chars(); + let mut heap = None; + let mut quote = None; + let mut expect_whitespace = false; + + loop { + let Some(mut ch) = chars.next() else { + if let Some(quote) = quote.take() { + bail!("Missing closing '{quote}'"); + } + if let Some(arg) = heap.take() { + out.push(arg); + } + break; + }; + + crate::ensure!( + !expect_whitespace || ch.is_whitespace(), + "Expected white space after quoted argument" + ); + expect_whitespace = false; + + if QUOTES.contains(&ch) { + if let Some(qchr) = quote { + if qchr == ch { + // close the argument + if let Some(arg) = heap.take() { + out.push(arg); + } + quote = None; + expect_whitespace = true; + } else { + // accept the other quoting character as normal char + heap.get_or_insert(String::new()).push(ch); + } + } else { + // beginning of a new argument + crate::ensure!(heap.is_none(), "Missing opening quote '{ch}'"); + quote = Some(ch); + } + } else if ch.is_whitespace() { + if quote.is_none() { + if let Some(arg) = heap.take() { + out.push(arg); + } + } else { + heap.get_or_insert(String::new()).push(ch); + } + } else { + if ch == '\\' && (quote.is_some() || !cfg!(target_os = "windows")) { + ch = chars.next().context("Invalid escape")?; + } + heap.get_or_insert(String::new()).push(ch); + } + } + + Ok(out) +} + +pub(super) fn warn_unsupported(opt: &str) -> Result { + match std::env::var(WILD_UNSUPPORTED_ENV) + .unwrap_or_default() + .as_str() + { + "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), + "ignore" => {} + "error" => bail!("{opt} is not yet supported"), + other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), + } + Ok(()) +} + /// The output binary format. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum OutputFormat { @@ -313,33 +1146,347 @@ pub enum TargetArgs { Pe(windows::PeArgs), } -/// Parsed linker arguments. Shared fields are directly accessible. -/// Format-specific fields are behind the `target_args` enum. -pub struct Args { +/// Parsed linker arguments. Common fields are directly accessible. +/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target_args`. +/// +/// `T` defaults to `TargetArgs` (the enum). During parsing, `T` is set to the +/// concrete format type (e.g. `ElfArgs` or `PeArgs`). +#[derive(Debug)] +pub struct Args { + // ── Infrastructure ─────────────────────────────────────────────────────── pub should_fork: bool, - pub target_args: TargetArgs, + pub(crate) output: Arc, + pub(crate) arch: Architecture, + pub(crate) inputs: Vec, + pub(crate) lib_search_path: Vec>, + pub num_threads: Option, + pub(crate) available_threads: NonZeroUsize, + pub(crate) save_dir: SaveDir, + pub(crate) unrecognized_options: Vec, + pub(crate) files_per_group: Option, + pub(crate) write_layout: bool, + pub(crate) write_trace: bool, + pub(crate) jobserver_client: Option, + + // ── Core linker behavior ───────────────────────────────────────────────── + pub(crate) strip: Strip, + pub(crate) gc_sections: bool, + pub(crate) merge_sections: bool, + pub(crate) relax: bool, + pub(crate) demangle: bool, + pub(crate) no_undefined: bool, + pub(crate) allow_shlib_undefined: bool, + pub(crate) error_unresolved_symbols: bool, + pub(crate) allow_multiple_definitions: bool, + pub(crate) unresolved_symbols: UnresolvedSymbols, + pub(crate) undefined: Vec, + pub(crate) copy_relocations: CopyRelocations, + pub(crate) sysroot: Option>, + pub(crate) entry: Option, + pub(crate) wrap: Vec, + pub(crate) exclude_libs: ExcludeLibs, + pub(crate) defsym: Vec<(String, DefsymValue)>, + pub(crate) section_start: HashMap, + pub(crate) max_page_size: Option, + pub(crate) execstack: bool, + pub(crate) version_mode: VersionMode, + pub(crate) relocation_model: RelocationModel, + pub(crate) should_output_executable: bool, + pub(crate) export_all_dynamic_symbols: bool, + + // ── Output/writing ─────────────────────────────────────────────────────── + pub(crate) mmap_output_file: bool, + pub(crate) file_write_mode: Option, + pub(crate) prepopulate_maps: bool, + pub(crate) should_write_linker_identity: bool, + + // ── Debug/diagnostic ───────────────────────────────────────────────────── + pub(crate) debug_fuel: Option, + pub(crate) validate_output: bool, + pub(crate) sym_info: Option, + pub(crate) debug_address: Option, + pub(crate) print_allocations: Option, + pub(crate) verify_allocation_consistency: bool, + pub(crate) time_phase_options: Option>, + pub(crate) numeric_experiments: Vec>, + pub(crate) write_gc_stats: Option, + pub(crate) gc_stats_ignore: Vec, + pub(crate) verbose_gc_stats: bool, + pub(crate) dependency_file: Option, + + // ── Format-specific ────────────────────────────────────────────────────── + pub target_args: T, +} + +impl Default for Args { + fn default() -> Self { + Args { + // Infrastructure + should_fork: true, + arch: Architecture::DEFAULT, + unrecognized_options: Vec::new(), + lib_search_path: Vec::new(), + inputs: Vec::new(), + output: Arc::from(Path::new("a.out")), + num_threads: None, + write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), + write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), + files_per_group: None, + save_dir: Default::default(), + jobserver_client: None, + available_threads: NonZeroUsize::new(1).unwrap(), + // Core linker behavior + strip: Strip::Nothing, + gc_sections: true, + merge_sections: true, + relax: true, + demangle: true, + no_undefined: false, + allow_shlib_undefined: false, + error_unresolved_symbols: true, + allow_multiple_definitions: false, + unresolved_symbols: UnresolvedSymbols::ReportAll, + undefined: Vec::new(), + copy_relocations: CopyRelocations::Allowed, + sysroot: None, + entry: None, + wrap: Vec::new(), + exclude_libs: ExcludeLibs::None, + defsym: Vec::new(), + section_start: HashMap::new(), + max_page_size: None, + execstack: false, + version_mode: VersionMode::None, + relocation_model: RelocationModel::NonRelocatable, + should_output_executable: true, + export_all_dynamic_symbols: false, + // Output/writing + mmap_output_file: true, + file_write_mode: None, + prepopulate_maps: false, + should_write_linker_identity: true, + // Debug/diagnostic + debug_fuel: None, + validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), + sym_info: None, + debug_address: None, + print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") + .ok() + .and_then(|s| s.parse().ok()) + .map(FileId::from_encoded), + verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) + .is_ok_and(|v| v == "1"), + time_phase_options: None, + numeric_experiments: Vec::new(), + write_gc_stats: None, + gc_stats_ignore: Vec::new(), + verbose_gc_stats: false, + dependency_file: None, + // Format-specific + target_args: T::default(), + } + } +} + +impl std::ops::Deref for Args { + type Target = T; + fn deref(&self) -> &T { + &self.target_args + } +} + +impl std::ops::DerefMut for Args { + fn deref_mut(&mut self) -> &mut T { + &mut self.target_args + } +} + +impl Args { + /// Transform the target-specific part while preserving common fields. + pub fn map_target(self, f: impl FnOnce(T) -> U) -> Args { + Args { + // Infrastructure + should_fork: self.should_fork, + output: self.output, + arch: self.arch, + inputs: self.inputs, + lib_search_path: self.lib_search_path, + num_threads: self.num_threads, + available_threads: self.available_threads, + save_dir: self.save_dir, + unrecognized_options: self.unrecognized_options, + files_per_group: self.files_per_group, + write_layout: self.write_layout, + write_trace: self.write_trace, + jobserver_client: self.jobserver_client, + // Core linker behavior + strip: self.strip, + gc_sections: self.gc_sections, + merge_sections: self.merge_sections, + relax: self.relax, + demangle: self.demangle, + no_undefined: self.no_undefined, + allow_shlib_undefined: self.allow_shlib_undefined, + error_unresolved_symbols: self.error_unresolved_symbols, + allow_multiple_definitions: self.allow_multiple_definitions, + unresolved_symbols: self.unresolved_symbols, + undefined: self.undefined, + copy_relocations: self.copy_relocations, + sysroot: self.sysroot, + entry: self.entry, + wrap: self.wrap, + exclude_libs: self.exclude_libs, + defsym: self.defsym, + section_start: self.section_start, + max_page_size: self.max_page_size, + execstack: self.execstack, + version_mode: self.version_mode, + relocation_model: self.relocation_model, + should_output_executable: self.should_output_executable, + export_all_dynamic_symbols: self.export_all_dynamic_symbols, + // Output/writing + mmap_output_file: self.mmap_output_file, + file_write_mode: self.file_write_mode, + prepopulate_maps: self.prepopulate_maps, + should_write_linker_identity: self.should_write_linker_identity, + // Debug/diagnostic + debug_fuel: self.debug_fuel, + validate_output: self.validate_output, + sym_info: self.sym_info, + debug_address: self.debug_address, + print_allocations: self.print_allocations, + verify_allocation_consistency: self.verify_allocation_consistency, + time_phase_options: self.time_phase_options, + numeric_experiments: self.numeric_experiments, + write_gc_stats: self.write_gc_stats, + gc_stats_ignore: self.gc_stats_ignore, + verbose_gc_stats: self.verbose_gc_stats, + dependency_file: self.dependency_file, + // Format-specific + target_args: f(self.target_args), + } + } + + /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when + /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the + /// caller should take a different branch depending on whether the value is still positive. You + /// can then do a binary search. + pub(crate) fn use_debug_fuel(&self) -> i64 { + let Some(fuel) = self.debug_fuel.as_ref() else { + return i64::MAX; + }; + fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 + } + + /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls + /// `last_cb`. + #[allow(unused)] + pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { + match self.use_debug_fuel() { + 1.. => true, + 0 => { + last_cb(); + true + } + _ => false, + } + } + + pub(crate) fn trace_span_for_file( + &self, + file_id: FileId, + ) -> Option { + let should_trace = self.print_allocations == Some(file_id); + should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) + } + + pub fn should_fork(&self) -> bool { + self.should_fork + } + + pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { + self.numeric_experiments + .get(exp as usize) + .copied() + .flatten() + .unwrap_or(default) + } + + pub(crate) fn strip_all(&self) -> bool { + matches!(self.strip, Strip::All) + } + + pub(crate) fn strip_debug(&self) -> bool { + matches!(self.strip, Strip::All | Strip::Debug) + } +} + +/// Linker args with an activated thread pool. Holds jobserver tokens for the +/// duration of the link to keep the threads available. +pub struct ActivatedArgs { + pub args: Args, + _jobserver_tokens: Vec, +} + +impl ActivatedArgs { + pub fn map_target(self, f: impl FnOnce(T) -> U) -> ActivatedArgs { + ActivatedArgs { + args: self.args.map_target(f), + _jobserver_tokens: self._jobserver_tokens, + } + } +} + +impl Args { + /// Sets up the thread pool, using the explicit number of threads if specified, + /// or falling back to the jobserver protocol if available. + /// + /// + pub fn activate_thread_pool(mut self) -> Result> { + crate::timing_phase!("Activate thread pool"); + + let mut tokens = Vec::new(); + self.available_threads = self.num_threads.unwrap_or_else(|| { + if let Some(client) = &self.jobserver_client { + while let Ok(Some(acquired)) = client.try_acquire() { + tokens.push(acquired); + } + tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); + // Our parent "holds" one jobserver token, add it. + NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() + } else { + std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) + } + }); + + // The pool might be already initialized, suppress the error intentionally. + let _ = rayon::ThreadPoolBuilder::new() + .num_threads(self.available_threads.get()) + .build_global(); + + Ok(ActivatedArgs { + args: self, + _jobserver_tokens: tokens, + }) + } } impl Args { /// Parse CLI arguments. Detects target format from `--target=`, `-m`, /// or host default, then routes to the format-specific parser. - pub fn parse I, S: AsRef, I: Iterator>( - input: F, - ) -> Result { + pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); let detected = detect_target(&all_args)?; let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); match detected.format { OutputFormat::Elf => { - let elf = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; - let should_fork = elf.should_fork(); - Ok(Args { should_fork, target_args: TargetArgs::Elf(elf) }) + let elf_args = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(elf_args.map_target(TargetArgs::Elf)) } OutputFormat::Pe => { - let pe = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; - let should_fork = pe.should_fork(); - Ok(Args { should_fork, target_args: TargetArgs::Pe(pe) }) + let pe_args = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(pe_args.map_target(TargetArgs::Pe)) } } } @@ -348,7 +1495,7 @@ impl Args { /// Top-level parse function. pub fn parse I, S: AsRef, I: Iterator>( input: F, -) -> Result { +) -> Result> { Args::parse(input) } @@ -430,7 +1577,8 @@ mod tests { #[test] fn test_filter_strips_target_equals() { let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); assert_eq!(filtered[0], "-m"); assert_eq!(filtered[1], "elf_x86_64"); assert_eq!(filtered[2], "-o"); @@ -440,24 +1588,37 @@ mod tests { #[test] fn test_filter_strips_target_space() { let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); assert_eq!(filtered[0], "-m"); assert_eq!(filtered[1], "aarch64linux"); - assert!(!filtered.iter().any(|a| a == "--target" || a.contains("linux-gnu"))); + assert!( + !filtered + .iter() + .any(|a| a == "--target" || a.contains("linux-gnu")) + ); } #[test] fn test_filter_strips_slash_target() { let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); assert_eq!(filtered[0], "/MACHINE:X64"); assert_eq!(filtered[1], "/OUT:foo.exe"); } #[test] fn test_filter_preserves_m_flag() { - let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-m", "aarch64linux", "-o", "out"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + let args = to_strings(&[ + "--target=x86_64-unknown-linux-gnu", + "-m", + "aarch64linux", + "-o", + "out", + ]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); assert_eq!(filtered[0], "-m"); assert_eq!(filtered[1], "elf_x86_64"); assert!(filtered.contains(&"-m".to_string())); diff --git a/libwild/src/args/windows.rs b/libwild/src/args/windows.rs index ee6de80e5..819868ac8 100644 --- a/libwild/src/args/windows.rs +++ b/libwild/src/args/windows.rs @@ -1,6 +1,17 @@ -use super::*; +use super::ArgumentParser; +use super::Input; +use super::InputSpec; +use super::Modifiers; +use super::add_default_flags; +use super::add_silently_ignored_flags; +use super::consts::FILES_PER_GROUP_ENV; +use super::consts::REFERENCE_LINKER_ENV; +use crate::arch::Architecture; use crate::bail; use crate::ensure; +use crate::error::Result; +use crate::output_kind::OutputKind; +use crate::save_dir::SaveDir; use jobserver::Client; use std::num::NonZeroUsize; use std::path::Path; @@ -20,33 +31,17 @@ pub enum WindowsSubsystem { EfiRuntimeDriver, } +/// PE/COFF-specific linker arguments. Common fields (output, arch, inputs, etc.) +/// live on `Args`. Access them via direct field access on `Args`, +/// and PE-specific fields are accessible via `Deref`/`DerefMut`. pub struct PeArgs { - pub num_threads: Option, - pub(crate) save_dir: SaveDir, - pub(crate) inputs: Vec, - pub(crate) unrecognized_options: Vec, - pub(crate) jobserver_client: Option, - pub(crate) files_per_group: Option, - pub(crate) write_layout: bool, - pub(crate) write_trace: bool, - pub(crate) output_kind: OutputKind, - pub(crate) allow_copy_relocations: bool, - /// The number of actually available threads (considering jobserver) - pub(crate) available_threads: NonZeroUsize, - should_fork: bool, - // Windows-specific fields - pub(crate) output: Arc, - pub(crate) arch: Architecture, - pub(crate) lib_search_path: Vec>, pub(crate) base_address: Option, pub(crate) subsystem: Option, - pub(crate) entry_point: Option, pub(crate) heap_size: Option, pub(crate) stack_size: Option, pub(crate) is_dll: bool, pub(crate) debug_info: bool, - pub(crate) strip_symbols: bool, pub(crate) def_file: Option, pub(crate) import_lib: Option, pub(crate) manifest_file: Option, @@ -65,31 +60,12 @@ pub struct PeArgs { impl Default for PeArgs { fn default() -> Self { Self { - save_dir: SaveDir::default(), - inputs: Vec::new(), - num_threads: None, - unrecognized_options: Vec::new(), - jobserver_client: None, - files_per_group: None, - write_layout: false, - write_trace: false, - output_kind: OutputKind::StaticExecutable(RelocationModel::NonRelocatable), - allow_copy_relocations: true, - available_threads: NonZeroUsize::new(1).unwrap(), - should_fork: false, - - // Windows-specific defaults - output: Arc::from(Path::new("a.exe")), - arch: Architecture::X86_64, - lib_search_path: Vec::new(), base_address: None, subsystem: None, - entry_point: None, heap_size: None, stack_size: None, is_dll: false, debug_info: false, - strip_symbols: false, def_file: None, import_lib: None, manifest_file: None, @@ -107,66 +83,14 @@ impl Default for PeArgs { } } -impl super::PrivateArgs for PeArgs { - fn new_default() -> Self { - Self::default() - } - - fn save_dir_mut(&mut self) -> &mut SaveDir { - &mut self.save_dir - } - - fn inputs_mut(&mut self) -> &mut Vec { - &mut self.inputs - } - - fn unrecognized_options_mut(&mut self) -> &mut Vec { - &mut self.unrecognized_options - } - - fn files_per_group_mut(&mut self) -> &mut Option { - &mut self.files_per_group - } - - fn jobserver_client_mut(&mut self) -> &mut Option { - &mut self.jobserver_client - } - - fn write_layout_mut(&mut self) -> &mut bool { - &mut self.write_layout - } - - fn write_trace_mut(&mut self) -> &mut bool { - &mut self.write_trace - } - - fn setup_argument_parser() -> ArgumentParser - where - Self: Sized, - { - setup_windows_argument_parser() - } - - fn has_option_prefix(arg: &str) -> bool { - arg.starts_with('/') || arg.starts_with('-') - } - - fn strip_option<'a>(arg: &'a str) -> Option<&'a str> { - arg.strip_prefix('/').or(arg.strip_prefix('-')) - } - - fn find_separator(stripped: &str) -> Option { - stripped.find(':') - } -} - -impl PeArgs { - pub fn should_fork(&self) -> bool { - self.should_fork - } +impl super::Args { pub fn output_kind(&self) -> OutputKind { - self.output_kind + if !self.should_output_executable { + OutputKind::SharedObject + } else { + OutputKind::StaticExecutable(self.relocation_model) + } } /// Check if a specific library should be ignored due to /NODEFAULTLIB @@ -188,7 +112,7 @@ impl PeArgs { /// Parse Windows linker arguments from the given input iterator. pub(crate) fn parse I, S: AsRef, I: Iterator>( input: F, -) -> Result { +) -> Result> { use crate::input_data::MAX_FILES_PER_GROUP; // SAFETY: Should be called early before other descriptors are opened. @@ -206,7 +130,9 @@ pub(crate) fn parse I, S: AsRef, I: Iterator>( ); } - let mut args = PeArgs { + let mut args = super::Args:: { + output: Arc::from(Path::new("a.exe")), + should_write_linker_identity: false, files_per_group, jobserver_client, ..Default::default() @@ -249,7 +175,7 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .declare_with_param() .long("ALIGN") .help("/ALIGN - Specifies the alignment of each section.") - .execute(|_args: &mut PeArgs, _modifier_stack, _value| { + .execute(|_args: &mut super::Args, _modifier_stack, _value| { unimplemented_option("/ALIGN") }); // /ALLOWBIND - Specifies that a DLL can't be bound. @@ -454,7 +380,7 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .help("/DLL - Builds a DLL.") .execute(|args, _modifier_stack| { args.is_dll = true; - args.output_kind = OutputKind::SharedObject; + args.should_output_executable = false; Ok(()) }); // /DRIVER - Creates a kernel mode driver. @@ -497,7 +423,7 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .long("ENTRY") .help("/ENTRY - Sets the starting address.") .execute(|args, _modifier_stack, value| { - args.entry_point = Some(value.to_string()); + args.entry = Some(value.to_string()); Ok(()) }); // /ERRORREPORT - Deprecated. Error reporting is controlled by Windows Error Reporting (WER) settings. @@ -1212,7 +1138,7 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("WX") .help("/WX - Treats linker warnings as errors.") - .execute(|_args: &mut PeArgs, _modifier_stack, _value| { + .execute(|_args: &mut super::Args, _modifier_stack, _value| { unimplemented_option("/WX") }); @@ -1277,13 +1203,16 @@ mod tests { })); } - /// Extract PeArgs from unified Args, panicking if it's not the Pe variant. + /// Extract Args from unified Args, panicking if it's not the Pe variant. #[track_caller] - fn unwrap_pe(args: crate::args::Args) -> PeArgs { - match args.target_args { + fn unwrap_pe(args: crate::args::Args) -> crate::args::Args { + args.map_target(|t| match t { crate::args::TargetArgs::Pe(pe) => pe, - other => panic!("Expected Pe variant, got {:?}", std::mem::discriminant(&other)), - } + other => panic!( + "Expected Pe variant, got {:?}", + std::mem::discriminant(&other) + ), + }) } #[test] @@ -1500,21 +1429,21 @@ mod tests { let args_upper = &["--target=x86_64-pc-windows-msvc","/ENTRY:main", "/OUT:test.exe"]; let result_upper = unwrap_pe(crate::args::parse(|| args_upper.iter()) .unwrap()); - assert_eq!(result_upper.entry_point, Some("main".to_string())); + assert_eq!(result_upper.entry, Some("main".to_string())); assert_eq!(result_upper.output.as_ref(), Path::new("test.exe")); // Test lowercase /entry:main and /out:test.exe let args_lower = &["--target=x86_64-pc-windows-msvc","/entry:main", "/out:test.exe"]; let result_lower = unwrap_pe(crate::args::parse(|| args_lower.iter()) .unwrap()); - assert_eq!(result_lower.entry_point, Some("main".to_string())); + assert_eq!(result_lower.entry, Some("main".to_string())); assert_eq!(result_lower.output.as_ref(), Path::new("test.exe")); // Test mixed case /Entry:main and /Out:test.exe let args_mixed = &["--target=x86_64-pc-windows-msvc","/Entry:main", "/Out:test.exe"]; let result_mixed = unwrap_pe(crate::args::parse(|| args_mixed.iter()) .unwrap()); - assert_eq!(result_mixed.entry_point, Some("main".to_string())); + assert_eq!(result_mixed.entry, Some("main".to_string())); assert_eq!(result_mixed.output.as_ref(), Path::new("test.exe")); } diff --git a/libwild/src/diff.rs b/libwild/src/diff.rs index 93afdc5f0..3784ec462 100644 --- a/libwild/src/diff.rs +++ b/libwild/src/diff.rs @@ -14,7 +14,7 @@ use std::path::PathBuf; use std::process::Command; pub(crate) fn maybe_diff() -> Result { - if let Ok(reference_linker) = std::env::var(crate::args::REFERENCE_LINKER_ENV) + if let Ok(reference_linker) = std::env::var(crate::args::consts::REFERENCE_LINKER_ENV) && let Some(paths) = run_with_linker(&reference_linker)? { run_diff(&paths)?; diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index 399f9ddef..c19479f8f 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -1,4 +1,5 @@ -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::alignment::Alignment; use crate::arch::Architecture; use crate::bail; @@ -246,7 +247,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { type GroupLayoutExt = GroupLayoutExt; type CommonGroupStateExt = CommonGroupStateExt; - fn parse(input: &InputBytes<'data>, args: &ElfArgs) -> Result { + fn parse(input: &InputBytes<'data>, args: &Args) -> Result { let is_dynamic = input.kind == FileKind::ElfDynamic; let file = Self::parse_bytes(input.data, is_dynamic)?; @@ -655,7 +656,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &ElfArgs, + args: &Args, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -824,7 +825,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn new_epilogue_layout( - args: &ElfArgs, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout { @@ -1103,7 +1104,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { .sum::(), "resolved relocations"); } - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &ElfArgs) { + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args) { if args.should_write_eh_frame_hdr { common.allocate(part_id::EH_FRAME_HDR, size_of::() as u64); } @@ -1929,7 +1930,7 @@ impl ElfLayoutProperties { pub(crate) fn new<'files, 'states, 'data: 'files + 'states, P: Platform<'data>>( objects: impl Iterator>, states: impl Iterator> + Clone, - args: &ElfArgs, + args: &Args, ) -> Result { let gnu_property_notes = merge_gnu_property_notes::

(states.clone(), args.z_isa)?; let riscv_attributes = merge_riscv_attributes::

(states)?; @@ -2543,7 +2544,7 @@ pub(crate) struct GnuHashLayout { } fn create_gnu_hash_layout( - args: &ElfArgs, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Option { diff --git a/libwild/src/elf_writer.rs b/libwild/src/elf_writer.rs index 4bec49f55..ee8e969d3 100644 --- a/libwild/src/elf_writer.rs +++ b/libwild/src/elf_writer.rs @@ -4,8 +4,9 @@ use self::elf::NoteProperty; use self::elf::get_page_mask; use crate::OutputKind; use crate::alignment; -use crate::args::ElfArgs; -use crate::args::BuildIdOption; +use crate::args::Args; +use crate::args::linux::ElfArgs; +use crate::args::linux::BuildIdOption; use crate::bail; use crate::debug_assert_bail; use crate::elf; @@ -4228,7 +4229,7 @@ struct DynamicEntryWriter { } struct DynamicEntryInputs<'layout> { - args: &'layout ElfArgs, + args: &'layout Args, has_static_tls: bool, has_variant_pcs: bool, section_layouts: &'layout OutputSectionMap, diff --git a/libwild/src/file_writer.rs b/libwild/src/file_writer.rs index 6829943bb..2063c045a 100644 --- a/libwild/src/file_writer.rs +++ b/libwild/src/file_writer.rs @@ -1,7 +1,8 @@ use crate::OutputKind; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::FileWriteMode; -use crate::args::WRITE_VERIFY_ALLOCATIONS_ENV; +use crate::args::consts::WRITE_VERIFY_ALLOCATIONS_ENV; use crate::error; use crate::error::Context as _; use crate::error::Result; @@ -110,7 +111,7 @@ struct SectionAllocation { } impl Output { - pub(crate) fn new(args: &ElfArgs, output_kind: OutputKind) -> Output { + pub(crate) fn new(args: &Args, output_kind: OutputKind) -> Output { let file_write_mode = args .file_write_mode .unwrap_or_else(|| default_file_write_mode(args, output_kind)); @@ -230,7 +231,7 @@ impl Output { } /// Returns the file write mode that we should use to write to the specified path. -fn default_file_write_mode(args: &ElfArgs, output_kind: OutputKind) -> FileWriteMode { +fn default_file_write_mode(args: &Args, output_kind: OutputKind) -> FileWriteMode { if output_kind.is_shared_object() { return FileWriteMode::UnlinkAndReplace; } diff --git a/libwild/src/gc_stats.rs b/libwild/src/gc_stats.rs index 0bec4c77e..1e5deeccf 100644 --- a/libwild/src/gc_stats.rs +++ b/libwild/src/gc_stats.rs @@ -16,7 +16,8 @@ //! cargo rustc --bin rg -- -Clinker=/usr/bin/clang-15 -Clink-arg=--ld-path=wild -Clink-arg=-Wl,--write-gc-stats=/tmp/gc-stats.txt -Clink-arg=-Wl,--verbose-gc-stats //! ``` -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::error::Context as _; use crate::error::Result; use crate::layout::FileLayout; @@ -28,7 +29,7 @@ use hashbrown::HashMap; use itertools::Itertools; use std::path::PathBuf; -pub(crate) fn maybe_write_gc_stats(group_layouts: &[GroupLayout], args: &ElfArgs) -> Result { +pub(crate) fn maybe_write_gc_stats(group_layouts: &[GroupLayout], args: &Args) -> Result { let Some(stats_file) = args.write_gc_stats.as_ref() else { return Ok(()); }; @@ -46,7 +47,7 @@ struct InputFile<'data> { fn write_gc_stats( group_layouts: &[GroupLayout], stats_file: &std::path::Path, - args: &ElfArgs, + args: &Args, ) -> Result { use std::io::Write as _; diff --git a/libwild/src/grouping.rs b/libwild/src/grouping.rs index bcbd4b274..8641e5af0 100644 --- a/libwild/src/grouping.rs +++ b/libwild/src/grouping.rs @@ -1,4 +1,5 @@ -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::error::Result; use crate::input_data::FileId; use crate::input_data::MAX_FILES_PER_GROUP; @@ -189,7 +190,7 @@ pub(crate) fn create_groups<'data, O: ObjectFile<'data>>( } /// Decides after how many symbols, we should start a new group. -fn determine_symbols_per_group(num_symbols: usize, args: &ElfArgs) -> usize { +fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usize { let num_threads = args.available_threads.get(); // If we're running with a single thread, then we might as well put everything into a single @@ -213,7 +214,7 @@ fn determine_symbols_per_group(num_symbols: usize, args: &ElfArgs) -> usize { } /// Decides the maximum number of files that we'll put into one group. -fn determine_max_files_per_group(args: &ElfArgs) -> usize { +fn determine_max_files_per_group(args: &Args) -> usize { if let Some(v) = args.files_per_group { return v as usize; } diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index 952850c9f..9d23a0887 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -4,7 +4,8 @@ use crate::archive; use crate::archive::ArchiveEntry; use crate::archive::ArchiveIterator; use crate::archive::EntryMeta; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::Input; use crate::args::InputSpec; use crate::args::Modifiers; @@ -130,7 +131,7 @@ pub(crate) struct InputLinkerScript<'data> { } struct TemporaryState<'data, O: ObjectFile<'data>> { - args: &'data ElfArgs, + args: &'data Args, /// Mapping from paths to the index in `files` at which we'll place the result. path_to_load_index: Mutex>, @@ -205,7 +206,7 @@ pub(crate) struct AuxiliaryFiles<'data> { } impl<'data> AuxiliaryFiles<'data> { - pub(crate) fn new(args: &'data ElfArgs, inputs_arena: &'data Arena) -> Result { + pub(crate) fn new(args: &'data Args, inputs_arena: &'data Arena) -> Result { let resolve_script_path = |path: &Path| -> PathBuf { if path.exists() { path.to_owned() @@ -243,7 +244,7 @@ impl<'data> FileLoader<'data> { pub(crate) fn load_inputs>( &mut self, inputs: &[Input], - args: &'data ElfArgs, + args: &'data Args, plugin: &mut Option>, ) -> Result> { timing_phase!("Open input files"); @@ -408,7 +409,7 @@ impl<'data> FileLoader<'data> { fn process_linker_script<'data>( input_file: &'data InputFile, - args: &ElfArgs, + args: &Args, ) -> Result> { let bytes = input_file.data(); let script = LinkerScript::parse(bytes, &input_file.filename)?; @@ -698,7 +699,7 @@ fn read_script_data<'data>( } impl Input { - fn path(&self, args: &ElfArgs) -> Result { + fn path(&self, args: &Args) -> Result { match &self.spec { InputSpec::File(p) => { if self.search_first.is_some() diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs index 97bfd886c..67af1cdec 100644 --- a/libwild/src/layout.rs +++ b/libwild/src/layout.rs @@ -8,8 +8,9 @@ use self::elf::Symbol; use crate::OutputKind; use crate::alignment; use crate::alignment::Alignment; -use crate::args::ElfArgs; -use crate::args::BuildIdOption; +use crate::args::Args; +use crate::args::linux::ElfArgs; +use crate::args::linux::BuildIdOption; use crate::args::Strip; use crate::bail; use crate::debug_assert_bail; @@ -1456,7 +1457,7 @@ impl<'data> Layout<'data> { i } - pub(crate) fn args(&self) -> &'data ElfArgs { + pub(crate) fn args(&self) -> &'data Args { self.symbol_db.args } @@ -1737,7 +1738,7 @@ fn compute_segment_layout( output_order: &OutputOrder, program_segments: &ProgramSegments, header_info: &HeaderInfo, - args: &ElfArgs, + args: &Args, ) -> Result { #[derive(Clone)] struct Record { @@ -2666,7 +2667,7 @@ impl std::fmt::Display for GroupLayout<'_> { f, "Group with {} files. Rerun with {}=1", self.files.len(), - crate::args::FILES_PER_GROUP_ENV + crate::args::consts::FILES_PER_GROUP_ENV ) } } @@ -2681,7 +2682,7 @@ impl std::fmt::Display for GroupState<'_> { f, "Group with {} files. Rerun with {}=1", self.files.len(), - crate::args::FILES_PER_GROUP_ENV + crate::args::consts::FILES_PER_GROUP_ENV ) } } @@ -3171,7 +3172,7 @@ impl<'data> PreludeLayoutState<'data> { &mut self, common: &mut CommonGroupState, uses_tlsld: &AtomicBool, - args: &ElfArgs, + args: &Args, output_kind: OutputKind, ) { if uses_tlsld.load(atomic::Ordering::Relaxed) { @@ -3649,7 +3650,7 @@ fn should_emit_undefined_error( sym_file_id: FileId, sym_def_file_id: FileId, flags: ValueFlags, - args: &ElfArgs, + args: &Args, output_kind: OutputKind, ) -> bool { if (output_kind.is_shared_object() && !args.no_undefined) || symbol.is_weak() { @@ -3722,7 +3723,7 @@ impl<'data> SyntheticSymbolsLayoutState<'data> { impl EpilogueLayoutState { fn new( - args: &ElfArgs, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition], ) -> EpilogueLayoutState { @@ -5215,7 +5216,7 @@ fn layout_section_parts( output_sections: &OutputSections, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &ElfArgs, + args: &Args, ) -> OutputSectionPartMap { let segment_alignments = compute_segment_alignments(sizes, program_segments, output_order, args); @@ -5332,7 +5333,7 @@ fn compute_segment_alignments( sizes: &OutputSectionPartMap, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &ElfArgs, + args: &Args, ) -> HashMap { timing_phase!("Computing segment alignments"); @@ -5917,7 +5918,7 @@ fn test_no_disallowed_overlaps() { let mut output_sections = OutputSections::with_base_address(0x1000); let (output_order, program_segments) = output_sections.output_order(); - let args = ElfArgs::default(); + let args = Args::::default(); let section_part_sizes = output_sections.new_part_map::().map(|_, _| 7); let section_part_layouts = layout_section_parts( diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index ced519d99..a532eb4de 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -79,7 +79,7 @@ use crate::platform::Platform; use crate::value_flags::PerSymbolFlags; use crate::version_script::VersionScript; pub use args::Args; -use args::ElfArgs; +use args::linux::ElfArgs; use colosseum::sync::Arena; use crossbeam_utils::atomic::AtomicCell; use error::AlreadyInitialised; @@ -91,40 +91,21 @@ use output_section_id::OutputSections; use std::io::BufWriter; use std::io::Write; use std::path::Path; +pub use subprocess::run_in_subprocess; use tracing_subscriber::EnvFilter; use tracing_subscriber::fmt; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -/// Runs the linker. Dispatches to the appropriate format-specific linker based on `target_args`. +/// Runs the linker and cleans up associated resources. pub fn run(args: args::Args) -> error::Result { - match args.target_args { - args::TargetArgs::Elf(elf_args) => run_elf(elf_args), - args::TargetArgs::Pe(_) => Err(anyhow::anyhow!("PE linking not yet implemented").into()), - } -} - -/// # Safety -/// Must not be called once threads have been spawned. -pub unsafe fn run_in_subprocess(args: args::Args) -> ! { - match args.target_args { - args::TargetArgs::Elf(elf_args) => unsafe { subprocess::run_in_subprocess(elf_args) }, - args::TargetArgs::Pe(_) => { - eprintln!("PE linking does not support fork mode"); - std::process::exit(1); - } - } -} - -/// Runs the ELF linker and cleans up associated resources. -pub(crate) fn run_elf(args: ElfArgs) -> error::Result { // Note, we need to setup tracing before we activate the thread pool. In particular, we need to // initialise the timing module before the worker threads are started, otherwise the threads // won't contribute to counters such as --time=cycles,instructions etc. setup_tracing(&args)?; let args = args.activate_thread_pool()?; let linker = Linker::new(); - linker.run(&args)?; + linker.run(args)?; drop(linker); timing::finalise_perfetto_trace()?; Ok(()) @@ -133,7 +114,7 @@ pub(crate) fn run_elf(args: ElfArgs) -> error::Result { /// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be /// called once and only if nothing else has already set the global tracing dispatcher. Calling this /// is optional. If it isn't called, no tracing-based features will function. e.g. --time. -pub fn setup_tracing(args: &ElfArgs) -> Result<(), AlreadyInitialised> { +pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { if let Some(opts) = args.time_phase_options.as_ref() { timing::init_tracing(opts) } else if args.print_allocations.is_some() { @@ -193,18 +174,13 @@ impl Linker { } } - /// Runs the linker. The returned value isn't useful for anything, but is somewhat expensive to - /// drop, so we leave it up to the caller to decide when to drop it. At the point at which we - /// return, the output file should be usable. - pub fn run<'layout_inputs>( - &'layout_inputs self, - args: &'layout_inputs ActivatedArgs, - ) -> error::Result> { - let args = &args.args; - match args.version_mode { + /// Runs the linker. Takes ownership of the activated args so it can dispatch + /// to the appropriate format-specific linker internally. + pub fn run(&self, args: ActivatedArgs) -> error::Result { + match args.args.version_mode { args::VersionMode::ExitAfterPrint => { println!("{}", linker_identity()); - return Ok(LinkerOutput { layout: None }); + return Ok(()); } args::VersionMode::Verbose => { println!("{}", linker_identity()); @@ -215,19 +191,43 @@ impl Linker { } } - match args.arch { - arch::Architecture::X86_64 => self.link_for_arch::(args), - arch::Architecture::AArch64 => self.link_for_arch::(args), - arch::Architecture::RISCV64 => self.link_for_arch::(args), - arch::Architecture::LoongArch64 => { - self.link_for_arch::(args) + match args.args.target_args { + args::TargetArgs::Elf(_) => { + let args = args.map_target(|t| match t { + args::TargetArgs::Elf(e) => e, + _ => unreachable!(), + }); + let args = &args.args; + match args.arch { + arch::Architecture::X86_64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::AArch64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::RISCV64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::LoongArch64 => { + self.link_for_arch::(args)?; + } + } + } + args::TargetArgs::Pe(_) => { + crate::bail!("PE linking not yet implemented"); } } + + // We've finished linking. We consider everything from this point onwards as shutdown. + let (g1, g2) = timing_guard!("Shutdown"); + self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); + + Ok(()) } fn link_for_arch<'data, P: Platform<'data, File = crate::elf::File<'data>>>( &'data self, - args: &'data ElfArgs, + args: &'data args::Args, ) -> error::Result> { let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); @@ -256,7 +256,7 @@ impl Linker { fn load_inputs_and_link<'data, P: Platform<'data, File = crate::elf::File<'data>>>( &'data self, file_loader: &mut FileLoader<'data>, - args: &'data ElfArgs, + args: &'data args::Args, ) -> error::Result> { let mut plugin = linker_plugins::LinkerPlugin::from_args(args, &self.linker_plugin_arena, &self.herd)?; diff --git a/libwild/src/linker_plugins.rs b/libwild/src/linker_plugins.rs index 8434ce1e0..d3057d0d7 100644 --- a/libwild/src/linker_plugins.rs +++ b/libwild/src/linker_plugins.rs @@ -9,7 +9,8 @@ //! up having to make quite a bit of use of thread locals in order to get state to where it needs to //! be. -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::Input; use crate::args::Modifiers; use crate::bail; @@ -68,7 +69,7 @@ enum Store<'data> { } struct LoadInfo<'data> { - args: &'data ElfArgs, + args: &'data Args, arena: &'data Arena, } @@ -128,7 +129,7 @@ pub(crate) struct PluginOutputs { impl<'data> LinkerPlugin<'data> { pub(crate) fn from_args( - args: &'data crate::ElfArgs, + args: &'data crate::args::Args, arena: &'data Arena, herd: &'data Herd, ) -> Result>> { @@ -319,7 +320,7 @@ impl<'data> WrapSymbols<'data> { } impl LoadedPlugin { - fn new(plugin_path: &Path, args: &ElfArgs) -> Result { + fn new(plugin_path: &Path, args: &Args) -> Result { timing_phase!("Load linker plugin"); if cfg!(target_feature = "crt-static") { diff --git a/libwild/src/linker_plugins_disabled.rs b/libwild/src/linker_plugins_disabled.rs index 585504e09..596f9f033 100644 --- a/libwild/src/linker_plugins_disabled.rs +++ b/libwild/src/linker_plugins_disabled.rs @@ -35,7 +35,7 @@ impl<'data> LinkerPlugin<'data> { } pub(crate) fn from_args( - _args: &'data crate::args::ElfArgs, + _args: &'data crate::args::Args, _linker_plugin_arena: &colosseum::sync::Arena, _herd: &bumpalo_herd::Herd, ) -> Result> { diff --git a/libwild/src/output_kind.rs b/libwild/src/output_kind.rs index 70babbcc8..f6b543dbb 100644 --- a/libwild/src/output_kind.rs +++ b/libwild/src/output_kind.rs @@ -1,4 +1,5 @@ -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::RelocationModel; use crate::input_data::FileLoader; @@ -10,7 +11,7 @@ pub(crate) enum OutputKind { } impl OutputKind { - pub(crate) fn new(args: &ElfArgs, input_data: &FileLoader<'_>) -> OutputKind { + pub(crate) fn new(args: &Args, input_data: &FileLoader<'_>) -> OutputKind { if !args.should_output_executable { OutputKind::SharedObject } else if args.dynamic_linker.is_some() diff --git a/libwild/src/output_section_id.rs b/libwild/src/output_section_id.rs index 48509dcc5..463dc0f5a 100644 --- a/libwild/src/output_section_id.rs +++ b/libwild/src/output_section_id.rs @@ -18,7 +18,8 @@ use crate::alignment; use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::elf; use crate::elf::DynamicEntry; use crate::elf::GLOBAL_POINTER_SYMBOL_NAME; @@ -1016,7 +1017,7 @@ impl<'data> OutputSections<'data> { &mut self, custom_sections: &[CustomSectionDetails<'data>], sections: &mut [SectionSlot], - args: &ElfArgs, + args: &Args, ) { for custom in custom_sections { let name_str = std::str::from_utf8(custom.name.bytes()).ok(); diff --git a/libwild/src/parsing.rs b/libwild/src/parsing.rs index bc29b9c49..3d7dfc200 100644 --- a/libwild/src/parsing.rs +++ b/libwild/src/parsing.rs @@ -1,6 +1,7 @@ use crate::OutputKind; use crate::OutputSections; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::DefsymValue; use crate::args::Modifiers; use crate::args::RelocationModel; @@ -190,7 +191,7 @@ impl<'data> InternalSymDefInfo<'data> { } impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { - pub(crate) fn new(input: &InputBytes<'data>, args: &ElfArgs) -> Result> { + pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { verbose_timing_phase!("Parse file"); let object = O::parse(input, args) @@ -213,7 +214,7 @@ impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { } impl<'data> Prelude<'data> { - pub(crate) fn new(args: &'data ElfArgs, output_kind: OutputKind) -> Self { + pub(crate) fn new(args: &'data Args, output_kind: OutputKind) -> Self { verbose_timing_phase!("Construct prelude"); // The undefined symbol must always be symbol 0. diff --git a/libwild/src/part_id.rs b/libwild/src/part_id.rs index 26ad8b5b6..7c942b7c5 100644 --- a/libwild/src/part_id.rs +++ b/libwild/src/part_id.rs @@ -1,6 +1,7 @@ use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::output_section_id::BuiltInSectionDetails; use crate::output_section_id::FINI; use crate::output_section_id::INIT; @@ -60,7 +61,7 @@ pub(crate) const CUSTOM_PLACEHOLDER: PartId = PartId(u32::MAX); pub(crate) fn should_merge_sections( section_flags: S, section_alignment: u64, - args: &ElfArgs, + args: &Args, ) -> bool { if !args.merge_sections { return false; diff --git a/libwild/src/platform.rs b/libwild/src/platform.rs index ee23f143e..320b404e2 100644 --- a/libwild/src/platform.rs +++ b/libwild/src/platform.rs @@ -1,4 +1,5 @@ -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::OutputKind; use crate::Result; use crate::bail; @@ -183,7 +184,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// As for `parse_bytes` but also validates that the file architecture matches what is expected /// based on `args`. - fn parse(input: &InputBytes<'data>, args: &ElfArgs) -> Result; + fn parse(input: &InputBytes<'data>, args: &Args) -> Result; fn is_dynamic(&self) -> bool; @@ -267,7 +268,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Self::DynamicLayout; fn new_epilogue_layout( - args: &ElfArgs, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout; @@ -368,7 +369,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Result; fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &ElfArgs, + args: &Args, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -401,7 +402,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// Called after GC phase has completed. Mostly useful for platform-specific logging. fn finalise_find_required_sections(groups: &[layout::GroupState]); - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &ElfArgs); + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args); fn finalise_object_sizes( object: &mut layout::ObjectLayoutState<'data>, diff --git a/libwild/src/resolution.rs b/libwild/src/resolution.rs index ceb6b4022..9dc212a14 100644 --- a/libwild/src/resolution.rs +++ b/libwild/src/resolution.rs @@ -4,7 +4,8 @@ use crate::LayoutRules; use crate::alignment::Alignment; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::bail; use crate::debug_assert_bail; use crate::elf::RawSymbolName; @@ -688,7 +689,7 @@ pub(crate) struct ResolvedLtoInput { fn assign_section_ids<'data, O: ObjectFile<'data>>( resolved: &mut [ResolvedGroup<'data, O>], output_sections: &mut OutputSections<'data>, - args: &ElfArgs, + args: &Args, ) { timing_phase!("Assign section IDs"); @@ -1123,7 +1124,7 @@ impl<'data, O: ObjectFile<'data>> ResolvedDynamic<'data, O> { fn resolve_sections_for_object<'data, O: ObjectFile<'data>>( obj: &mut ResolvedObject<'data, O>, - args: &ElfArgs, + args: &Args, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, @@ -1151,7 +1152,7 @@ fn resolve_section<'data, O: ObjectFile<'data>>( input_section_index: SectionIndex, input_section: &O::SectionHeader, obj: &mut ResolvedObject<'data, O>, - args: &ElfArgs, + args: &Args, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, diff --git a/libwild/src/save_dir.rs b/libwild/src/save_dir.rs index 69fca2e40..5e77c926b 100644 --- a/libwild/src/save_dir.rs +++ b/libwild/src/save_dir.rs @@ -1,6 +1,7 @@ //! Support for saving inputs for later use. -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::archive::ArchiveEntry; use crate::archive::ArchiveIterator; use crate::args::Modifiers; @@ -48,7 +49,7 @@ impl SaveDir { )))) } - pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &ElfArgs) -> Result { + pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &Args) -> Result { if let Some(state) = self.0.as_ref() { let mut files_to_copy = state.files_to_copy.clone(); files_to_copy.extend( @@ -132,7 +133,7 @@ impl SaveDirState { fn finish<'a, I: Iterator>( &self, filenames: I, - parsed_args: &ElfArgs, + parsed_args: &Args, ) -> Result { for filename in filenames { self.copy_file(&std::path::absolute(filename)?, parsed_args)?; @@ -148,7 +149,7 @@ impl SaveDirState { Ok(()) } - fn write_args_file(&self, run_file: &Path, args: &ElfArgs) -> Result { + fn write_args_file(&self, run_file: &Path, args: &Args) -> Result { let mut file = std::fs::File::create(run_file)?; let mut out = BufWriter::new(&mut file); out.write_all(PRELUDE.as_bytes())?; @@ -229,7 +230,7 @@ impl SaveDirState { } /// Copies `source_path` to our output directory. - fn copy_file(&self, source_path: &Path, parsed_args: &ElfArgs) -> Result { + fn copy_file(&self, source_path: &Path, parsed_args: &Args) -> Result { let dest_path = self.output_path(source_path); if dest_path.exists() || !source_path.exists() { @@ -340,7 +341,7 @@ impl SaveDirState { } /// Copies the files listed by the thin archive. - fn handle_thin_archive(&self, path: &Path, parsed_args: &ElfArgs) -> Result { + fn handle_thin_archive(&self, path: &Path, parsed_args: &Args) -> Result { let file_bytes = std::fs::read(path)?; let parent_path = path.parent().unwrap(); @@ -468,7 +469,7 @@ fn to_output_relative_path(path: &Path) -> PathBuf { /// Saves certain environment variables into the script. We only propagate environment variables /// that are known to be used for communication between the compiler and say linker plugins. -fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &ElfArgs) -> Result { +fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &Args) -> Result { for var in &["COLLECT_GCC", "COLLECT_GCC_OPTIONS"] { if let Ok(mut value) = std::env::var(var) { // COLLECT_GCC_OPTIONS has things like "-o /path/to/output-file" in it. Update these so diff --git a/libwild/src/string_merging.rs b/libwild/src/string_merging.rs index 853bcb528..5427c705c 100644 --- a/libwild/src/string_merging.rs +++ b/libwild/src/string_merging.rs @@ -26,7 +26,8 @@ //! in our primary offset map. use crate::alignment; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::args::Experiment; use crate::bail; use crate::error::Context as _; @@ -215,7 +216,7 @@ pub(crate) struct MergeStringsSectionBucket<'data> { pub(crate) fn merge_strings<'data>( inputs: &StringMergeInputs<'data>, output_sections: &OutputSections, - args: &ElfArgs, + args: &Args, ) -> Result>> { timing_phase!("Merge strings"); @@ -426,7 +427,7 @@ impl<'data> MergedStringsSection<'data> { &mut self, input_sections: &[StringMergeInputSection<'data>], reuse_pool: &ReusePool, - args: &ElfArgs, + args: &Args, ) -> Result { let mut resources = create_split_resources(&mut self.string_offsets, input_sections, reuse_pool, args); @@ -587,7 +588,7 @@ fn create_split_resources<'data, 'offsets, 'scope>( string_offsets: &'offsets mut OffsetMap, input_sections: &'scope [StringMergeInputSection<'data>], reuse_pool: &'scope ReusePool, - args: &ElfArgs, + args: &Args, ) -> SplitResources<'data, 'offsets, 'scope> { verbose_timing_phase!("Create input section groups"); diff --git a/libwild/src/subprocess/linux.rs b/libwild/src/subprocess/linux.rs index 12fabeff3..5f83b3c8e 100644 --- a/libwild/src/subprocess/linux.rs +++ b/libwild/src/subprocess/linux.rs @@ -1,4 +1,4 @@ -use crate::args::ElfArgs; +use crate::args::Args; use crate::bail; use crate::error::Context as _; use crate::error::Result; @@ -20,7 +20,7 @@ use std::ffi::c_void; /// # Safety /// Must not be called once threads have been spawned. Calling this function from main is generally /// the best way to ensure this. -pub unsafe fn run_in_subprocess(args: ElfArgs) -> ! { +pub unsafe fn run_in_subprocess(args: Args) -> ! { let exit_code = match subprocess_result(args) { Ok(code) => code, Err(error) => crate::error::report_error_and_exit(&error), @@ -28,7 +28,7 @@ pub unsafe fn run_in_subprocess(args: ElfArgs) -> ! { std::process::exit(exit_code); } -fn subprocess_result(args: ElfArgs) -> Result { +fn subprocess_result(args: Args) -> Result { let mut fds: [c_int; 2] = [0; 2]; // create the pipe used to communicate between the parent and child processes - exit on failure make_pipe(&mut fds).context("make_pipe")?; @@ -43,7 +43,7 @@ fn subprocess_result(args: ElfArgs) -> Result { crate::setup_tracing(&args)?; let args = args.activate_thread_pool()?; let linker = crate::Linker::new(); - let _outputs = linker.run(&args)?; + linker.run(args)?; crate::timing::finalise_perfetto_trace()?; inform_parent_done(&fds); Ok(0) @@ -51,7 +51,7 @@ fn subprocess_result(args: ElfArgs) -> Result { -1 => { // Fork failure in the parent - Fallback to running linker in this process - crate::run_elf(args)?; + crate::run(args)?; Ok(0) } pid => { diff --git a/libwild/src/subprocess/mod.rs b/libwild/src/subprocess/mod.rs index 646343ba0..8517e9d37 100644 --- a/libwild/src/subprocess/mod.rs +++ b/libwild/src/subprocess/mod.rs @@ -9,8 +9,8 @@ pub use linux::run_in_subprocess; pub use windows::run_in_subprocess; #[cfg(not(any(target_os = "linux", target_os = "windows")))] -pub unsafe fn run_in_subprocess(args: crate::args::ElfArgs) -> ! { - let exit_code = match crate::run_elf(args) { +pub unsafe fn run_in_subprocess(args: crate::args::Args) -> ! { + let exit_code = match crate::run(args) { Ok(()) => 0, Err(error) => crate::error::report_error_and_exit(&error), }; diff --git a/libwild/src/subprocess/windows.rs b/libwild/src/subprocess/windows.rs index 771ac8f62..7f4e48ef1 100644 --- a/libwild/src/subprocess/windows.rs +++ b/libwild/src/subprocess/windows.rs @@ -1,4 +1,4 @@ -use crate::args::ElfArgs as OsArgs; +use crate::args::Args; use crate::bail; use crate::error::Result; use phnt::ffi::HANDLE; @@ -35,7 +35,7 @@ use windows_sys::Win32::System::Threading::THREAD_ALL_ACCESS; /// # Safety /// Must not be called once threads have been spawned. Calling this function from main is generally /// the best way to ensure this. -pub unsafe fn run_in_subprocess(args: OsArgs) -> ! { +pub unsafe fn run_in_subprocess(args: Args) -> ! { let exit_code = match subprocess_result(args) { Ok(code) => code, Err(error) => crate::error::report_error_and_exit(&error), @@ -46,7 +46,7 @@ pub unsafe fn run_in_subprocess(args: OsArgs) -> ! { #[allow(non_upper_case_globals)] pub const NtCurrentProcess: HANDLE = -1isize as *mut std::ffi::c_void; -fn subprocess_result(args: OsArgs) -> Result { +fn subprocess_result(args: Args) -> Result { let (read_end, write_end) = make_pipe()?; let mut hprocess: HANDLE = std::ptr::null_mut(); @@ -65,7 +65,7 @@ fn subprocess_result(args: OsArgs) -> Result { crate::setup_tracing(&args)?; let args = args.activate_thread_pool()?; let linker = crate::Linker::new(); - let _outputs = linker.run(&args)?; + linker.run(args)?; inform_parent_done(write_end); unsafe { NtTerminateProcess(NtCurrentProcess, STATUS_PROCESS_CLONED) }; Ok(0) @@ -76,7 +76,7 @@ fn subprocess_result(args: OsArgs) -> Result { } _ => { // Fork failure in the parent - Fallback to running linker in this process - crate::run_elf(args)?; + crate::run(args)?; Ok(0) } } diff --git a/libwild/src/subprocess_unsupported.rs b/libwild/src/subprocess_unsupported.rs index 933fc378b..80e8086f2 100644 --- a/libwild/src/subprocess_unsupported.rs +++ b/libwild/src/subprocess_unsupported.rs @@ -1,7 +1,7 @@ /// # Safety /// See function of the same name in `subprocess.rs` -pub unsafe fn run_in_subprocess(args: crate::args::ElfArgs) -> ! { - let exit_code = match crate::run_elf(args) { +pub unsafe fn run_in_subprocess(args: crate::args::Args) -> ! { + let exit_code = match crate::run(args) { Ok(()) => 0, Err(error) => { eprintln!("{}", error.to_string()); diff --git a/libwild/src/symbol_db.rs b/libwild/src/symbol_db.rs index f74ce4090..0c450605e 100644 --- a/libwild/src/symbol_db.rs +++ b/libwild/src/symbol_db.rs @@ -4,7 +4,8 @@ use crate::InputLinkerScript; use crate::OutputKind; use crate::args; -use crate::args::ElfArgs; +use crate::args::Args; +use crate::args::linux::ElfArgs; use crate::bail; use crate::elf::RawSymbolName; use crate::error; @@ -71,7 +72,7 @@ use symbolic_demangle::demangle; #[derive(Debug)] pub struct SymbolDb<'data, O: ObjectFile<'data>> { - pub(crate) args: &'data ElfArgs, + pub(crate) args: &'data Args, pub(crate) groups: Vec>, @@ -321,7 +322,7 @@ impl<'data, O: ObjectFile<'data>> SymbolDb<'data, O> { } pub(crate) fn new( - args: &'data ElfArgs, + args: &'data Args, output_kind: OutputKind, auxiliary: &AuxiliaryFiles<'data>, herd: &'data bumpalo_herd::Herd, @@ -1393,7 +1394,7 @@ pub(crate) fn is_mapping_symbol_name(name: &[u8]) -> bool { fn read_symbols<'data, O: ObjectFile<'data>>( version_script: &VersionScript, shards: &mut [SymbolWriterShard<'_, '_, 'data, O>], - args: &ElfArgs, + args: &Args, export_list: &Option>, output_kind: OutputKind, ) -> Result>> { @@ -1421,7 +1422,7 @@ fn read_symbols_for_group<'data, O: ObjectFile<'data>>( version_script: &VersionScript, export_list: &Option>, num_buckets: usize, - args: &ElfArgs, + args: &Args, output_kind: OutputKind, ) -> Result> { verbose_timing_phase!( @@ -1558,7 +1559,7 @@ fn load_symbols_from_file<'data, O: ObjectFile<'data>>( version_script: &VersionScript, symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, outputs: &mut SymbolLoadOutputs<'data>, - args: &ElfArgs, + args: &Args, export_list: &Option>, output_kind: OutputKind, ) -> Result { @@ -1685,7 +1686,7 @@ trait SymbolLoader<'data, O: ObjectFile<'data>> { struct RegularObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { object: &'a O, - args: &'a ElfArgs, + args: &'a Args, version_script: &'a VersionScript<'a>, archive_semantics: bool, lib_name: &'data [u8], @@ -2070,7 +2071,7 @@ impl<'data> PendingVersionedSymbol<'data> { } /// Decides how many buckets we should use for symbol names. -fn num_symbol_hash_buckets(args: &ElfArgs) -> usize { +fn num_symbol_hash_buckets(args: &Args) -> usize { args.available_threads.get() } diff --git a/wild/src/main.rs b/wild/src/main.rs index 01789fcf7..e9359ec79 100644 --- a/wild/src/main.rs +++ b/wild/src/main.rs @@ -1,30 +1,30 @@ -#[cfg(feature = "mimalloc")] -#[global_allocator] -static MIMALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; - -#[cfg(feature = "dhat")] -#[global_allocator] -static ALLOC: dhat::Alloc = dhat::Alloc; - -fn main() { - if let Err(error) = run() { - libwild::error::report_error_and_exit(&error) - } -} - -fn run() -> libwild::error::Result { - #[cfg(feature = "dhat")] - let _profiler = dhat::Profiler::new_heap(); - - libwild::init_timing()?; - - let args = libwild::Args::parse(|| std::env::args().skip(1))?; - - if args.should_fork { - // Safety: We haven't spawned any threads yet. - unsafe { libwild::run_in_subprocess(args) }; - } else { - // Run the linker in this process without forking. - libwild::run(args) - } -} +#[cfg(feature = "mimalloc")] +#[global_allocator] +static MIMALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; + +#[cfg(feature = "dhat")] +#[global_allocator] +static ALLOC: dhat::Alloc = dhat::Alloc; + +fn main() { + if let Err(error) = run() { + libwild::error::report_error_and_exit(&error) + } +} + +fn run() -> libwild::error::Result { + #[cfg(feature = "dhat")] + let _profiler = dhat::Profiler::new_heap(); + + libwild::init_timing()?; + + let args = libwild::Args::parse(|| std::env::args().skip(1))?; + + if args.should_fork { + // Safety: We haven't spawned any threads yet. + unsafe { libwild::run_in_subprocess(args) }; + } else { + // Run the linker in this process without forking. + libwild::run(args) + } +} From adb6c32a9c498d4b2ec41e146ab56264db964cde Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Wed, 4 Mar 2026 18:26:30 +1300 Subject: [PATCH 03/10] start on coff support --- Cargo.toml | 1 + libwild/src/coff.rs | 133 +++++++++++++++++++++++ libwild/src/file_kind.rs | 10 ++ libwild/src/input_data.rs | 4 +- libwild/src/lib.rs | 10 +- libwild/src/pe_link.rs | 218 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 libwild/src/coff.rs create mode 100644 libwild/src/pe_link.rs diff --git a/Cargo.toml b/Cargo.toml index 43eade3db..06a0a456f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ memmap2 = "0.9.0" mimalloc = { version = "0.1", default-features = false } object = { version = "0.38.1", default-features = false, features = [ "elf", + "coff", "read_core", "std", "unaligned", diff --git a/libwild/src/coff.rs b/libwild/src/coff.rs new file mode 100644 index 000000000..d97051d91 --- /dev/null +++ b/libwild/src/coff.rs @@ -0,0 +1,133 @@ +//! COFF object file wrapper for PE linking. +//! +//! Provides a unified interface over regular COFF and COFF bigobj files +//! using the `object` crate's parsing support. + +use crate::error::Context as _; +use crate::error::Result; +use object::pe; +use object::read::coff::CoffHeader; +use object::read::coff::ImageSymbol; +use object::read::coff::SectionTable; + +/// A parsed COFF object file, abstracting over regular and bigobj formats. +pub(crate) enum CoffFile<'data> { + Regular { + file: object::read::coff::CoffFile<'data>, + data: &'data [u8], + }, + Big { + file: object::read::coff::CoffBigFile<'data>, + data: &'data [u8], + }, +} + +impl<'data> CoffFile<'data> { + pub(crate) fn parse(data: &'data [u8]) -> Result { + let kind = object::FileKind::parse(data).context("Failed to identify COFF file kind")?; + match kind { + object::FileKind::Coff => { + let file = object::read::coff::CoffFile::parse(data) + .context("Failed to parse COFF object")?; + Ok(CoffFile::Regular { file, data }) + } + object::FileKind::CoffBig => { + let file = object::read::coff::CoffBigFile::parse(data) + .context("Failed to parse COFF bigobj")?; + Ok(CoffFile::Big { file, data }) + } + _ => crate::bail!("Not a COFF file"), + } + } + + pub(crate) fn machine(&self) -> u16 { + match self { + CoffFile::Regular { file, .. } => file.coff_header().machine(), + CoffFile::Big { file, .. } => file.coff_header().machine(), + } + } + + pub(crate) fn sections(&self) -> SectionTable<'data> { + match self { + CoffFile::Regular { file, .. } => file.coff_section_table(), + CoffFile::Big { file, .. } => file.coff_section_table(), + } + } + + /// Iterate over symbols, calling the callback with + /// (symbol name, section number, storage class, value). + pub(crate) fn for_each_symbol( + &self, + mut cb: impl FnMut(&[u8], i32, u8, u32) -> Result<()>, + ) -> Result<()> { + match self { + CoffFile::Regular { file, .. } => { + let symbols = file.coff_symbol_table(); + for (_index, symbol) in symbols.iter() { + let name = symbol + .name(symbols.strings()) + .context("Failed to read symbol name")?; + cb( + name, + symbol.section_number() as i32, + symbol.storage_class(), + symbol.value(), + )?; + } + } + CoffFile::Big { file, .. } => { + let symbols = file.coff_symbol_table(); + for (_index, symbol) in symbols.iter() { + let name = symbol + .name(symbols.strings()) + .context("Failed to read symbol name")?; + cb( + name, + symbol.section_number() as i32, + symbol.storage_class(), + symbol.value(), + )?; + } + } + } + Ok(()) + } + + /// Get the raw data for a section by its 1-based index. + pub(crate) fn section_data( + &self, + index: object::read::SectionIndex, + ) -> Result<&'data [u8]> { + let section = self + .sections() + .section(index) + .with_context(|| format!("Invalid section index {}", index.0))?; + match self { + CoffFile::Regular { data, .. } => section + .coff_data(*data) + .map_err(|()| crate::error!("Failed to read section {} data", index.0)), + CoffFile::Big { data, .. } => section + .coff_data(*data) + .map_err(|()| crate::error!("Failed to read section {} data", index.0)), + } + } + + /// Get relocations for a section by its 1-based index. + pub(crate) fn section_relocations( + &self, + index: object::read::SectionIndex, + ) -> Result<&'data [pe::ImageRelocation]> { + let section = self + .sections() + .section(index) + .with_context(|| format!("Invalid section index {}", index.0))?; + match self { + CoffFile::Regular { data, .. } => section + .coff_relocations(*data) + .with_context(|| format!("Failed to read section {} relocations", index.0)), + CoffFile::Big { data, .. } => section + .coff_relocations(*data) + .with_context(|| format!("Failed to read section {} relocations", index.0)), + } + } +} diff --git a/libwild/src/file_kind.rs b/libwild/src/file_kind.rs index 57314657f..dbbca3b4e 100644 --- a/libwild/src/file_kind.rs +++ b/libwild/src/file_kind.rs @@ -11,6 +11,8 @@ use object::read::elf::SectionHeader; pub(crate) enum FileKind { ElfObject, ElfDynamic, + CoffObject, + CoffImport, Archive, ThinArchive, Text, @@ -48,6 +50,12 @@ impl FileKind { object::elf::ET_DYN => Ok(FileKind::ElfDynamic), t => bail!("Unsupported ELF kind {t}"), } + } else if let Ok(kind) = object::FileKind::parse(bytes) { + match kind { + object::FileKind::Coff | object::FileKind::CoffBig => Ok(FileKind::CoffObject), + object::FileKind::CoffImport => Ok(FileKind::CoffImport), + _ => bail!("Couldn't identify file type"), + } } else if bytes.is_ascii() { Ok(FileKind::Text) } else if bytes.starts_with(b"BC") { @@ -94,6 +102,8 @@ impl std::fmt::Display for FileKind { let s = match self { FileKind::ElfObject => "ELF object", FileKind::ElfDynamic => "ELF dynamic", + FileKind::CoffObject => "COFF object", + FileKind::CoffImport => "COFF import", FileKind::Archive => "archive", FileKind::ThinArchive => "thin archive", FileKind::Text => "text", diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index 9d23a0887..ec282ec60 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -84,11 +84,11 @@ pub(crate) struct InputFile { pub(crate) filename: PathBuf, /// The filename prior to path search. If this is absolute, then `filename` will be the same. - original_filename: PathBuf, + pub(crate) original_filename: PathBuf, pub(crate) modifiers: Modifiers, - data: Option, + pub(crate) data: Option, } #[derive(Debug)] diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index a532eb4de..dc885e20b 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -2,6 +2,7 @@ pub(crate) mod alignment; pub(crate) mod arch; pub(crate) mod archive; pub mod args; +pub(crate) mod coff; pub(crate) mod debug_trace; pub(crate) mod diagnostics; pub(crate) mod diff; @@ -34,6 +35,7 @@ pub(crate) mod output_section_part_map; pub(crate) mod output_trace; pub(crate) mod parsing; pub(crate) mod part_id; +pub(crate) mod pe_link; #[cfg(all( target_os = "linux", any(target_arch = "x86_64", target_arch = "aarch64") @@ -136,7 +138,7 @@ pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { /// pages) will still happen anyway. pub struct Linker { /// We store our input files here once we've read them. - inputs_arena: Arena, + pub(crate) inputs_arena: Arena, linker_plugin_arena: Arena, @@ -214,7 +216,11 @@ impl Linker { } } args::TargetArgs::Pe(_) => { - crate::bail!("PE linking not yet implemented"); + let args = args.map_target(|t| match t { + args::TargetArgs::Pe(p) => p, + _ => unreachable!(), + }); + pe_link::link_pe(self, &args.args)?; } } diff --git a/libwild/src/pe_link.rs b/libwild/src/pe_link.rs new file mode 100644 index 000000000..3660bbcdf --- /dev/null +++ b/libwild/src/pe_link.rs @@ -0,0 +1,218 @@ +//! PE/COFF linking pipeline. +//! +//! This is separate from the ELF pipeline because the Platform/ObjectFile traits are deeply +//! ELF-coupled. Shared abstractions can be extracted later once both pipelines work. + +use crate::args::windows::PeArgs; +use crate::args::Args; +use crate::args::Input; +use crate::args::InputSpec; +use crate::bail; +use crate::coff::CoffFile; +use crate::error::Context as _; +use crate::error::Result; +use crate::file_kind::FileKind; +use crate::input_data::FileData; +use crate::input_data::InputFile; +use colosseum::sync::Arena; +use object::pe; +use std::path::Path; +use std::path::PathBuf; + +pub(crate) fn link_pe<'data>( + linker: &'data crate::Linker, + args: &'data Args, +) -> Result { + let coff_files = load_coff_inputs(&linker.inputs_arena, args)?; + + let symbols = collect_symbols(&coff_files)?; + + eprintln!( + "PE link: {} COFF objects, {} defined symbols, {} undefined symbols", + coff_files.len(), + symbols.defined.len(), + symbols.undefined.len(), + ); + + bail!("PE layout and output writing not yet implemented"); +} + +struct SymbolInfo { + /// Map from symbol name to (file index, value, section index). + defined: hashbrown::HashMap, DefinedSymbol>, + /// Symbols referenced but not defined. + undefined: Vec>, +} + +struct DefinedSymbol { + file_index: usize, + section_number: i32, + value: u32, +} + +fn load_coff_inputs<'data>( + arena: &'data Arena, + args: &'data Args, +) -> Result>> { + let mut coff_files = Vec::new(); + + for input in &args.inputs { + let path = resolve_pe_input(input, &args.lib_search_path)?; + let file_data = + FileData::new(&path, false).with_context(|| format!("Failed to open `{}`", path.display()))?; + + let input_file = arena.alloc(InputFile { + filename: path.clone(), + original_filename: path.clone(), + modifiers: input.modifiers, + data: Some(file_data), + }); + let data = input_file.data(); + + if data.is_empty() { + continue; + } + + let kind = FileKind::identify_bytes(data) + .with_context(|| format!("Failed to identify `{}`", path.display()))?; + + match kind { + FileKind::CoffObject => { + let coff = CoffFile::parse(data) + .with_context(|| format!("Failed to parse COFF object `{}`", path.display()))?; + coff_files.push(coff); + } + FileKind::CoffImport => { + // TODO: Handle import libraries + } + FileKind::Archive => { + load_archive_coff_objects(data, &path, arena, &mut coff_files)?; + } + FileKind::Text => { + // Linker scripts — skip for now in PE mode + } + other => { + bail!("Unsupported input file type `{other}` for PE linking: `{}`", path.display()); + } + } + } + + Ok(coff_files) +} + +fn load_archive_coff_objects<'data>( + archive_data: &'data [u8], + archive_path: &Path, + _arena: &'data Arena, + coff_files: &mut Vec>, +) -> Result { + let archive = object::read::archive::ArchiveFile::parse(archive_data) + .with_context(|| format!("Failed to parse archive `{}`", archive_path.display()))?; + + for member in archive.members() { + let member = member + .with_context(|| format!("Failed to read archive member in `{}`", archive_path.display()))?; + let member_data = member.data(archive_data) + .with_context(|| format!("Failed to read archive member data in `{}`", archive_path.display()))?; + + if member_data.is_empty() { + continue; + } + + // Try to identify — skip non-COFF entries (e.g. import library headers) + if let Ok(kind) = FileKind::identify_bytes(member_data) { + match kind { + FileKind::CoffObject => { + let coff = CoffFile::parse(member_data).with_context(|| { + format!( + "Failed to parse COFF object in archive `{}`", + archive_path.display() + ) + })?; + coff_files.push(coff); + } + FileKind::CoffImport => { + // TODO: Handle import library entries + } + _ => { + // Skip other types in archives + } + } + } + } + + Ok(()) +} + +fn collect_symbols(coff_files: &[CoffFile]) -> Result { + let mut defined = hashbrown::HashMap::new(); + let mut undefined_set = hashbrown::HashSet::new(); + + for (file_index, coff) in coff_files.iter().enumerate() { + coff.for_each_symbol(|name, section_number, storage_class, value| { + if storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL { + if section_number > 0 { + // Defined external symbol + defined.entry(name.to_vec()).or_insert(DefinedSymbol { + file_index, + section_number, + value, + }); + } else if section_number == 0 && value == 0 { + // Undefined external symbol + undefined_set.insert(name.to_vec()); + } + } + Ok(()) + })?; + } + + // Remove symbols that are actually defined from the undefined set + for key in defined.keys() { + undefined_set.remove(key); + } + + Ok(SymbolInfo { + defined, + undefined: undefined_set.into_iter().collect(), + }) +} + +fn resolve_pe_input(input: &Input, lib_search_path: &[Box]) -> Result { + match &input.spec { + InputSpec::File(p) => { + let path = p.as_ref().to_owned(); + if path.exists() { + Ok(path) + } else if let Some(search_first) = &input.search_first { + let searched = search_first.join(&path); + if searched.exists() { + return Ok(searched); + } + Ok(path) + } else { + Ok(path) + } + } + InputSpec::Lib(lib_name) => { + // On Windows, search for .lib + let filename = format!("{lib_name}.lib"); + for dir in lib_search_path { + let path = dir.join(&filename); + if path.exists() { + return Ok(path); + } + } + bail!("Couldn't find library `{lib_name}` on library search path"); + } + InputSpec::Search(filename) => { + for dir in lib_search_path { + let path = dir.join(filename.as_ref()); + if path.exists() { + return Ok(path); + } + } + bail!("Couldn't find `{filename}` on library search path"); + } + } +} From 7e5f8613c8f199e50eaabcc91afec2fd3108c7e7 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Wed, 4 Mar 2026 20:12:32 +1300 Subject: [PATCH 04/10] make inputs more genric not just for elf --- libwild/src/elf.rs | 18 ++--------------- libwild/src/elf_aarch64.rs | 2 +- libwild/src/elf_loongarch64.rs | 2 +- libwild/src/elf_riscv64.rs | 2 +- libwild/src/elf_x86_64.rs | 4 ++-- libwild/src/input_data.rs | 10 +++++----- libwild/src/parsing.rs | 5 ++--- libwild/src/platform.rs | 36 +++++++++++++++++++++++++--------- 8 files changed, 41 insertions(+), 38 deletions(-) diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index c19479f8f..4abb4ea5d 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -22,6 +22,7 @@ use crate::output_section_part_map::OutputSectionPartMap; use crate::part_id; use crate::platform; use crate::platform::CommonSymbol; +use crate::platform::PropertyClass; use crate::platform::FrameIndex; use crate::platform::ObjectFile; use crate::platform::Platform; @@ -223,6 +224,7 @@ const _: () = assert!(!core::mem::needs_drop::()); const SECTION_PAR_COPY_SIZE_THRESHOLD: usize = 1_000_000; impl<'data> platform::ObjectFile<'data> for File<'data> { + type ArgsType = ElfArgs; type Symbol = Symbol; type SectionHeader = SectionHeader; type SectionIterator = core::slice::Iter<'data, Self::SectionHeader>; @@ -1843,22 +1845,6 @@ impl std::fmt::Display for SymDebug<'_> { } } -pub(crate) enum PropertyClass { - // A bit in the output pr_data is set if it is set in any relocatable input. - // If all bits in the output pr_data field are zero, this property should be removed from - // output. - Or, - // A bit in the output pr_data field is set only if it is set in all relocatable input pr_data - // fields. If all bits in the output pr_data field are zero, this property should be - // removed from output. - And, - // A bit in the output pr_data field is set if it is set in any relocatable input pr_data - // fields and this property is present in all relocatable input files. When all bits in - // the output pr_data field are zero, this property should not be removed from output to - // indicate it has zero in all bits. - AndOr, -} - #[derive(Debug)] pub(crate) struct GnuProperty { pub(crate) ptype: u32, diff --git a/libwild/src/elf_aarch64.rs b/libwild/src/elf_aarch64.rs index bed22ac7e..8b249a683 100644 --- a/libwild/src/elf_aarch64.rs +++ b/libwild/src/elf_aarch64.rs @@ -1,5 +1,5 @@ use crate::elf::PLT_ENTRY_SIZE; -use crate::elf::PropertyClass; +use crate::platform::PropertyClass; use crate::ensure; use crate::error; use crate::error::Result; diff --git a/libwild/src/elf_loongarch64.rs b/libwild/src/elf_loongarch64.rs index c777f89ba..c7c7ee1be 100644 --- a/libwild/src/elf_loongarch64.rs +++ b/libwild/src/elf_loongarch64.rs @@ -90,7 +90,7 @@ impl<'data> crate::platform::Platform<'data> for ElfLoongArch64 { layout.tls_start_address() } - fn get_property_class(_property_type: u32) -> Option { + fn get_property_class(_property_type: u32) -> Option { None } diff --git a/libwild/src/elf_riscv64.rs b/libwild/src/elf_riscv64.rs index e0c335abf..d09b0a8c7 100644 --- a/libwild/src/elf_riscv64.rs +++ b/libwild/src/elf_riscv64.rs @@ -101,7 +101,7 @@ impl<'data> crate::platform::Platform<'data> for ElfRiscV64 { layout.tls_start_address() } - fn get_property_class(_property_type: u32) -> Option { + fn get_property_class(_property_type: u32) -> Option { None } diff --git a/libwild/src/elf_x86_64.rs b/libwild/src/elf_x86_64.rs index fa8c794e4..d62ad5b70 100644 --- a/libwild/src/elf_x86_64.rs +++ b/libwild/src/elf_x86_64.rs @@ -5,7 +5,7 @@ use crate::OutputKind; use crate::elf::PLT_ENTRY_SIZE; -use crate::elf::PropertyClass; +use crate::platform::PropertyClass; use crate::error; use crate::error::Result; use crate::value_flags::ValueFlags; @@ -93,7 +93,7 @@ impl<'data> crate::platform::Platform<'data> for ElfX86_64 { layout.tls_end_address() } - fn get_property_class(property_type: u32) -> Option { + fn get_property_class(property_type: u32) -> Option { match property_type { GNU_PROPERTY_X86_UINT32_AND_LO..=GNU_PROPERTY_X86_UINT32_AND_HI => { Some(PropertyClass::And) diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index ec282ec60..f1fa9c260 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -131,7 +131,7 @@ pub(crate) struct InputLinkerScript<'data> { } struct TemporaryState<'data, O: ObjectFile<'data>> { - args: &'data Args, + args: &'data Args, /// Mapping from paths to the index in `files` at which we'll place the result. path_to_load_index: Mutex>, @@ -244,7 +244,7 @@ impl<'data> FileLoader<'data> { pub(crate) fn load_inputs>( &mut self, inputs: &[Input], - args: &'data Args, + args: &'data Args, plugin: &mut Option>, ) -> Result> { timing_phase!("Open input files"); @@ -407,9 +407,9 @@ impl<'data> FileLoader<'data> { } } -fn process_linker_script<'data>( +fn process_linker_script<'data, T>( input_file: &'data InputFile, - args: &Args, + args: &Args, ) -> Result> { let bytes = input_file.data(); let script = LinkerScript::parse(bytes, &input_file.filename)?; @@ -699,7 +699,7 @@ fn read_script_data<'data>( } impl Input { - fn path(&self, args: &Args) -> Result { + fn path(&self, args: &Args) -> Result { match &self.spec { InputSpec::File(p) => { if self.search_first.is_some() diff --git a/libwild/src/parsing.rs b/libwild/src/parsing.rs index 3d7dfc200..cb348a524 100644 --- a/libwild/src/parsing.rs +++ b/libwild/src/parsing.rs @@ -1,7 +1,6 @@ use crate::OutputKind; use crate::OutputSections; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::args::DefsymValue; use crate::args::Modifiers; use crate::args::RelocationModel; @@ -191,7 +190,7 @@ impl<'data> InternalSymDefInfo<'data> { } impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { - pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { + pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { verbose_timing_phase!("Parse file"); let object = O::parse(input, args) @@ -214,7 +213,7 @@ impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { } impl<'data> Prelude<'data> { - pub(crate) fn new(args: &'data Args, output_kind: OutputKind) -> Self { + pub(crate) fn new(args: &'data Args, output_kind: OutputKind) -> Self { verbose_timing_phase!("Construct prelude"); // The undefined symbol must always be symbol 0. diff --git a/libwild/src/platform.rs b/libwild/src/platform.rs index 320b404e2..a8bc131c8 100644 --- a/libwild/src/platform.rs +++ b/libwild/src/platform.rs @@ -1,5 +1,4 @@ use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::OutputKind; use crate::Result; use crate::bail; @@ -63,7 +62,7 @@ pub(crate) trait Platform<'data>: 'data { fn tp_offset_start(layout: &Layout<'data>) -> u64; // Classify a GNU property note. - fn get_property_class(property_type: u32) -> Option; + fn get_property_class(property_type: u32) -> Option; // Merge e_flags of the input files and provide an error // if the flags are not compatible. @@ -89,7 +88,7 @@ pub(crate) trait Platform<'data>: 'data { fn collect_relaxation_deltas( _section_output_address: u64, _section_bytes: &[u8], - // TODO: Change to be non-ELF specific. + // TODO: Change to be non-ELF specific once layout.rs is genericised. _relocations: crate::elf::RelocationList<'data>, _existing_deltas: Option<&SectionRelaxDeltas>, _resolve_symbol: impl FnMut(object::SymbolIndex) -> Option, @@ -180,11 +179,14 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// For platforms that don't support symbol versioning, this can just be the unit type. type VersionNames; + /// The format-specific args type (e.g. `ElfArgs` or `PeArgs`). + type ArgsType: Send + Sync + 'static; + fn parse_bytes(input: &'data [u8], is_dynamic: bool) -> Result; /// As for `parse_bytes` but also validates that the file architecture matches what is expected /// based on `args`. - fn parse(input: &InputBytes<'data>, args: &Args) -> Result; + fn parse(input: &InputBytes<'data>, args: &Args) -> Result; fn is_dynamic(&self) -> bool; @@ -268,7 +270,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Self::DynamicLayout; fn new_epilogue_layout( - args: &Args, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout; @@ -297,7 +299,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ); fn apply_late_size_adjustments_epilogue( - state: &mut crate::elf::EpilogueLayout, + state: &mut Self::EpilogueLayout, current_sizes: &OutputSectionPartMap, extra_sizes: &mut OutputSectionPartMap, dynamic_symbol_defs: &[DynamicSymbolDefinition], @@ -307,7 +309,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat epilogue_state: &mut Self::EpilogueLayout, memory_offsets: &mut OutputSectionPartMap, symbol_db: &SymbolDb<'data, Self>, - common_state: &crate::elf::ElfLayoutProperties, + common_state: &Self::LayoutProperties, dynsym_start_index: u32, dynamic_symbol_defs: &[DynamicSymbolDefinition], ) -> Result; @@ -369,7 +371,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Result; fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, + args: &Args, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -402,7 +404,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// Called after GC phase has completed. Mostly useful for platform-specific logging. fn finalise_find_required_sections(groups: &[layout::GroupState]); - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args); + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args); fn finalise_object_sizes( object: &mut layout::ObjectLayoutState<'data>, @@ -563,6 +565,22 @@ pub(crate) trait SectionAttributes: std::fmt::Debug + Send + Sync + 'static { pub(crate) struct SourceInfo(pub(crate) Option); +pub(crate) enum PropertyClass { + // A bit in the output pr_data is set if it is set in any relocatable input. + // If all bits in the output pr_data field are zero, this property should be removed from + // output. + Or, + // A bit in the output pr_data field is set only if it is set in all relocatable input pr_data + // fields. If all bits in the output pr_data field are zero, this property should be + // removed from output. + And, + // A bit in the output pr_data field is set if it is set in any relocatable input pr_data + // fields and this property is present in all relocatable input files. When all bits in + // the output pr_data field are zero, this property should not be removed from output to + // indicate it has zero in all bits. + AndOr, +} + #[derive(Debug)] pub(crate) struct SourceInfoDetails { pub(crate) path: PathBuf, From d38e72ad6a74495195018c77107cbe4456c0fdf0 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Wed, 4 Mar 2026 20:34:26 +1300 Subject: [PATCH 05/10] coff file support --- libwild/src/arch.rs | 6 +- libwild/src/coff.rs | 946 ++++++++++++++++++++++++++++++++++---- libwild/src/input_data.rs | 6 +- libwild/src/pe_link.rs | 214 +-------- 4 files changed, 873 insertions(+), 299 deletions(-) diff --git a/libwild/src/arch.rs b/libwild/src/arch.rs index 965f58ad6..bd9eea0c4 100644 --- a/libwild/src/arch.rs +++ b/libwild/src/arch.rs @@ -4,6 +4,8 @@ use object::elf::EM_AARCH64; use object::elf::EM_LOONGARCH; use object::elf::EM_RISCV; use object::elf::EM_X86_64; +use object::pe::IMAGE_FILE_MACHINE_AMD64; +use object::pe::IMAGE_FILE_MACHINE_ARM64; use std::fmt::Display; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -42,8 +44,8 @@ impl TryFrom for Architecture { fn try_from(arch: u16) -> Result { match arch { - EM_X86_64 => Ok(Self::X86_64), - EM_AARCH64 => Ok(Self::AArch64), + EM_X86_64 | IMAGE_FILE_MACHINE_AMD64 => Ok(Self::X86_64), + EM_AARCH64 | IMAGE_FILE_MACHINE_ARM64 => Ok(Self::AArch64), EM_RISCV => Ok(Self::RISCV64), EM_LOONGARCH => Ok(Self::LoongArch64), _ => bail!("Unsupported architecture: 0x{:x}", arch), diff --git a/libwild/src/coff.rs b/libwild/src/coff.rs index d97051d91..023e03905 100644 --- a/libwild/src/coff.rs +++ b/libwild/src/coff.rs @@ -1,133 +1,891 @@ //! COFF object file wrapper for PE linking. //! -//! Provides a unified interface over regular COFF and COFF bigobj files -//! using the `object` crate's parsing support. +//! Provides a unified `CoffObjectFile` type that implements the `ObjectFile` trait, +//! abstracting over regular COFF and COFF bigobj files. +use crate::args::Args; +use crate::args::windows::PeArgs; +use crate::arch::Architecture; +use crate::bail; use crate::error::Context as _; use crate::error::Result; +use crate::input_data::InputBytes; +use crate::layout; +use crate::layout::DynamicSymbolDefinition; +use crate::layout::OutputRecordLayout; +use crate::output_section_id::OutputSectionId; +use crate::output_section_id::OutputSections; +use crate::output_section_map::OutputSectionMap; +use crate::output_section_part_map::OutputSectionPartMap; +use crate::platform; +use crate::resolution::LoadedMetrics; +use crate::resolution::UnloadedSection; +use crate::symbol_db::SymbolDb; +use crate::symbol_db::Visibility; +use object::LittleEndian; use object::pe; use object::read::coff::CoffHeader; use object::read::coff::ImageSymbol; -use object::read::coff::SectionTable; +use rayon::Scope; +use std::borrow::Cow; -/// A parsed COFF object file, abstracting over regular and bigobj formats. -pub(crate) enum CoffFile<'data> { - Regular { - file: object::read::coff::CoffFile<'data>, - data: &'data [u8], - }, - Big { - file: object::read::coff::CoffBigFile<'data>, - data: &'data [u8], - }, +// ── Core COFF object file type ────────────────────────────────────────────── + +/// A parsed COFF object file that implements the `ObjectFile` trait. +/// Handles both regular COFF and COFF bigobj formats uniformly. +#[derive(Debug)] +pub(crate) struct CoffObjectFile<'data> { + data: &'data [u8], + sections: &'data [pe::ImageSectionHeader], + /// Pre-parsed symbols (leaked allocation to satisfy `'data` lifetime). + symbols: &'data [CoffSymbol], + /// Pre-resolved section names (leaked, parallel to `sections`). + section_names: &'data [&'data [u8]], + /// String table for resolving symbol names. + strings: object::read::StringTable<'data>, + machine: u16, +} + +/// Pre-parsed COFF symbol entry. Stores the essential fields from both +/// regular and bigobj symbol table entries. +#[derive(Debug, Clone, Copy)] +pub(crate) struct CoffSymbol { + /// Offset in the file data where the 8-byte name field lives. + name_data_offset: u32, + /// 1-based section number, 0 = undefined, -1 = absolute, -2 = debug. + section_number: i32, + storage_class: u8, + value: u32, + number_of_aux_symbols: u8, + has_name: bool, +} + +/// COFF section characteristics flags. +#[derive(Debug, Clone, Copy)] +pub(crate) struct CoffSectionFlags(u32); + +/// COFF section content type (derived from characteristics). +#[derive(Debug, Clone, Copy)] +pub(crate) struct CoffSectionType(u32); + +/// COFF symbol name (no versioning). +#[derive(Debug)] +pub(crate) struct CoffRawSymbolName<'data> { + name: &'data [u8], } -impl<'data> CoffFile<'data> { - pub(crate) fn parse(data: &'data [u8]) -> Result { - let kind = object::FileKind::parse(data).context("Failed to identify COFF file kind")?; +/// Stub verneed table — COFF has no symbol versioning. +#[derive(Debug)] +pub(crate) struct NeverVerneed; + +/// Stub dynamic tag values — COFF has no dynamic linking. +#[derive(Debug)] +pub(crate) enum NeverDynamicTagValues {} + +// ── Parsing ───────────────────────────────────────────────────────────────── + +impl<'data> CoffObjectFile<'data> { + fn parse_impl(data: &'data [u8]) -> Result { + let kind = + object::FileKind::parse(data).context("Failed to identify COFF file kind")?; match kind { - object::FileKind::Coff => { - let file = object::read::coff::CoffFile::parse(data) - .context("Failed to parse COFF object")?; - Ok(CoffFile::Regular { file, data }) - } - object::FileKind::CoffBig => { - let file = object::read::coff::CoffBigFile::parse(data) - .context("Failed to parse COFF bigobj")?; - Ok(CoffFile::Big { file, data }) + object::FileKind::Coff => Self::parse_regular(data), + object::FileKind::CoffBig => Self::parse_big(data), + _ => bail!("Not a COFF file"), + } + } + + fn parse_regular(data: &'data [u8]) -> Result { + let mut offset = 0; + let header = pe::ImageFileHeader::parse(data, &mut offset) + .context("Failed to parse COFF header")?; + let machine = header.machine.get(LittleEndian); + let (section_table, sym_table) = header + .sections(data, offset) + .and_then(|s| header.symbols(data).map(|sym| (s, sym))) + .context("Failed to parse COFF sections/symbols")?; + let strings = sym_table.strings(); + + let symbols = Self::collect_symbols(data, &sym_table)?; + let sections = section_table.iter().as_slice(); + let section_names = Self::resolve_all_section_names(sections, &strings)?; + + Ok(CoffObjectFile { + data, + sections, + symbols, + section_names, + strings, + machine, + }) + } + + fn parse_big(data: &'data [u8]) -> Result { + let mut offset = 0; + let header = pe::AnonObjectHeaderBigobj::parse(data, &mut offset) + .context("Failed to parse COFF bigobj header")?; + let machine = header.machine.get(LittleEndian); + let (section_table, sym_table) = header + .sections(data, offset) + .and_then(|s| header.symbols(data).map(|sym| (s, sym))) + .context("Failed to parse COFF bigobj sections/symbols")?; + let strings = sym_table.strings(); + + let symbols = Self::collect_symbols(data, &sym_table)?; + let sections = section_table.iter().as_slice(); + let section_names = Self::resolve_all_section_names(sections, &strings)?; + + Ok(CoffObjectFile { + data, + sections, + symbols, + section_names, + strings, + machine, + }) + } + + fn collect_symbols( + data: &'data [u8], + sym_table: &object::read::coff::SymbolTable<'data, &'data [u8], Coff>, + ) -> Result<&'data [CoffSymbol]> { + let mut symbols_vec = Vec::new(); + for (_, symbol) in sym_table.iter() { + // Compute offset of the name field in the file data via pointer arithmetic. + let raw_name = symbol.raw_name(); + let name_data_offset = + (raw_name.as_ptr() as usize - data.as_ptr() as usize) as u32; + let has_name = *raw_name != [0u8; 8]; + + symbols_vec.push(CoffSymbol { + name_data_offset, + section_number: symbol.section_number() as i32, + storage_class: symbol.storage_class(), + value: symbol.value(), + number_of_aux_symbols: symbol.number_of_aux_symbols(), + has_name, + }); + // Pad aux entries so indices match the raw symbol table. + for _ in 0..symbol.number_of_aux_symbols() { + symbols_vec.push(CoffSymbol { + name_data_offset: 0, + section_number: 0, + storage_class: pe::IMAGE_SYM_CLASS_NULL, + value: 0, + number_of_aux_symbols: 0, + has_name: false, + }); } - _ => crate::bail!("Not a COFF file"), + } + + Ok(Box::leak(symbols_vec.into_boxed_slice())) + } + + fn resolve_all_section_names( + sections: &'data [pe::ImageSectionHeader], + strings: &object::read::StringTable<'data>, + ) -> Result<&'data [&'data [u8]]> { + let names: Vec<&'data [u8]> = sections + .iter() + .map(|header| Self::resolve_section_name(header, strings)) + .collect::>()?; + Ok(Box::leak(names.into_boxed_slice())) + } + + fn resolve_section_name( + header: &'data pe::ImageSectionHeader, + strings: &object::read::StringTable<'data>, + ) -> Result<&'data [u8]> { + let name = &header.name; + if name[0] == b'/' { + let offset_str = &name[1..]; + let len = offset_str.iter().position(|&b| b == 0).unwrap_or(7); + let offset_str = std::str::from_utf8(&offset_str[..len]) + .context("Invalid COFF section name string table reference")?; + let offset: u32 = offset_str + .trim() + .parse() + .context("Invalid COFF section name string table offset")?; + strings + .get(offset) + .map_err(|()| crate::error!("COFF section name string table offset out of range")) + } else { + let len = name.iter().position(|&b| b == 0).unwrap_or(8); + Ok(&name[..len]) } } - pub(crate) fn machine(&self) -> u16 { - match self { - CoffFile::Regular { file, .. } => file.coff_header().machine(), - CoffFile::Big { file, .. } => file.coff_header().machine(), + /// Resolve a symbol's name from the file data using the stored offset. + fn resolve_symbol_name(&self, sym: &CoffSymbol) -> Result<&'data [u8]> { + let off = sym.name_data_offset as usize; + let name = self + .data + .get(off..off + 8) + .context("COFF symbol name offset out of range")?; + if name[..4] == [0, 0, 0, 0] { + let offset = u32::from_le_bytes(name[4..8].try_into().unwrap()); + self.strings + .get(offset) + .map_err(|()| crate::error!("Invalid COFF symbol string table offset")) + } else { + let len = name.iter().position(|&b| b == 0).unwrap_or(8); + Ok(&name[..len]) } } - pub(crate) fn sections(&self) -> SectionTable<'data> { - match self { - CoffFile::Regular { file, .. } => file.coff_section_table(), - CoffFile::Big { file, .. } => file.coff_section_table(), + /// Find the 0-based index of a section header by pointer identity with `self.sections`. + fn section_index_of(&self, header: &pe::ImageSectionHeader) -> usize { + let ptr_offset = (header as *const _ as usize) + .wrapping_sub(self.sections.as_ptr() as usize); + ptr_offset / core::mem::size_of::() + } +} + +// ── Symbol trait impl ─────────────────────────────────────────────────────── + +impl platform::Symbol for CoffSymbol { + fn as_common(&self) -> Option { + // COFF common symbols: storage_class == EXTERNAL, section_number == 0, value != 0 + if self.storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL + && self.section_number == 0 + && self.value != 0 + { + let size = self.value as u64; + let alignment = crate::alignment::Alignment::new(1).unwrap(); + let part_id = crate::output_section_id::BSS.part_id_with_alignment(alignment); + Some(platform::CommonSymbol { size, part_id }) + } else { + None + } + } + + fn is_undefined(&self) -> bool { + self.section_number == 0 && self.value == 0 + && self.storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL + } + + fn is_local(&self) -> bool { + self.storage_class != pe::IMAGE_SYM_CLASS_EXTERNAL + && self.storage_class != pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL + } + + fn is_absolute(&self) -> bool { + self.section_number == pe::IMAGE_SYM_ABSOLUTE as i32 + } + + fn is_weak(&self) -> bool { + self.storage_class == pe::IMAGE_SYM_CLASS_WEAK_EXTERNAL + } + + fn visibility(&self) -> Visibility { + Visibility::Default + } + + fn value(&self) -> u64 { + self.value as u64 + } + + fn size(&self) -> u64 { + // COFF symbols don't store size. Common symbols use value as size. + if self.is_common() { self.value as u64 } else { 0 } + } + + fn section_index(&self) -> object::SectionIndex { + // COFF sections are 1-based; convert to 0-based for object::SectionIndex. + if self.section_number > 0 { + object::SectionIndex(self.section_number as usize) + } else { + object::SectionIndex(0) + } + } + + fn has_name(&self) -> bool { + self.has_name + } + + fn debug_string(&self) -> String { + format!( + "sect={} class={} val={}", + self.section_number, self.storage_class, self.value + ) + } + + fn is_tls(&self) -> bool { + false + } + + fn is_interposable(&self) -> bool { + false + } + + fn is_func(&self) -> bool { + false + } + + fn is_ifunc(&self) -> bool { + false + } + + fn is_hidden(&self) -> bool { + false + } + + fn is_gnu_unique(&self) -> bool { + false + } +} + +// ── Section trait impls ───────────────────────────────────────────────────── + +impl<'data> platform::SectionHeader<'data, CoffObjectFile<'data>> + for pe::ImageSectionHeader +{ + fn flags(&self) -> CoffSectionFlags { + CoffSectionFlags(self.characteristics.get(LittleEndian)) + } + + fn attributes(&self) -> () {} + + fn section_type(&self) -> CoffSectionType { + CoffSectionType(self.characteristics.get(LittleEndian)) + } +} + +impl platform::SectionFlags for CoffSectionFlags { + fn is_alloc(self) -> bool { + self.0 & pe::IMAGE_SCN_MEM_DISCARDABLE == 0 + } + + fn is_writable(self) -> bool { + self.0 & pe::IMAGE_SCN_MEM_WRITE != 0 + } + + fn is_executable(self) -> bool { + self.0 & pe::IMAGE_SCN_MEM_EXECUTE != 0 + } + + fn is_tls(self) -> bool { + false + } + + fn is_merge_section(self) -> bool { + false + } + + fn is_strings(self) -> bool { + false + } + + fn should_retain(self) -> bool { + false + } + + fn should_exclude(&self) -> bool { + self.0 & pe::IMAGE_SCN_LNK_REMOVE != 0 + } + + fn is_group(self) -> bool { + self.0 & pe::IMAGE_SCN_LNK_COMDAT != 0 + } +} + +impl platform::SectionType for CoffSectionType { + fn is_note(self) -> bool { + false + } + + fn is_prog_bits(self) -> bool { + self.0 & pe::IMAGE_SCN_CNT_CODE != 0 + || self.0 & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 + } + + fn is_no_bits(self) -> bool { + self.0 & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 + } +} + +impl platform::SectionAttributes for () { + fn merge(&mut self, _rhs: Self) {} + + fn apply(&self, _output_sections: &mut OutputSections, _section_id: OutputSectionId) {} +} + +// ── RawSymbolName ─────────────────────────────────────────────────────────── + +impl<'data> platform::RawSymbolName<'data> for CoffRawSymbolName<'data> { + fn parse(bytes: &'data [u8]) -> Self { + CoffRawSymbolName { name: bytes } + } + + fn name(&self) -> &'data [u8] { + self.name + } + + fn version_name(&self) -> Option<&'data [u8]> { + None + } + + fn is_default(&self) -> bool { + true + } +} + +// ── VerneedTable ──────────────────────────────────────────────────────────── + +impl<'data> platform::VerneedTable<'data> for NeverVerneed { + fn version_name(&self, _local_symbol_index: object::SymbolIndex) -> Option<&'data [u8]> { + None + } +} + +// ── DynamicTagValues ──────────────────────────────────────────────────────── + +impl<'data> platform::DynamicTagValues<'data> for NeverDynamicTagValues { + fn lib_name(&self, _input: &crate::input_data::InputRef<'data>) -> &'data [u8] { + match *self {} + } +} + +// ── NonAddressableIndexes ─────────────────────────────────────────────────── + +impl platform::NonAddressableIndexes for () { + fn new<'data, O: platform::ObjectFile<'data>>(_symbol_db: &SymbolDb<'data, O>) -> Self {} +} + +// ── ObjectFile trait implementation ───────────────────────────────────────── + +impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { + type ArgsType = PeArgs; + type Symbol = CoffSymbol; + type SectionHeader = pe::ImageSectionHeader; + type SectionIterator = core::slice::Iter<'data, pe::ImageSectionHeader>; + type SectionFlags = CoffSectionFlags; + type SectionType = CoffSectionType; + type SectionAttributes = (); + type DynamicTagValues = NeverDynamicTagValues; + type DynamicEntry = (); + type RelocationList = &'data [pe::ImageRelocation]; + type RelocationSections = (); + type VersionNames = (); + type RawSymbolName = CoffRawSymbolName<'data>; + type VerneedTable = NeverVerneed; + type FileLayoutState = (); + type LayoutProperties = (); + type SymbolVersionIndex = (); + type DynamicLayoutState = (); + type DynamicLayout = (); + type NonAddressableCounts = (); + type NonAddressableIndexes = (); + type EpilogueLayout = (); + type GroupLayoutExt = (); + type CommonGroupStateExt = (); + + // ── Parsing ───────────────────────────────────────────────────────── + + fn parse_bytes(input: &'data [u8], _is_dynamic: bool) -> Result { + Self::parse_impl(input) + } + + fn parse(input: &InputBytes<'data>, args: &Args) -> Result { + let file = Self::parse_impl(input.data)?; + + let file_arch = Architecture::try_from(file.machine)?; + if file_arch != args.arch { + bail!( + "`{input}` has incompatible architecture: {file_arch}, expecting {}", + args.arch, + ); } + + Ok(file) } - /// Iterate over symbols, calling the callback with - /// (symbol name, section number, storage class, value). - pub(crate) fn for_each_symbol( + fn is_dynamic(&self) -> bool { + false + } + + // ── Symbols ───────────────────────────────────────────────────────── + + fn num_symbols(&self) -> usize { + self.symbols.len() + } + + fn symbols(&self) -> &'data [CoffSymbol] { + self.symbols + } + + fn enumerate_symbols( &self, - mut cb: impl FnMut(&[u8], i32, u8, u32) -> Result<()>, - ) -> Result<()> { - match self { - CoffFile::Regular { file, .. } => { - let symbols = file.coff_symbol_table(); - for (_index, symbol) in symbols.iter() { - let name = symbol - .name(symbols.strings()) - .context("Failed to read symbol name")?; - cb( - name, - symbol.section_number() as i32, - symbol.storage_class(), - symbol.value(), - )?; - } - } - CoffFile::Big { file, .. } => { - let symbols = file.coff_symbol_table(); - for (_index, symbol) in symbols.iter() { - let name = symbol - .name(symbols.strings()) - .context("Failed to read symbol name")?; - cb( - name, - symbol.section_number() as i32, - symbol.storage_class(), - symbol.value(), - )?; + ) -> impl Iterator { + let mut i = 0; + let symbols = self.symbols; + std::iter::from_fn(move || { + while i < symbols.len() { + let idx = i; + let sym = &symbols[idx]; + i += 1 + sym.number_of_aux_symbols as usize; + if sym.storage_class != pe::IMAGE_SYM_CLASS_NULL || idx == 0 { + return Some((object::SymbolIndex(idx), sym)); } } + None + }) + } + + fn symbols_iter(&self) -> impl Iterator { + self.enumerate_symbols().map(|(_, s)| s) + } + + fn symbol(&self, index: object::SymbolIndex) -> Result<&'data CoffSymbol> { + self.symbols + .get(index.0) + .with_context(|| format!("Invalid COFF symbol index {}", index.0)) + } + + fn symbol_name(&self, symbol: &CoffSymbol) -> Result<&'data [u8]> { + self.resolve_symbol_name(symbol) + } + + fn symbol_section( + &self, + symbol: &CoffSymbol, + _index: object::SymbolIndex, + ) -> Result> { + if symbol.section_number > 0 { + Ok(Some(object::SectionIndex(symbol.section_number as usize))) + } else { + Ok(None) } + } + + fn symbol_versions(&self) -> &[()] { + &[] + } + + fn symbol_version_debug(&self, _symbol_index: object::SymbolIndex) -> Option { + None + } + + fn get_version_names(&self) -> Result<()> { Ok(()) } - /// Get the raw data for a section by its 1-based index. - pub(crate) fn section_data( + fn get_symbol_name_and_version( &self, - index: object::read::SectionIndex, + symbol: &CoffSymbol, + _local_index: usize, + _version_names: &(), + ) -> Result> { + let name = self.resolve_symbol_name(symbol)?; + Ok(CoffRawSymbolName { name }) + } + + fn verneed_table(&self) -> Result { + Ok(NeverVerneed) + } + + // ── Sections ──────────────────────────────────────────────────────── + + fn num_sections(&self) -> usize { + self.sections.len() + } + + fn section_iter(&self) -> Self::SectionIterator { + self.sections.iter() + } + + fn enumerate_sections( + &self, + ) -> impl Iterator { + self.sections + .iter() + .enumerate() + .map(|(i, s)| (object::SectionIndex(i + 1), s)) + } + + fn section(&self, index: object::SectionIndex) -> Result<&'data pe::ImageSectionHeader> { + let idx = index + .0 + .checked_sub(1) + .with_context(|| format!("Invalid COFF section index {}", index.0))?; + self.sections + .get(idx) + .with_context(|| format!("COFF section index {} out of range", index.0)) + } + + fn section_by_name( + &self, + name: &str, + ) -> Option<(object::SectionIndex, &'data pe::ImageSectionHeader)> { + for (i, section_name) in self.section_names.iter().enumerate() { + if *section_name == name.as_bytes() { + return Some((object::SectionIndex(i + 1), &self.sections[i])); + } + } + None + } + + fn section_name( + &self, + section_header: &pe::ImageSectionHeader, ) -> Result<&'data [u8]> { - let section = self - .sections() - .section(index) - .with_context(|| format!("Invalid section index {}", index.0))?; - match self { - CoffFile::Regular { data, .. } => section - .coff_data(*data) - .map_err(|()| crate::error!("Failed to read section {} data", index.0)), - CoffFile::Big { data, .. } => section - .coff_data(*data) - .map_err(|()| crate::error!("Failed to read section {} data", index.0)), + let index = self.section_index_of(section_header); + self.section_names + .get(index) + .copied() + .context("Section header not found in this file") + } + + fn section_size(&self, header: &pe::ImageSectionHeader) -> Result { + Ok(header.size_of_raw_data.get(LittleEndian) as u64) + } + + fn section_alignment(&self, header: &pe::ImageSectionHeader) -> Result { + let chars = header.characteristics.get(LittleEndian); + let align_field = (chars & pe::IMAGE_SCN_ALIGN_MASK) >> 20; + if align_field == 0 { + Ok(1) + } else { + Ok(1u64 << (align_field - 1)) + } + } + + fn raw_section_data(&self, section: &pe::ImageSectionHeader) -> Result<&'data [u8]> { + let offset = section.pointer_to_raw_data.get(LittleEndian) as usize; + let size = section.size_of_raw_data.get(LittleEndian) as usize; + if size == 0 { + return Ok(&[]); } + self.data + .get(offset..offset + size) + .context("COFF section data out of range") } - /// Get relocations for a section by its 1-based index. - pub(crate) fn section_relocations( + fn section_data( &self, - index: object::read::SectionIndex, + section: &pe::ImageSectionHeader, + _member: &bumpalo_herd::Member<'data>, + _loaded_metrics: &LoadedMetrics, + ) -> Result<&'data [u8]> { + self.raw_section_data(section) + } + + fn copy_section_data(&self, section: &pe::ImageSectionHeader, out: &mut [u8]) -> Result { + let data = self.raw_section_data(section)?; + out[..data.len()].copy_from_slice(data); + Ok(()) + } + + fn section_data_cow(&self, section: &pe::ImageSectionHeader) -> Result> { + self.raw_section_data(section).map(Cow::Borrowed) + } + + fn section_display_name(&self, index: object::SectionIndex) -> Cow<'data, str> { + let idx = index.0.checked_sub(1).unwrap_or(0); + if let Some(name) = self.section_names.get(idx) { + String::from_utf8_lossy(name) + } else { + Cow::Owned(format!("section {}", index.0)) + } + } + + // ── Relocations ───────────────────────────────────────────────────── + + fn relocations( + &self, + index: object::SectionIndex, + _relocations: &(), ) -> Result<&'data [pe::ImageRelocation]> { - let section = self - .sections() - .section(index) - .with_context(|| format!("Invalid section index {}", index.0))?; - match self { - CoffFile::Regular { data, .. } => section - .coff_relocations(*data) - .with_context(|| format!("Failed to read section {} relocations", index.0)), - CoffFile::Big { data, .. } => section - .coff_relocations(*data) - .with_context(|| format!("Failed to read section {} relocations", index.0)), + let idx = index.0.checked_sub(1).unwrap_or(0); + if let Some(section) = self.sections.get(idx) { + let offset = section.pointer_to_relocations.get(LittleEndian) as usize; + let count = section.number_of_relocations.get(LittleEndian) as usize; + if count == 0 { + return Ok(&[]); + } + let size = count * core::mem::size_of::(); + let reloc_data = self + .data + .get(offset..offset + size) + .context("COFF relocation data out of range")?; + Ok(object::pod::slice_from_all_bytes(reloc_data) + .map_err(|()| crate::error!("Failed to parse COFF relocations"))?) + } else { + Ok(&[]) } } + + fn parse_relocations(&self) -> Result<()> { + Ok(()) + } + + // ── Dynamic linking stubs (COFF has no dynamic linking) ───────────── + + fn dynamic_tags(&self) -> Result<&'data [()]> { + Ok(&[]) + } + + fn dynamic_tag_values(&self) -> Option { + None + } + + fn activate_dynamic(&self, _state: &mut ()) {} + + fn dynamic_symbol_used( + &self, + _symbol_index: object::SymbolIndex, + _state: &mut (), + ) -> Result { + Ok(()) + } + + fn finalise_sizes_dynamic( + &self, + _lib_name: &[u8], + _state: &mut (), + _mem_sizes: &mut OutputSectionPartMap, + ) -> Result { + Ok(()) + } + + fn apply_non_addressable_indexes_dynamic( + &self, + _indexes: &mut (), + _counts: &mut (), + _state: &mut (), + ) -> Result { + Ok(()) + } + + fn finalise_layout_dynamic( + &self, + _state: (), + _memory_offsets: &mut OutputSectionPartMap, + _section_layouts: &OutputSectionMap, + ) {} + + // ── Layout stubs (PE layout is separate from ELF layout) ──────────── + + fn new_epilogue_layout( + _args: &Args, + _output_kind: crate::OutputKind, + _dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], + ) {} + + fn apply_non_addressable_indexes_epilogue(_counts: &mut (), _state: &mut ()) {} + + fn apply_non_addressable_indexes<'groups>( + _symbol_db: &SymbolDb<'data, Self>, + _counts: &(), + _mem_sizes_iter: impl Iterator>, + ) { + } + + fn finalise_sizes_epilogue( + _state: &mut (), + _mem_sizes: &mut OutputSectionPartMap, + _properties: &(), + _symbol_db: &SymbolDb<'data, Self>, + ) { + } + + fn finalise_sizes_all( + _mem_sizes: &mut OutputSectionPartMap, + _symbol_db: &SymbolDb<'data, Self>, + ) { + } + + fn apply_late_size_adjustments_epilogue( + _state: &mut (), + _current_sizes: &OutputSectionPartMap, + _extra_sizes: &mut OutputSectionPartMap, + _dynamic_symbol_defs: &[DynamicSymbolDefinition], + ) -> Result { + Ok(()) + } + + fn finalise_layout_epilogue( + _epilogue_state: &mut (), + _memory_offsets: &mut OutputSectionPartMap, + _symbol_db: &SymbolDb<'data, Self>, + _common_state: &(), + _dynsym_start_index: u32, + _dynamic_symbol_defs: &[DynamicSymbolDefinition], + ) -> Result { + Ok(()) + } + + fn process_gnu_note_section( + &self, + _state: &mut (), + _section_index: object::SectionIndex, + ) -> Result { + Ok(()) + } + + fn create_layout_properties<'states, 'files, P: platform::Platform<'data, File = Self>>( + _args: &Args, + _objects: impl Iterator, + _states: impl Iterator + Clone, + ) -> Result<()> + where + 'data: 'files, + 'data: 'states, + { + Ok(()) + } + + fn load_exception_frame_data<'scope, P: platform::Platform<'data, File = Self>>( + _object: &mut layout::ObjectLayoutState<'data>, + _common: &mut layout::CommonGroupState<'data>, + _eh_frame_section_index: object::SectionIndex, + _resources: &'scope layout::GraphResources<'data, '_>, + _queue: &mut layout::LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + Ok(()) + } + + fn non_empty_section_loaded<'scope, P: platform::Platform<'data, File = Self>>( + _object: &mut layout::ObjectLayoutState<'data>, + _common: &mut layout::CommonGroupState<'data>, + _queue: &mut layout::LocalWorkQueue, + _unloaded: UnloadedSection, + _resources: &'scope layout::GraphResources<'data, 'scope>, + _scope: &Scope<'scope>, + ) -> Result { + Ok(()) + } + + fn finalise_group_layout(_memory_offsets: &OutputSectionPartMap) {} + + fn finalise_find_required_sections(_groups: &[layout::GroupState]) {} + + fn pre_finalise_sizes_prelude( + _common: &mut layout::CommonGroupState, + _args: &Args, + ) { + } + + fn finalise_object_sizes( + _object: &mut layout::ObjectLayoutState<'data>, + _common: &mut layout::CommonGroupState, + ) { + } + + fn finalise_object_layout( + _object: &layout::ObjectLayoutState<'data>, + _memory_offsets: &mut OutputSectionPartMap, + ) { + } + + fn compute_object_addresses( + _object: &layout::ObjectLayoutState<'data>, + _memory_offsets: &mut OutputSectionPartMap, + ) { + } + + fn frame_data_base_address(_memory_offsets: &OutputSectionPartMap) -> u64 { + 0 + } } diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index f1fa9c260..4bc5d93ff 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -665,7 +665,11 @@ impl<'data, O: ObjectFile<'data>> TemporaryState<'data, O> { }))); } - if input_ref.is_archive_entry() && kind != FileKind::ElfObject { + if input_ref.is_archive_entry() + && kind != FileKind::ElfObject + && kind != FileKind::CoffObject + && kind != FileKind::CoffImport + { bail!("Unexpected archive member of kind {kind:?}: {input_ref}"); } diff --git a/libwild/src/pe_link.rs b/libwild/src/pe_link.rs index 3660bbcdf..4a8e39a27 100644 --- a/libwild/src/pe_link.rs +++ b/libwild/src/pe_link.rs @@ -1,218 +1,28 @@ //! PE/COFF linking pipeline. -//! -//! This is separate from the ELF pipeline because the Platform/ObjectFile traits are deeply -//! ELF-coupled. Shared abstractions can be extracted later once both pipelines work. use crate::args::windows::PeArgs; use crate::args::Args; -use crate::args::Input; -use crate::args::InputSpec; use crate::bail; -use crate::coff::CoffFile; -use crate::error::Context as _; +use crate::coff::CoffObjectFile; use crate::error::Result; -use crate::file_kind::FileKind; -use crate::input_data::FileData; -use crate::input_data::InputFile; -use colosseum::sync::Arena; -use object::pe; -use std::path::Path; -use std::path::PathBuf; +use crate::input_data::FileLoader; pub(crate) fn link_pe<'data>( linker: &'data crate::Linker, args: &'data Args, ) -> Result { - let coff_files = load_coff_inputs(&linker.inputs_arena, args)?; - - let symbols = collect_symbols(&coff_files)?; - - eprintln!( - "PE link: {} COFF objects, {} defined symbols, {} undefined symbols", - coff_files.len(), - symbols.defined.len(), - symbols.undefined.len(), - ); - - bail!("PE layout and output writing not yet implemented"); -} - -struct SymbolInfo { - /// Map from symbol name to (file index, value, section index). - defined: hashbrown::HashMap, DefinedSymbol>, - /// Symbols referenced but not defined. - undefined: Vec>, -} - -struct DefinedSymbol { - file_index: usize, - section_number: i32, - value: u32, -} - -fn load_coff_inputs<'data>( - arena: &'data Arena, - args: &'data Args, -) -> Result>> { - let mut coff_files = Vec::new(); - - for input in &args.inputs { - let path = resolve_pe_input(input, &args.lib_search_path)?; - let file_data = - FileData::new(&path, false).with_context(|| format!("Failed to open `{}`", path.display()))?; - - let input_file = arena.alloc(InputFile { - filename: path.clone(), - original_filename: path.clone(), - modifiers: input.modifiers, - data: Some(file_data), - }); - let data = input_file.data(); - - if data.is_empty() { - continue; - } - - let kind = FileKind::identify_bytes(data) - .with_context(|| format!("Failed to identify `{}`", path.display()))?; - - match kind { - FileKind::CoffObject => { - let coff = CoffFile::parse(data) - .with_context(|| format!("Failed to parse COFF object `{}`", path.display()))?; - coff_files.push(coff); - } - FileKind::CoffImport => { - // TODO: Handle import libraries - } - FileKind::Archive => { - load_archive_coff_objects(data, &path, arena, &mut coff_files)?; - } - FileKind::Text => { - // Linker scripts — skip for now in PE mode - } - other => { - bail!("Unsupported input file type `{other}` for PE linking: `{}`", path.display()); - } - } - } - - Ok(coff_files) -} - -fn load_archive_coff_objects<'data>( - archive_data: &'data [u8], - archive_path: &Path, - _arena: &'data Arena, - coff_files: &mut Vec>, -) -> Result { - let archive = object::read::archive::ArchiveFile::parse(archive_data) - .with_context(|| format!("Failed to parse archive `{}`", archive_path.display()))?; - - for member in archive.members() { - let member = member - .with_context(|| format!("Failed to read archive member in `{}`", archive_path.display()))?; - let member_data = member.data(archive_data) - .with_context(|| format!("Failed to read archive member data in `{}`", archive_path.display()))?; - - if member_data.is_empty() { - continue; + let mut file_loader = FileLoader::new(&linker.inputs_arena); + let loaded = file_loader.load_inputs::(&args.inputs, args, &mut None)?; + + let num_objects = loaded.objects.len(); + let mut num_symbols = 0; + for obj in &loaded.objects { + if let Ok(obj) = obj { + num_symbols += obj.num_symbols(); } - - // Try to identify — skip non-COFF entries (e.g. import library headers) - if let Ok(kind) = FileKind::identify_bytes(member_data) { - match kind { - FileKind::CoffObject => { - let coff = CoffFile::parse(member_data).with_context(|| { - format!( - "Failed to parse COFF object in archive `{}`", - archive_path.display() - ) - })?; - coff_files.push(coff); - } - FileKind::CoffImport => { - // TODO: Handle import library entries - } - _ => { - // Skip other types in archives - } - } - } - } - - Ok(()) -} - -fn collect_symbols(coff_files: &[CoffFile]) -> Result { - let mut defined = hashbrown::HashMap::new(); - let mut undefined_set = hashbrown::HashSet::new(); - - for (file_index, coff) in coff_files.iter().enumerate() { - coff.for_each_symbol(|name, section_number, storage_class, value| { - if storage_class == pe::IMAGE_SYM_CLASS_EXTERNAL { - if section_number > 0 { - // Defined external symbol - defined.entry(name.to_vec()).or_insert(DefinedSymbol { - file_index, - section_number, - value, - }); - } else if section_number == 0 && value == 0 { - // Undefined external symbol - undefined_set.insert(name.to_vec()); - } - } - Ok(()) - })?; } - // Remove symbols that are actually defined from the undefined set - for key in defined.keys() { - undefined_set.remove(key); - } - - Ok(SymbolInfo { - defined, - undefined: undefined_set.into_iter().collect(), - }) -} + eprintln!("PE link: {num_objects} COFF objects, {num_symbols} symbols"); -fn resolve_pe_input(input: &Input, lib_search_path: &[Box]) -> Result { - match &input.spec { - InputSpec::File(p) => { - let path = p.as_ref().to_owned(); - if path.exists() { - Ok(path) - } else if let Some(search_first) = &input.search_first { - let searched = search_first.join(&path); - if searched.exists() { - return Ok(searched); - } - Ok(path) - } else { - Ok(path) - } - } - InputSpec::Lib(lib_name) => { - // On Windows, search for .lib - let filename = format!("{lib_name}.lib"); - for dir in lib_search_path { - let path = dir.join(&filename); - if path.exists() { - return Ok(path); - } - } - bail!("Couldn't find library `{lib_name}` on library search path"); - } - InputSpec::Search(filename) => { - for dir in lib_search_path { - let path = dir.join(filename.as_ref()); - if path.exists() { - return Ok(path); - } - } - bail!("Couldn't find `{filename}` on library search path"); - } - } + bail!("PE layout and output writing not yet implemented"); } From 4279cca92d5bf1e288270afdc1d2af230fa359f1 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Wed, 4 Mar 2026 22:40:16 +1300 Subject: [PATCH 06/10] more work on making it genric --- libwild/src/args/linux.rs | 6 - libwild/src/args/mod.rs | 3287 ++++++++++++------------ libwild/src/args/windows.rs | 9 - libwild/src/coff.rs | 8 + libwild/src/file_writer.rs | 5 +- libwild/src/grouping.rs | 5 +- libwild/src/input_data.rs | 9 + libwild/src/layout.rs | 4 +- libwild/src/lib.rs | 987 ++++--- libwild/src/linker_plugins_disabled.rs | 4 +- libwild/src/output_kind.rs | 3 +- libwild/src/output_section_id.rs | 5 +- libwild/src/part_id.rs | 5 +- libwild/src/pe_link.rs | 28 - libwild/src/resolution.rs | 7 +- libwild/src/save_dir.rs | 15 +- libwild/src/symbol_db.rs | 20 +- 17 files changed, 2264 insertions(+), 2143 deletions(-) delete mode 100644 libwild/src/pe_link.rs diff --git a/libwild/src/args/linux.rs b/libwild/src/args/linux.rs index c8a92b9cf..5d74b61dd 100644 --- a/libwild/src/args/linux.rs +++ b/libwild/src/args/linux.rs @@ -63,7 +63,6 @@ use std::sync::atomic::AtomicI64; /// and ELF-specific fields are accessible via `Deref`/`DerefMut`. #[derive(Debug)] pub struct ElfArgs { - pub(crate) dynamic_linker: Option>, pub(crate) version_script_path: Option, pub(crate) should_write_eh_frame_hdr: bool, pub(crate) rpath: Option, @@ -73,8 +72,6 @@ pub struct ElfArgs { pub(crate) needs_origin_handling: bool, pub(crate) needs_nodelete_handling: bool, pub(crate) relro: bool, - pub(crate) b_symbolic: BSymbolicKind, - pub(crate) export_list: Vec, pub(crate) export_list_path: Option, pub(crate) auxiliary: Vec, pub(crate) got_plt_syms: bool, @@ -120,7 +117,6 @@ use super::consts::*; impl Default for ElfArgs { fn default() -> Self { ElfArgs { - dynamic_linker: None, version_script_path: None, should_write_eh_frame_hdr: false, rpath: None, @@ -130,8 +126,6 @@ impl Default for ElfArgs { needs_origin_handling: false, needs_nodelete_handling: false, relro: true, - b_symbolic: BSymbolicKind::None, - export_list: Vec::new(), export_list_path: None, auxiliary: Vec::new(), got_plt_syms: false, diff --git a/libwild/src/args/mod.rs b/libwild/src/args/mod.rs index 51ff02e6d..9b82bab19 100644 --- a/libwild/src/args/mod.rs +++ b/libwild/src/args/mod.rs @@ -1,1634 +1,1653 @@ -//! A handwritten parser for our arguments. -//! -//! We don't currently use a 3rd party library like clap for a few reasons. Firstly, we need to -//! support flags like `--push-state` and `--pop-state`. These need to push and pop a state stack -//! when they're parsed. Some of the other flags then need to manipulate the state of the top of the -//! stack. Positional arguments like input files and libraries to link, then need to have the -//! current state of the stack attached to that file. -//! -//! Secondly, long arguments need to also be accepted with a single '-' in addition to the more -//! common double-dash. -//! -//! Basically, we need to be able to parse arguments in the same way as the other linkers on the -//! platform that we're targeting. - -pub mod consts; -pub mod linux; -pub mod windows; - -use consts::*; - -use crate::alignment::Alignment; -use crate::arch::Architecture; -use crate::bail; -use crate::error::Context as _; -use crate::error::Result; -use crate::input_data::FileId; -use crate::save_dir::SaveDir; -use crate::target_os::Os; -use hashbrown::HashMap; -use hashbrown::HashSet; -use jobserver::Client; -use std::fmt::Display; -use std::num::NonZeroUsize; -use std::path::Path; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::atomic::AtomicI64; -use target_lexicon::Triple; - -// ── Shared type definitions (format-agnostic) ──────────────────────────────── - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum VersionMode { - /// Don't print version - None, - /// Print version and continue linking (-v) - Verbose, - /// Print version and exit immediately (--version) - ExitAfterPrint, -} - -#[derive(Debug)] -pub(crate) enum DefsymValue { - /// A numeric value (address) - Value(u64), - /// Reference to another symbol with an optional offset - SymbolWithOffset(String, i64), -} - -#[derive(Debug)] -pub(crate) enum Strip { - Nothing, - Debug, - All, - Retain(HashSet>), -} - -#[derive(Debug, Clone, Copy)] -pub enum CounterKind { - Cycles, - Instructions, - CacheMisses, - BranchMisses, - PageFaults, - PageFaultsMinor, - PageFaultsMajor, - L1dRead, - L1dMiss, -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocations { - Allowed, - Disallowed(CopyRelocationsDisabledReason), -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocationsDisabledReason { - Flag, - SharedObject, -} - -impl Display for CopyRelocationsDisabledReason { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let reason = match self { - CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", - CopyRelocationsDisabledReason::SharedObject => "output is a shared object", - }; - Display::fmt(&reason, f) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum RelocationModel { - NonRelocatable, - Relocatable, -} - -#[derive(Debug, Copy, Clone)] -pub(crate) enum Experiment { - /// How much parallelism to allow when splitting string-merge sections. - MergeStringSplitParallelism = 0, - - /// Number of bytes of string-merge sections before we'll break to a new group. - MergeStringMinGroupBytes = 1, - - GroupsPerThread = 2, - - MinGroups = 3, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum FileWriteMode { - /// The existing output file, if any, will be unlinked (deleted) and a new file with the same - /// name put in its place. Any hard links to the file will not be affected. - UnlinkAndReplace, - - /// The existing output file, if any, will be edited in-place. Any hard links to the file will - /// update accordingly. If the file is locked due to currently being executed, then our write - /// will fail. - UpdateInPlace, - - /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to - /// unlinking and replacing. - UpdateInPlaceWithFallback, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub(crate) enum BSymbolicKind { - None, - All, - Functions, - NonWeakFunctions, - NonWeak, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum UnresolvedSymbols { - /// Report all unresolved symbols. - ReportAll, - - /// Ignore unresolved symbols in shared libraries. - IgnoreInSharedLibs, - - /// Ignore unresolved symbols in object files. - IgnoreInObjectFiles, - - /// Ignore all unresolved symbols. - IgnoreAll, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum ExcludeLibs { - None, - All, - Some(HashSet>), -} - -impl ExcludeLibs { - pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { - match self { - ExcludeLibs::None => false, - ExcludeLibs::All => true, - ExcludeLibs::Some(libs) => { - let lib_path_str = String::from_utf8_lossy(lib_path); - let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); - - libs.contains(lib_name) - } - } - } -} - -#[derive(Debug, Eq, PartialEq, Clone, Copy)] -pub struct Modifiers { - /// Whether shared objects should only be linked if they're referenced. - pub(crate) as_needed: bool, - - /// Whether we're currently allowed to link against shared libraries. - pub(crate) allow_shared: bool, - - /// Whether object files in archives should be linked even if they do not contain symbols that - /// are referenced. - pub(crate) whole_archive: bool, - - /// Whether archive semantics should be applied even for regular objects. - pub(crate) archive_semantics: bool, - - /// Whether the file is known to be a temporary file that will be deleted when the linker - /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is - /// stored in the layout file if written so that linker-diff knows not to error if the file - /// is missing. - pub(crate) temporary: bool, -} - -impl Default for Modifiers { - fn default() -> Self { - Self { - as_needed: false, - allow_shared: true, - whole_archive: false, - archive_semantics: false, - temporary: false, - } - } -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) struct Input { - pub(crate) spec: InputSpec, - /// A directory to search first. Only present when the input came from a linker script, in - /// which case this is the directory containing the linker script. - pub(crate) search_first: Option, - pub(crate) modifiers: Modifiers, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum InputSpec { - /// Path (possibly just a filename) to the file. - File(Box), - /// Name of the library, without prefix and suffix. - Lib(Box), - /// Name of the library, including prefix and suffix. - Search(Box), -} - -// ── End shared type definitions ────────────────────────────────────────────── - -// ── Argument parser infrastructure ─────────────────────────────────────────── - -pub(crate) struct ArgumentParser { - options: HashMap<&'static str, OptionHandler>, - short_options: HashMap<&'static str, OptionHandler>, - prefix_options: HashMap<&'static str, PrefixOptionHandler>, - case_insensitive: bool, - has_option_prefix: fn(&str) -> bool, - strip_option: for<'a> fn(&'a str) -> Option<&'a str>, - find_separator: fn(&str) -> Option, -} - -struct OptionHandler { - help_text: &'static str, - handler: OptionHandlerFn, - short_names: Vec<&'static str>, -} - -impl Clone for OptionHandler { - fn clone(&self) -> Self { - Self { - help_text: self.help_text, - handler: self.handler, - short_names: self.short_names.clone(), - } - } -} - -struct PrefixOptionHandler { - help_text: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, - sub_options: HashMap<&'static str, SubOption>, -} - -#[allow(clippy::enum_variant_names)] -enum OptionHandlerFn { - NoParam(fn(&mut Args, &mut Vec) -> Result<()>), - WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), - OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), -} - -impl Clone for OptionHandlerFn { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for OptionHandlerFn {} - -impl OptionHandlerFn { - fn help_suffix_long(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => "=", - OptionHandlerFn::OptionalParam(_) => "[=]", - } - } - - fn help_suffix_short(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => " ", - OptionHandlerFn::OptionalParam(_) => " []", - } - } -} - -pub(crate) struct OptionDeclaration<'a, T, S> { - parser: &'a mut ArgumentParser, - long_names: Vec<&'static str>, - short_names: Vec<&'static str>, - prefixes: Vec<&'static str>, - sub_options: HashMap<&'static str, SubOption>, - help_text: &'static str, - _phantom: std::marker::PhantomData, -} - -pub struct NoParam; -pub struct WithParam; -pub struct WithOptionalParam; - -enum SubOptionHandler { - /// Handler without value parameter (exact match) - NoValue(fn(&mut Args, &mut Vec) -> Result<()>), - /// Handler with value parameter (prefix match) - WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), -} - -impl Clone for SubOptionHandler { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOptionHandler {} - -struct SubOption { - help: &'static str, - handler: SubOptionHandler, -} - -impl Clone for SubOption { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOption {} - -impl SubOption { - fn with_value(&self) -> bool { - matches!(self.handler, SubOptionHandler::WithValue(_)) - } -} - -impl Default for ArgumentParser { - fn default() -> Self { - Self::new() - } -} - -impl ArgumentParser { - #[must_use] - pub fn new() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: false, - has_option_prefix: |arg| arg.starts_with('-'), - strip_option: |arg| arg.strip_prefix("--").or(arg.strip_prefix('-')), - find_separator: |stripped| stripped.find('='), - } - } - - #[must_use] - pub fn new_case_insensitive() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: true, - has_option_prefix: |arg| arg.starts_with('/') || arg.starts_with('-'), - strip_option: |arg| arg.strip_prefix('/').or(arg.strip_prefix('-')), - find_separator: |stripped| stripped.find(':'), - } - } - - pub fn declare(&mut self) -> OptionDeclaration<'_, T, NoParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, T, WithParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, T, WithOptionalParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { - if self.case_insensitive { - if let Some(handler) = self.options.get(option_name) { - return Some(handler); - } - for (key, handler) in &self.options { - if key.eq_ignore_ascii_case(option_name) { - return Some(handler); - } - } - None - } else { - self.options.get(option_name) - } - } - - pub(crate) fn handle_argument, I: Iterator>( - &self, - args: &mut Args, - modifier_stack: &mut Vec, - arg: &str, - input: &mut I, - ) -> Result<()> { - // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. - // Handle `@file`option (recursively) - merging in the options contained in the file - if let Some(path) = arg.strip_prefix('@') { - let file_args = read_args_from_file(Path::new(path))?; - let mut file_arg_iter = file_args.iter(); - while let Some(file_arg) = file_arg_iter.next() { - self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; - } - return Ok(()); - } - - if let Some(stripped) = (self.strip_option)(arg) { - // Check for option with separator syntax - if let Some(eq_pos) = (self.find_separator)(stripped) { - let option_name = &stripped[..eq_pos]; - let value = &stripped[eq_pos + 1..]; - - if let Some(handler) = self.get_option_handler(option_name) { - match &handler.handler { - OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, - OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, - OptionHandlerFn::NoParam(_) => return Ok(()), - } - return Ok(()); - } - } else { - if stripped == "build-id" - && let Some(handler) = self.get_option_handler(stripped) - && let OptionHandlerFn::WithParam(f) = &handler.handler - { - f(args, modifier_stack, "fast")?; - return Ok(()); - } - - if let Some(handler) = self.get_option_handler(stripped) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - } - - if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { - let option_name = &arg[1..]; - if let Some(handler) = self.short_options.get(option_name) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - - // Prefix options. These should be handled after processing long and short options, - // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. - for (prefix, handler) in &self.prefix_options { - if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { - let value = if rest.is_empty() { - let next_arg = input - .next() - .context(format!("Missing argument to -{prefix}"))?; - next_arg.as_ref().to_owned() - } else { - rest.to_owned() - }; - - if let Some((key, param_value)) = value.split_once('=') { - // Value has '=', look up key with trailing '=' - if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { - match sub.handler { - SubOptionHandler::NoValue(_) => { - (handler.handler)(args, modifier_stack, &value)?; - } - SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } else { - // No '=' in value, look up exact match - if let Some(sub) = handler.sub_options.get(value.as_str()) { - match sub.handler { - SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, - SubOptionHandler::WithValue(_) => { - bail!("Option -{prefix} {value} requires a value"); - } - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } - return Ok(()); - } - } - - if (self.has_option_prefix)(arg) { - if let Some(stripped) = (self.strip_option)(arg) - && IGNORED_FLAGS.contains(&stripped) - { - warn_unsupported(arg)?; - return Ok(()); - } - - args.unrecognized_options.push(arg.to_owned()); - return Ok(()); - } - - args.save_dir.handle_file(arg); - args.inputs.push(Input { - spec: InputSpec::File(Box::from(Path::new(arg))), - search_first: None, - modifiers: *modifier_stack.last().unwrap(), - }); - - Ok(()) - } - - #[must_use] - fn generate_help(&self) -> String { - let mut help = String::new(); - help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); - - let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); - prefix_options.sort_by_key(|(prefix, _)| *prefix); - - // TODO: This is ad-hoc - help.push_str(&format!( - " {:<31} Read options from a file\n", - format!("@"), - )); - - let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); - let mut processed_short_options: HashSet<&str> = HashSet::new(); - - // Collect all long options and their associated short options - for (long_name, handler) in &self.options { - if !handler.help_text.is_empty() { - let long_suffix = handler.handler.help_suffix_long(); - let mut option_names = vec![format!("--{long_name}{long_suffix}")]; - - // Add associated short options - let short_suffix = handler.handler.help_suffix_short(); - for short_char in &handler.short_names { - option_names.push(format!("-{short_char}{short_suffix}")); - } - - help_to_options - .entry(handler.help_text) - .or_default() - .extend(option_names); - } - - // Mark short options of help-less handlers as processed - for short_name in &handler.short_names { - processed_short_options.insert(short_name); - } - } - - for (prefix, handler) in prefix_options { - if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { - help.push_str(&format!( - " -{:<30} {}\n", - format!("{prefix} "), - handler.help_text - )); - - // Add sub-options if they exist - let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); - sub_options.sort_by_key(|(name, _)| *name); - - for (sub_name, sub) in sub_options { - let display_name = if sub.with_value() && sub_name.ends_with('=') { - // sub_name ends with '=' (e.g., "max-page-size="), so add - format!("{sub_name}") - } else { - sub_name.to_string() - }; - help.push_str(&format!( - " -{prefix} {display_name:<30} {sub_help}\n", - sub_help = sub.help - )); - } - } - } - - // Add short-only options - for (short_char, handler) in &self.short_options { - if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { - let short_suffix = handler.handler.help_suffix_short(); - help_to_options - .entry(handler.help_text) - .or_default() - .push(format!("-{short_char}{short_suffix}")); - } - } - - let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); - sorted_help_groups.sort_by_key(|(_, option_names)| { - option_names.iter().min().unwrap_or(&String::new()).clone() - }); - - for (help_text, mut option_names) in sorted_help_groups { - option_names.sort_by(|a, b| { - let a_is_short = a.len() == 2 && a.starts_with('-'); - let b_is_short = b.len() == 2 && b.starts_with('-'); - match (a_is_short, b_is_short) { - (true, false) => std::cmp::Ordering::Less, // short options first - (false, true) => std::cmp::Ordering::Greater, // long options after - _ => a.cmp(b), // same type, alphabetical - } - }); - - let option_names_str = option_names.join(", "); - help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); - } - - help - } -} - -impl<'a, T, S> OptionDeclaration<'a, T, S> { - #[must_use] - pub fn long(mut self, name: &'static str) -> Self { - self.long_names.push(name); - self - } - - #[must_use] - pub fn short(mut self, option: &'static str) -> Self { - self.short_names.push(option); - self - } - - #[must_use] - pub fn help(mut self, text: &'static str) -> Self { - self.help_text = text; - self - } - - pub fn prefix(mut self, prefix: &'static str) -> Self { - self.prefixes.push(prefix); - self - } - - #[must_use] - pub fn sub_option( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut Args, &mut Vec) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::NoValue(handler), - }, - ); - self - } - - #[must_use] - pub fn sub_option_with_value( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::WithValue(handler), - }, - ); - self - } -} - -impl<'a, T> OptionDeclaration<'a, T, NoParam> { - pub fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::NoParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} - -impl<'a, T> OptionDeclaration<'a, T, WithParam> { - pub fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { - let mut short_names = self.short_names.clone(); - short_names.extend_from_slice(&self.prefixes); - - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::WithParam(handler), - short_names, - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - - for prefix in self.prefixes { - let prefix_handler = PrefixOptionHandler { - help_text: self.help_text, - sub_options: self.sub_options.clone(), - handler, - }; - - self.parser.prefix_options.insert(prefix, prefix_handler); - } - } -} - -impl<'a, T> OptionDeclaration<'a, T, WithOptionalParam> { - pub fn execute( - self, - handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>, - ) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::OptionalParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} - -// ── End argument parser infrastructure ─────────────────────────────────────── - -pub(crate) fn add_silently_ignored_flags(parser: &mut ArgumentParser) { - fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { - Ok(()) - } - for flag in SILENTLY_IGNORED_FLAGS { - parser.declare().long(flag).execute(noop); - } - for flag in SILENTLY_IGNORED_SHORT_FLAGS { - parser.declare().short(flag).execute(noop); - } -} - -pub(crate) fn add_default_flags(parser: &mut ArgumentParser) { - fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { - Ok(()) - } - for flag in DEFAULT_FLAGS { - parser.declare().long(flag).execute(noop); - } - for flag in DEFAULT_SHORT_FLAGS { - parser.declare().short(flag).execute(noop); - } -} - -pub(crate) fn read_args_from_file(path: &Path) -> Result> { - let contents = std::fs::read_to_string(path) - .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; - arguments_from_string(&contents) -} - -/// Parses arguments from a string, handling quoting, escapes etc. -/// All arguments must be surrounded by a white space. -pub(crate) fn arguments_from_string(input: &str) -> Result> { - const QUOTES: [char; 2] = ['\'', '"']; - - let mut out = Vec::new(); - let mut chars = input.chars(); - let mut heap = None; - let mut quote = None; - let mut expect_whitespace = false; - - loop { - let Some(mut ch) = chars.next() else { - if let Some(quote) = quote.take() { - bail!("Missing closing '{quote}'"); - } - if let Some(arg) = heap.take() { - out.push(arg); - } - break; - }; - - crate::ensure!( - !expect_whitespace || ch.is_whitespace(), - "Expected white space after quoted argument" - ); - expect_whitespace = false; - - if QUOTES.contains(&ch) { - if let Some(qchr) = quote { - if qchr == ch { - // close the argument - if let Some(arg) = heap.take() { - out.push(arg); - } - quote = None; - expect_whitespace = true; - } else { - // accept the other quoting character as normal char - heap.get_or_insert(String::new()).push(ch); - } - } else { - // beginning of a new argument - crate::ensure!(heap.is_none(), "Missing opening quote '{ch}'"); - quote = Some(ch); - } - } else if ch.is_whitespace() { - if quote.is_none() { - if let Some(arg) = heap.take() { - out.push(arg); - } - } else { - heap.get_or_insert(String::new()).push(ch); - } - } else { - if ch == '\\' && (quote.is_some() || !cfg!(target_os = "windows")) { - ch = chars.next().context("Invalid escape")?; - } - heap.get_or_insert(String::new()).push(ch); - } - } - - Ok(out) -} - -pub(super) fn warn_unsupported(opt: &str) -> Result { - match std::env::var(WILD_UNSUPPORTED_ENV) - .unwrap_or_default() - .as_str() - { - "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), - "ignore" => {} - "error" => bail!("{opt} is not yet supported"), - other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), - } - Ok(()) -} - -/// The output binary format. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum OutputFormat { - Elf, - Pe, -} - -impl Default for OutputFormat { - fn default() -> Self { - match Os::DEFAULT { - Os::Linux => OutputFormat::Elf, - Os::Windows => OutputFormat::Pe, - Os::MacOS => todo!("macOS linking not yet supported"), - } - } -} - -/// Result of pre-scanning args for target-determining flags. -#[derive(Debug)] -pub(crate) struct DetectedTarget { - pub format: OutputFormat, - /// Architecture from `--target` triple. `None` if no `--target` was given. - pub arch: Option, -} - -/// Known `-m` emulation values that imply ELF output. -const ELF_EMULATIONS: &[&str] = &[ - "elf_x86_64", - "elf_x86_64_sol2", - "aarch64elf", - "aarch64linux", - "elf64lriscv", - "elf64loongarch", -]; - -/// Map `target_lexicon::Architecture` to Wild's `Architecture`. -fn map_triple_arch(arch: target_lexicon::Architecture) -> Result { - use target_lexicon::Architecture as TL; - match arch { - TL::X86_64 | TL::X86_64h => Ok(Architecture::X86_64), - TL::Aarch64(_) => Ok(Architecture::AArch64), - TL::Riscv64(_) => Ok(Architecture::RISCV64), - TL::LoongArch64 => Ok(Architecture::LoongArch64), - other => bail!("unsupported architecture in target triple: {other}"), - } -} - -/// Map `target_lexicon::BinaryFormat` to `OutputFormat`. -fn map_binary_format(fmt: target_lexicon::BinaryFormat) -> Result { - match fmt { - target_lexicon::BinaryFormat::Elf => Ok(OutputFormat::Elf), - target_lexicon::BinaryFormat::Coff => Ok(OutputFormat::Pe), - other => bail!("unsupported binary format: {other}"), - } -} - -/// Extract the target triple value from a flag, handling all prefix styles. -/// Returns `(Some(value), consumed_next)` if the arg is a target flag. -fn extract_target_value<'a>(arg: &'a str, next_arg: Option<&'a str>) -> (Option<&'a str>, bool) { - // Combined forms: --target=VAL, -target=VAL, /TARGET:VAL - if let Some(val) = arg - .strip_prefix("--target=") - .or_else(|| arg.strip_prefix("-target=")) - .or_else(|| arg.strip_prefix("/TARGET:")) - .or_else(|| arg.strip_prefix("/target:")) - { - return (Some(val), false); - } - // Space-separated: --target VAL, -target VAL, /TARGET VAL - if matches!(arg, "--target" | "-target" | "/TARGET" | "/target") { - if let Some(val) = next_arg { - return (Some(val), true); - } - } - (None, false) -} - -/// Pre-scan CLI arguments to determine the output format and architecture. -/// -/// Recognizes: -/// - `--target=` / `-target=` / `/TARGET:` — primary (parsed by target-lexicon) -/// - `-m ` — overrides format to ELF when present -/// -/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only. -pub(crate) fn detect_target(args: &[String]) -> Result { - let mut from_triple: Option<(OutputFormat, Architecture)> = None; - let mut m_implies_elf = false; - - let mut i = 0; - while i < args.len() { - let next = if i + 1 < args.len() { - Some(args[i + 1].as_str()) - } else { - None - }; - let (target_val, consumed_next) = extract_target_value(&args[i], next); - - if let Some(val) = target_val { - let triple: Triple = val - .parse() - .map_err(|e| anyhow::anyhow!("invalid target triple '{val}': {e}"))?; - let format = map_binary_format(triple.binary_format)?; - let arch = map_triple_arch(triple.architecture)?; - from_triple = Some((format, arch)); - if consumed_next { - i += 1; - } - } - // Check for -m (implies ELF) - else if args[i] == "-m" || args[i] == "--m" { - if let Some(next_val) = next { - if ELF_EMULATIONS.contains(&next_val) { - m_implies_elf = true; - } - i += 1; - } - } else if let Some(emu) = args[i].strip_prefix("-m") { - if ELF_EMULATIONS.contains(&emu) { - m_implies_elf = true; - } - } - - i += 1; - } - - match (from_triple, m_implies_elf) { - (Some((_, arch)), true) => { - // -m overrides format to ELF; arch from triple preserved - Ok(DetectedTarget { - format: OutputFormat::Elf, - arch: Some(arch), - }) - } - (Some((format, arch)), false) => Ok(DetectedTarget { - format, - arch: Some(arch), - }), - (None, true) => Ok(DetectedTarget { - format: OutputFormat::Elf, - arch: None, - }), - (None, false) => Ok(DetectedTarget { - format: OutputFormat::default(), - arch: None, - }), - } -} - -/// Map Wild `Architecture` to the GNU ld `-m` emulation name. -fn arch_to_elf_emulation(arch: Architecture) -> &'static str { - match arch { - Architecture::X86_64 => "elf_x86_64", - Architecture::AArch64 => "aarch64linux", - Architecture::RISCV64 => "elf64lriscv", - Architecture::LoongArch64 => "elf64loongarch", - } -} - -/// Map Wild `Architecture` to the MSVC `/MACHINE:` value. -fn arch_to_machine_value(arch: Architecture) -> &'static str { - match arch { - Architecture::X86_64 => "X64", - Architecture::AArch64 => "ARM64", - Architecture::RISCV64 => "X64", - Architecture::LoongArch64 => "X64", - } -} - -/// Strip `--target`/`-target`/`/TARGET` flags and inject a synthetic `-m` or `/MACHINE:` flag -/// from the detected architecture so the format-specific parser picks it up. -/// -/// The user's explicit `-m` or `/MACHINE:` flags are preserved and will override the injected one -/// since they appear later in the argument list. -pub(crate) fn filter_and_inject_target_flags( - args: &[String], - format: OutputFormat, - arch: Option, -) -> Vec { - let mut result = Vec::with_capacity(args.len() + 2); - - // Inject synthetic arch flag at the front (user's explicit flags override later) - if let Some(arch) = arch { - match format { - OutputFormat::Elf => { - result.push("-m".to_string()); - result.push(arch_to_elf_emulation(arch).to_string()); - } - OutputFormat::Pe => { - result.push(format!("/MACHINE:{}", arch_to_machine_value(arch))); - } - } - } - - // Strip --target flags, keep everything else - let mut i = 0; - while i < args.len() { - let arg = &args[i]; - if arg.starts_with("--target=") - || arg.starts_with("-target=") - || arg.starts_with("/TARGET:") - || arg.starts_with("/target:") - { - // Skip this combined arg - } else if matches!(arg.as_str(), "--target" | "-target" | "/TARGET" | "/target") { - i += 1; // skip value too - } else { - result.push(arg.clone()); - } - i += 1; - } - result -} - -/// Format-specific parsed arguments. -pub enum TargetArgs { - Elf(linux::ElfArgs), - #[allow(dead_code)] - Pe(windows::PeArgs), -} - -/// Parsed linker arguments. Common fields are directly accessible. -/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target_args`. -/// -/// `T` defaults to `TargetArgs` (the enum). During parsing, `T` is set to the -/// concrete format type (e.g. `ElfArgs` or `PeArgs`). -#[derive(Debug)] -pub struct Args { - // ── Infrastructure ─────────────────────────────────────────────────────── - pub should_fork: bool, - pub(crate) output: Arc, - pub(crate) arch: Architecture, - pub(crate) inputs: Vec, - pub(crate) lib_search_path: Vec>, - pub num_threads: Option, - pub(crate) available_threads: NonZeroUsize, - pub(crate) save_dir: SaveDir, - pub(crate) unrecognized_options: Vec, - pub(crate) files_per_group: Option, - pub(crate) write_layout: bool, - pub(crate) write_trace: bool, - pub(crate) jobserver_client: Option, - - // ── Core linker behavior ───────────────────────────────────────────────── - pub(crate) strip: Strip, - pub(crate) gc_sections: bool, - pub(crate) merge_sections: bool, - pub(crate) relax: bool, - pub(crate) demangle: bool, - pub(crate) no_undefined: bool, - pub(crate) allow_shlib_undefined: bool, - pub(crate) error_unresolved_symbols: bool, - pub(crate) allow_multiple_definitions: bool, - pub(crate) unresolved_symbols: UnresolvedSymbols, - pub(crate) undefined: Vec, - pub(crate) copy_relocations: CopyRelocations, - pub(crate) sysroot: Option>, - pub(crate) entry: Option, - pub(crate) wrap: Vec, - pub(crate) exclude_libs: ExcludeLibs, - pub(crate) defsym: Vec<(String, DefsymValue)>, - pub(crate) section_start: HashMap, - pub(crate) max_page_size: Option, - pub(crate) execstack: bool, - pub(crate) version_mode: VersionMode, - pub(crate) relocation_model: RelocationModel, - pub(crate) should_output_executable: bool, - pub(crate) export_all_dynamic_symbols: bool, - - // ── Output/writing ─────────────────────────────────────────────────────── - pub(crate) mmap_output_file: bool, - pub(crate) file_write_mode: Option, - pub(crate) prepopulate_maps: bool, - pub(crate) should_write_linker_identity: bool, - - // ── Debug/diagnostic ───────────────────────────────────────────────────── - pub(crate) debug_fuel: Option, - pub(crate) validate_output: bool, - pub(crate) sym_info: Option, - pub(crate) debug_address: Option, - pub(crate) print_allocations: Option, - pub(crate) verify_allocation_consistency: bool, - pub(crate) time_phase_options: Option>, - pub(crate) numeric_experiments: Vec>, - pub(crate) write_gc_stats: Option, - pub(crate) gc_stats_ignore: Vec, - pub(crate) verbose_gc_stats: bool, - pub(crate) dependency_file: Option, - - // ── Format-specific ────────────────────────────────────────────────────── - pub target_args: T, -} - -impl Default for Args { - fn default() -> Self { - Args { - // Infrastructure - should_fork: true, - arch: Architecture::DEFAULT, - unrecognized_options: Vec::new(), - lib_search_path: Vec::new(), - inputs: Vec::new(), - output: Arc::from(Path::new("a.out")), - num_threads: None, - write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), - write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), - files_per_group: None, - save_dir: Default::default(), - jobserver_client: None, - available_threads: NonZeroUsize::new(1).unwrap(), - // Core linker behavior - strip: Strip::Nothing, - gc_sections: true, - merge_sections: true, - relax: true, - demangle: true, - no_undefined: false, - allow_shlib_undefined: false, - error_unresolved_symbols: true, - allow_multiple_definitions: false, - unresolved_symbols: UnresolvedSymbols::ReportAll, - undefined: Vec::new(), - copy_relocations: CopyRelocations::Allowed, - sysroot: None, - entry: None, - wrap: Vec::new(), - exclude_libs: ExcludeLibs::None, - defsym: Vec::new(), - section_start: HashMap::new(), - max_page_size: None, - execstack: false, - version_mode: VersionMode::None, - relocation_model: RelocationModel::NonRelocatable, - should_output_executable: true, - export_all_dynamic_symbols: false, - // Output/writing - mmap_output_file: true, - file_write_mode: None, - prepopulate_maps: false, - should_write_linker_identity: true, - // Debug/diagnostic - debug_fuel: None, - validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), - sym_info: None, - debug_address: None, - print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") - .ok() - .and_then(|s| s.parse().ok()) - .map(FileId::from_encoded), - verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) - .is_ok_and(|v| v == "1"), - time_phase_options: None, - numeric_experiments: Vec::new(), - write_gc_stats: None, - gc_stats_ignore: Vec::new(), - verbose_gc_stats: false, - dependency_file: None, - // Format-specific - target_args: T::default(), - } - } -} - -impl std::ops::Deref for Args { - type Target = T; - fn deref(&self) -> &T { - &self.target_args - } -} - -impl std::ops::DerefMut for Args { - fn deref_mut(&mut self) -> &mut T { - &mut self.target_args - } -} - -impl Args { - /// Transform the target-specific part while preserving common fields. - pub fn map_target(self, f: impl FnOnce(T) -> U) -> Args { - Args { - // Infrastructure - should_fork: self.should_fork, - output: self.output, - arch: self.arch, - inputs: self.inputs, - lib_search_path: self.lib_search_path, - num_threads: self.num_threads, - available_threads: self.available_threads, - save_dir: self.save_dir, - unrecognized_options: self.unrecognized_options, - files_per_group: self.files_per_group, - write_layout: self.write_layout, - write_trace: self.write_trace, - jobserver_client: self.jobserver_client, - // Core linker behavior - strip: self.strip, - gc_sections: self.gc_sections, - merge_sections: self.merge_sections, - relax: self.relax, - demangle: self.demangle, - no_undefined: self.no_undefined, - allow_shlib_undefined: self.allow_shlib_undefined, - error_unresolved_symbols: self.error_unresolved_symbols, - allow_multiple_definitions: self.allow_multiple_definitions, - unresolved_symbols: self.unresolved_symbols, - undefined: self.undefined, - copy_relocations: self.copy_relocations, - sysroot: self.sysroot, - entry: self.entry, - wrap: self.wrap, - exclude_libs: self.exclude_libs, - defsym: self.defsym, - section_start: self.section_start, - max_page_size: self.max_page_size, - execstack: self.execstack, - version_mode: self.version_mode, - relocation_model: self.relocation_model, - should_output_executable: self.should_output_executable, - export_all_dynamic_symbols: self.export_all_dynamic_symbols, - // Output/writing - mmap_output_file: self.mmap_output_file, - file_write_mode: self.file_write_mode, - prepopulate_maps: self.prepopulate_maps, - should_write_linker_identity: self.should_write_linker_identity, - // Debug/diagnostic - debug_fuel: self.debug_fuel, - validate_output: self.validate_output, - sym_info: self.sym_info, - debug_address: self.debug_address, - print_allocations: self.print_allocations, - verify_allocation_consistency: self.verify_allocation_consistency, - time_phase_options: self.time_phase_options, - numeric_experiments: self.numeric_experiments, - write_gc_stats: self.write_gc_stats, - gc_stats_ignore: self.gc_stats_ignore, - verbose_gc_stats: self.verbose_gc_stats, - dependency_file: self.dependency_file, - // Format-specific - target_args: f(self.target_args), - } - } - - /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when - /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the - /// caller should take a different branch depending on whether the value is still positive. You - /// can then do a binary search. - pub(crate) fn use_debug_fuel(&self) -> i64 { - let Some(fuel) = self.debug_fuel.as_ref() else { - return i64::MAX; - }; - fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 - } - - /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls - /// `last_cb`. - #[allow(unused)] - pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { - match self.use_debug_fuel() { - 1.. => true, - 0 => { - last_cb(); - true - } - _ => false, - } - } - - pub(crate) fn trace_span_for_file( - &self, - file_id: FileId, - ) -> Option { - let should_trace = self.print_allocations == Some(file_id); - should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) - } - - pub fn should_fork(&self) -> bool { - self.should_fork - } - - pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { - self.numeric_experiments - .get(exp as usize) - .copied() - .flatten() - .unwrap_or(default) - } - - pub(crate) fn strip_all(&self) -> bool { - matches!(self.strip, Strip::All) - } - - pub(crate) fn strip_debug(&self) -> bool { - matches!(self.strip, Strip::All | Strip::Debug) - } -} - -/// Linker args with an activated thread pool. Holds jobserver tokens for the -/// duration of the link to keep the threads available. -pub struct ActivatedArgs { - pub args: Args, - _jobserver_tokens: Vec, -} - -impl ActivatedArgs { - pub fn map_target(self, f: impl FnOnce(T) -> U) -> ActivatedArgs { - ActivatedArgs { - args: self.args.map_target(f), - _jobserver_tokens: self._jobserver_tokens, - } - } -} - -impl Args { - /// Sets up the thread pool, using the explicit number of threads if specified, - /// or falling back to the jobserver protocol if available. - /// - /// - pub fn activate_thread_pool(mut self) -> Result> { - crate::timing_phase!("Activate thread pool"); - - let mut tokens = Vec::new(); - self.available_threads = self.num_threads.unwrap_or_else(|| { - if let Some(client) = &self.jobserver_client { - while let Ok(Some(acquired)) = client.try_acquire() { - tokens.push(acquired); - } - tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); - // Our parent "holds" one jobserver token, add it. - NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() - } else { - std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) - } - }); - - // The pool might be already initialized, suppress the error intentionally. - let _ = rayon::ThreadPoolBuilder::new() - .num_threads(self.available_threads.get()) - .build_global(); - - Ok(ActivatedArgs { - args: self, - _jobserver_tokens: tokens, - }) - } -} - -impl Args { - /// Parse CLI arguments. Detects target format from `--target=`, `-m`, - /// or host default, then routes to the format-specific parser. - pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { - let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); - let detected = detect_target(&all_args)?; - let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); - - match detected.format { - OutputFormat::Elf => { - let elf_args = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; - Ok(elf_args.map_target(TargetArgs::Elf)) - } - OutputFormat::Pe => { - let pe_args = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; - Ok(pe_args.map_target(TargetArgs::Pe)) - } - } - } -} - -/// Top-level parse function. -pub fn parse I, S: AsRef, I: Iterator>( - input: F, -) -> Result> { - Args::parse(input) -} - -#[cfg(test)] -mod tests { - use super::*; - - fn to_strings(args: &[&str]) -> Vec { - args.iter().map(|s| s.to_string()).collect() - } - - // ---- detect_target tests ---- - - #[test] - fn test_detect_format_from_triple_linux_x86() { - let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::X86_64)); - } - - #[test] - fn test_detect_format_from_triple_windows() { - let args = to_strings(&["-target=x86_64-pc-windows-msvc", "/OUT:foo.exe"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Pe); - assert_eq!(result.arch, Some(Architecture::X86_64)); - } - - #[test] - fn test_detect_format_from_slash_target() { - let args = to_strings(&["/TARGET:aarch64-pc-windows-msvc", "foo.obj"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Pe); - assert_eq!(result.arch, Some(Architecture::AArch64)); - } - - #[test] - fn test_detect_format_space_separated() { - let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::AArch64)); - } - - #[test] - fn test_detect_format_from_m_flag() { - let args = to_strings(&["-m", "elf_x86_64", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, None); - } - - #[test] - fn test_m_flag_overrides_target_format() { - let args = to_strings(&["--target=x86_64-pc-windows-msvc", "-m", "elf_x86_64"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - } - - #[test] - fn test_detect_format_default_no_flags() { - let args = to_strings(&["-o", "out", "foo.o"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::default()); - assert_eq!(result.arch, None); - } - - #[test] - fn test_detect_format_riscv_triple() { - let args = to_strings(&["--target=riscv64gc-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::RISCV64)); - } - - // ---- filter_and_inject_target_flags tests ---- - - #[test] - fn test_filter_strips_target_equals() { - let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "elf_x86_64"); - assert_eq!(filtered[2], "-o"); - assert!(!filtered.iter().any(|a| a.contains("--target"))); - } - - #[test] - fn test_filter_strips_target_space() { - let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "aarch64linux"); - assert!( - !filtered - .iter() - .any(|a| a == "--target" || a.contains("linux-gnu")) - ); - } - - #[test] - fn test_filter_strips_slash_target() { - let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "/MACHINE:X64"); - assert_eq!(filtered[1], "/OUT:foo.exe"); - } - - #[test] - fn test_filter_preserves_m_flag() { - let args = to_strings(&[ - "--target=x86_64-unknown-linux-gnu", - "-m", - "aarch64linux", - "-o", - "out", - ]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "elf_x86_64"); - assert!(filtered.contains(&"-m".to_string())); - assert!(filtered.contains(&"aarch64linux".to_string())); - } - - #[test] - fn test_filter_no_target_no_inject() { - let args = to_strings(&["-o", "out", "foo.o"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, None); - assert_eq!(filtered, args); - } -} +//! A handwritten parser for our arguments. +//! +//! We don't currently use a 3rd party library like clap for a few reasons. Firstly, we need to +//! support flags like `--push-state` and `--pop-state`. These need to push and pop a state stack +//! when they're parsed. Some of the other flags then need to manipulate the state of the top of the +//! stack. Positional arguments like input files and libraries to link, then need to have the +//! current state of the stack attached to that file. +//! +//! Secondly, long arguments need to also be accepted with a single '-' in addition to the more +//! common double-dash. +//! +//! Basically, we need to be able to parse arguments in the same way as the other linkers on the +//! platform that we're targeting. + +pub mod consts; +pub mod linux; +pub mod windows; + +use consts::*; + +use crate::alignment::Alignment; +use crate::arch::Architecture; +use crate::bail; +use crate::error::Context as _; +use crate::error::Result; +use crate::input_data::FileId; +use crate::save_dir::SaveDir; +use crate::target_os::Os; +use hashbrown::HashMap; +use hashbrown::HashSet; +use jobserver::Client; +use std::fmt::Display; +use std::num::NonZeroUsize; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::atomic::AtomicI64; +use target_lexicon::Triple; + +// ── Shared type definitions (format-agnostic) ──────────────────────────────── + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum VersionMode { + /// Don't print version + None, + /// Print version and continue linking (-v) + Verbose, + /// Print version and exit immediately (--version) + ExitAfterPrint, +} + +#[derive(Debug)] +pub(crate) enum DefsymValue { + /// A numeric value (address) + Value(u64), + /// Reference to another symbol with an optional offset + SymbolWithOffset(String, i64), +} + +#[derive(Debug)] +pub(crate) enum Strip { + Nothing, + Debug, + All, + Retain(HashSet>), +} + +#[derive(Debug, Clone, Copy)] +pub enum CounterKind { + Cycles, + Instructions, + CacheMisses, + BranchMisses, + PageFaults, + PageFaultsMinor, + PageFaultsMajor, + L1dRead, + L1dMiss, +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocations { + Allowed, + Disallowed(CopyRelocationsDisabledReason), +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocationsDisabledReason { + Flag, + SharedObject, +} + +impl Display for CopyRelocationsDisabledReason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let reason = match self { + CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", + CopyRelocationsDisabledReason::SharedObject => "output is a shared object", + }; + Display::fmt(&reason, f) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum RelocationModel { + NonRelocatable, + Relocatable, +} + +#[derive(Debug, Copy, Clone)] +pub(crate) enum Experiment { + /// How much parallelism to allow when splitting string-merge sections. + MergeStringSplitParallelism = 0, + + /// Number of bytes of string-merge sections before we'll break to a new group. + MergeStringMinGroupBytes = 1, + + GroupsPerThread = 2, + + MinGroups = 3, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum FileWriteMode { + /// The existing output file, if any, will be unlinked (deleted) and a new file with the same + /// name put in its place. Any hard links to the file will not be affected. + UnlinkAndReplace, + + /// The existing output file, if any, will be edited in-place. Any hard links to the file will + /// update accordingly. If the file is locked due to currently being executed, then our write + /// will fail. + UpdateInPlace, + + /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to + /// unlinking and replacing. + UpdateInPlaceWithFallback, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub(crate) enum BSymbolicKind { + None, + All, + Functions, + NonWeakFunctions, + NonWeak, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum UnresolvedSymbols { + /// Report all unresolved symbols. + ReportAll, + + /// Ignore unresolved symbols in shared libraries. + IgnoreInSharedLibs, + + /// Ignore unresolved symbols in object files. + IgnoreInObjectFiles, + + /// Ignore all unresolved symbols. + IgnoreAll, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum ExcludeLibs { + None, + All, + Some(HashSet>), +} + +impl ExcludeLibs { + pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { + match self { + ExcludeLibs::None => false, + ExcludeLibs::All => true, + ExcludeLibs::Some(libs) => { + let lib_path_str = String::from_utf8_lossy(lib_path); + let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); + + libs.contains(lib_name) + } + } + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub struct Modifiers { + /// Whether shared objects should only be linked if they're referenced. + pub(crate) as_needed: bool, + + /// Whether we're currently allowed to link against shared libraries. + pub(crate) allow_shared: bool, + + /// Whether object files in archives should be linked even if they do not contain symbols that + /// are referenced. + pub(crate) whole_archive: bool, + + /// Whether archive semantics should be applied even for regular objects. + pub(crate) archive_semantics: bool, + + /// Whether the file is known to be a temporary file that will be deleted when the linker + /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is + /// stored in the layout file if written so that linker-diff knows not to error if the file + /// is missing. + pub(crate) temporary: bool, +} + +impl Default for Modifiers { + fn default() -> Self { + Self { + as_needed: false, + allow_shared: true, + whole_archive: false, + archive_semantics: false, + temporary: false, + } + } +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) struct Input { + pub(crate) spec: InputSpec, + /// A directory to search first. Only present when the input came from a linker script, in + /// which case this is the directory containing the linker script. + pub(crate) search_first: Option, + pub(crate) modifiers: Modifiers, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum InputSpec { + /// Path (possibly just a filename) to the file. + File(Box), + /// Name of the library, without prefix and suffix. + Lib(Box), + /// Name of the library, including prefix and suffix. + Search(Box), +} + +// ── End shared type definitions ────────────────────────────────────────────── + +// ── Argument parser infrastructure ─────────────────────────────────────────── + +pub(crate) struct ArgumentParser { + options: HashMap<&'static str, OptionHandler>, + short_options: HashMap<&'static str, OptionHandler>, + prefix_options: HashMap<&'static str, PrefixOptionHandler>, + case_insensitive: bool, + has_option_prefix: fn(&str) -> bool, + strip_option: for<'a> fn(&'a str) -> Option<&'a str>, + find_separator: fn(&str) -> Option, +} + +struct OptionHandler { + help_text: &'static str, + handler: OptionHandlerFn, + short_names: Vec<&'static str>, +} + +impl Clone for OptionHandler { + fn clone(&self) -> Self { + Self { + help_text: self.help_text, + handler: self.handler, + short_names: self.short_names.clone(), + } + } +} + +struct PrefixOptionHandler { + help_text: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + sub_options: HashMap<&'static str, SubOption>, +} + +#[allow(clippy::enum_variant_names)] +enum OptionHandlerFn { + NoParam(fn(&mut Args, &mut Vec) -> Result<()>), + WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), + OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), +} + +impl Clone for OptionHandlerFn { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for OptionHandlerFn {} + +impl OptionHandlerFn { + fn help_suffix_long(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => "=", + OptionHandlerFn::OptionalParam(_) => "[=]", + } + } + + fn help_suffix_short(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => " ", + OptionHandlerFn::OptionalParam(_) => " []", + } + } +} + +pub(crate) struct OptionDeclaration<'a, T, S> { + parser: &'a mut ArgumentParser, + long_names: Vec<&'static str>, + short_names: Vec<&'static str>, + prefixes: Vec<&'static str>, + sub_options: HashMap<&'static str, SubOption>, + help_text: &'static str, + _phantom: std::marker::PhantomData, +} + +pub struct NoParam; +pub struct WithParam; +pub struct WithOptionalParam; + +enum SubOptionHandler { + /// Handler without value parameter (exact match) + NoValue(fn(&mut Args, &mut Vec) -> Result<()>), + /// Handler with value parameter (prefix match) + WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), +} + +impl Clone for SubOptionHandler { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOptionHandler {} + +struct SubOption { + help: &'static str, + handler: SubOptionHandler, +} + +impl Clone for SubOption { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOption {} + +impl SubOption { + fn with_value(&self) -> bool { + matches!(self.handler, SubOptionHandler::WithValue(_)) + } +} + +impl Default for ArgumentParser { + fn default() -> Self { + Self::new() + } +} + +impl ArgumentParser { + #[must_use] + pub fn new() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: false, + has_option_prefix: |arg| arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix("--").or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find('='), + } + } + + #[must_use] + pub fn new_case_insensitive() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: true, + has_option_prefix: |arg| arg.starts_with('/') || arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix('/').or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find(':'), + } + } + + pub fn declare(&mut self) -> OptionDeclaration<'_, T, NoParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, T, WithParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, T, WithOptionalParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { + if self.case_insensitive { + if let Some(handler) = self.options.get(option_name) { + return Some(handler); + } + for (key, handler) in &self.options { + if key.eq_ignore_ascii_case(option_name) { + return Some(handler); + } + } + None + } else { + self.options.get(option_name) + } + } + + pub(crate) fn handle_argument, I: Iterator>( + &self, + args: &mut Args, + modifier_stack: &mut Vec, + arg: &str, + input: &mut I, + ) -> Result<()> { + // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. + // Handle `@file`option (recursively) - merging in the options contained in the file + if let Some(path) = arg.strip_prefix('@') { + let file_args = read_args_from_file(Path::new(path))?; + let mut file_arg_iter = file_args.iter(); + while let Some(file_arg) = file_arg_iter.next() { + self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; + } + return Ok(()); + } + + if let Some(stripped) = (self.strip_option)(arg) { + // Check for option with separator syntax + if let Some(eq_pos) = (self.find_separator)(stripped) { + let option_name = &stripped[..eq_pos]; + let value = &stripped[eq_pos + 1..]; + + if let Some(handler) = self.get_option_handler(option_name) { + match &handler.handler { + OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, + OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, + OptionHandlerFn::NoParam(_) => return Ok(()), + } + return Ok(()); + } + } else { + if stripped == "build-id" + && let Some(handler) = self.get_option_handler(stripped) + && let OptionHandlerFn::WithParam(f) = &handler.handler + { + f(args, modifier_stack, "fast")?; + return Ok(()); + } + + if let Some(handler) = self.get_option_handler(stripped) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + } + + if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { + let option_name = &arg[1..]; + if let Some(handler) = self.short_options.get(option_name) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + + // Prefix options. These should be handled after processing long and short options, + // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. + for (prefix, handler) in &self.prefix_options { + if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { + let value = if rest.is_empty() { + let next_arg = input + .next() + .context(format!("Missing argument to -{prefix}"))?; + next_arg.as_ref().to_owned() + } else { + rest.to_owned() + }; + + if let Some((key, param_value)) = value.split_once('=') { + // Value has '=', look up key with trailing '=' + if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { + match sub.handler { + SubOptionHandler::NoValue(_) => { + (handler.handler)(args, modifier_stack, &value)?; + } + SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } else { + // No '=' in value, look up exact match + if let Some(sub) = handler.sub_options.get(value.as_str()) { + match sub.handler { + SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, + SubOptionHandler::WithValue(_) => { + bail!("Option -{prefix} {value} requires a value"); + } + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } + return Ok(()); + } + } + + if (self.has_option_prefix)(arg) { + if let Some(stripped) = (self.strip_option)(arg) + && IGNORED_FLAGS.contains(&stripped) + { + warn_unsupported(arg)?; + return Ok(()); + } + + args.unrecognized_options.push(arg.to_owned()); + return Ok(()); + } + + args.save_dir.handle_file(arg); + args.inputs.push(Input { + spec: InputSpec::File(Box::from(Path::new(arg))), + search_first: None, + modifiers: *modifier_stack.last().unwrap(), + }); + + Ok(()) + } + + #[must_use] + fn generate_help(&self) -> String { + let mut help = String::new(); + help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); + + let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); + prefix_options.sort_by_key(|(prefix, _)| *prefix); + + // TODO: This is ad-hoc + help.push_str(&format!( + " {:<31} Read options from a file\n", + format!("@"), + )); + + let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); + let mut processed_short_options: HashSet<&str> = HashSet::new(); + + // Collect all long options and their associated short options + for (long_name, handler) in &self.options { + if !handler.help_text.is_empty() { + let long_suffix = handler.handler.help_suffix_long(); + let mut option_names = vec![format!("--{long_name}{long_suffix}")]; + + // Add associated short options + let short_suffix = handler.handler.help_suffix_short(); + for short_char in &handler.short_names { + option_names.push(format!("-{short_char}{short_suffix}")); + } + + help_to_options + .entry(handler.help_text) + .or_default() + .extend(option_names); + } + + // Mark short options of help-less handlers as processed + for short_name in &handler.short_names { + processed_short_options.insert(short_name); + } + } + + for (prefix, handler) in prefix_options { + if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { + help.push_str(&format!( + " -{:<30} {}\n", + format!("{prefix} "), + handler.help_text + )); + + // Add sub-options if they exist + let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); + sub_options.sort_by_key(|(name, _)| *name); + + for (sub_name, sub) in sub_options { + let display_name = if sub.with_value() && sub_name.ends_with('=') { + // sub_name ends with '=' (e.g., "max-page-size="), so add + format!("{sub_name}") + } else { + sub_name.to_string() + }; + help.push_str(&format!( + " -{prefix} {display_name:<30} {sub_help}\n", + sub_help = sub.help + )); + } + } + } + + // Add short-only options + for (short_char, handler) in &self.short_options { + if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { + let short_suffix = handler.handler.help_suffix_short(); + help_to_options + .entry(handler.help_text) + .or_default() + .push(format!("-{short_char}{short_suffix}")); + } + } + + let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); + sorted_help_groups.sort_by_key(|(_, option_names)| { + option_names.iter().min().unwrap_or(&String::new()).clone() + }); + + for (help_text, mut option_names) in sorted_help_groups { + option_names.sort_by(|a, b| { + let a_is_short = a.len() == 2 && a.starts_with('-'); + let b_is_short = b.len() == 2 && b.starts_with('-'); + match (a_is_short, b_is_short) { + (true, false) => std::cmp::Ordering::Less, // short options first + (false, true) => std::cmp::Ordering::Greater, // long options after + _ => a.cmp(b), // same type, alphabetical + } + }); + + let option_names_str = option_names.join(", "); + help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); + } + + help + } +} + +impl<'a, T, S> OptionDeclaration<'a, T, S> { + #[must_use] + pub fn long(mut self, name: &'static str) -> Self { + self.long_names.push(name); + self + } + + #[must_use] + pub fn short(mut self, option: &'static str) -> Self { + self.short_names.push(option); + self + } + + #[must_use] + pub fn help(mut self, text: &'static str) -> Self { + self.help_text = text; + self + } + + pub fn prefix(mut self, prefix: &'static str) -> Self { + self.prefixes.push(prefix); + self + } + + #[must_use] + pub fn sub_option( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::NoValue(handler), + }, + ); + self + } + + #[must_use] + pub fn sub_option_with_value( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::WithValue(handler), + }, + ); + self + } +} + +impl<'a, T> OptionDeclaration<'a, T, NoParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::NoParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { + let mut short_names = self.short_names.clone(); + short_names.extend_from_slice(&self.prefixes); + + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::WithParam(handler), + short_names, + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + + for prefix in self.prefixes { + let prefix_handler = PrefixOptionHandler { + help_text: self.help_text, + sub_options: self.sub_options.clone(), + handler, + }; + + self.parser.prefix_options.insert(prefix, prefix_handler); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithOptionalParam> { + pub fn execute( + self, + handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>, + ) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::OptionalParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +// ── End argument parser infrastructure ─────────────────────────────────────── + +pub(crate) fn add_silently_ignored_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in SILENTLY_IGNORED_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in SILENTLY_IGNORED_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +pub(crate) fn add_default_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in DEFAULT_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in DEFAULT_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +pub(crate) fn read_args_from_file(path: &Path) -> Result> { + let contents = std::fs::read_to_string(path) + .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; + arguments_from_string(&contents) +} + +/// Parses arguments from a string, handling quoting, escapes etc. +/// All arguments must be surrounded by a white space. +pub(crate) fn arguments_from_string(input: &str) -> Result> { + const QUOTES: [char; 2] = ['\'', '"']; + + let mut out = Vec::new(); + let mut chars = input.chars(); + let mut heap = None; + let mut quote = None; + let mut expect_whitespace = false; + + loop { + let Some(mut ch) = chars.next() else { + if let Some(quote) = quote.take() { + bail!("Missing closing '{quote}'"); + } + if let Some(arg) = heap.take() { + out.push(arg); + } + break; + }; + + crate::ensure!( + !expect_whitespace || ch.is_whitespace(), + "Expected white space after quoted argument" + ); + expect_whitespace = false; + + if QUOTES.contains(&ch) { + if let Some(qchr) = quote { + if qchr == ch { + // close the argument + if let Some(arg) = heap.take() { + out.push(arg); + } + quote = None; + expect_whitespace = true; + } else { + // accept the other quoting character as normal char + heap.get_or_insert(String::new()).push(ch); + } + } else { + // beginning of a new argument + crate::ensure!(heap.is_none(), "Missing opening quote '{ch}'"); + quote = Some(ch); + } + } else if ch.is_whitespace() { + if quote.is_none() { + if let Some(arg) = heap.take() { + out.push(arg); + } + } else { + heap.get_or_insert(String::new()).push(ch); + } + } else { + if ch == '\\' && (quote.is_some() || !cfg!(target_os = "windows")) { + ch = chars.next().context("Invalid escape")?; + } + heap.get_or_insert(String::new()).push(ch); + } + } + + Ok(out) +} + +pub(super) fn warn_unsupported(opt: &str) -> Result { + match std::env::var(WILD_UNSUPPORTED_ENV) + .unwrap_or_default() + .as_str() + { + "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), + "ignore" => {} + "error" => bail!("{opt} is not yet supported"), + other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), + } + Ok(()) +} + +/// The output binary format. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum OutputFormat { + Elf, + Pe, +} + +impl Default for OutputFormat { + fn default() -> Self { + match Os::DEFAULT { + Os::Linux => OutputFormat::Elf, + Os::Windows => OutputFormat::Pe, + Os::MacOS => todo!("macOS linking not yet supported"), + } + } +} + +/// Result of pre-scanning args for target-determining flags. +#[derive(Debug)] +pub(crate) struct DetectedTarget { + pub format: OutputFormat, + /// Architecture from `--target` triple. `None` if no `--target` was given. + pub arch: Option, +} + +/// Known `-m` emulation values that imply ELF output. +const ELF_EMULATIONS: &[&str] = &[ + "elf_x86_64", + "elf_x86_64_sol2", + "aarch64elf", + "aarch64linux", + "elf64lriscv", + "elf64loongarch", +]; + +/// Map `target_lexicon::Architecture` to Wild's `Architecture`. +fn map_triple_arch(arch: target_lexicon::Architecture) -> Result { + use target_lexicon::Architecture as TL; + match arch { + TL::X86_64 | TL::X86_64h => Ok(Architecture::X86_64), + TL::Aarch64(_) => Ok(Architecture::AArch64), + TL::Riscv64(_) => Ok(Architecture::RISCV64), + TL::LoongArch64 => Ok(Architecture::LoongArch64), + other => bail!("unsupported architecture in target triple: {other}"), + } +} + +/// Map `target_lexicon::BinaryFormat` to `OutputFormat`. +fn map_binary_format(fmt: target_lexicon::BinaryFormat) -> Result { + match fmt { + target_lexicon::BinaryFormat::Elf => Ok(OutputFormat::Elf), + target_lexicon::BinaryFormat::Coff => Ok(OutputFormat::Pe), + other => bail!("unsupported binary format: {other}"), + } +} + +/// Extract the target triple value from a flag, handling all prefix styles. +/// Returns `(Some(value), consumed_next)` if the arg is a target flag. +fn extract_target_value<'a>(arg: &'a str, next_arg: Option<&'a str>) -> (Option<&'a str>, bool) { + // Combined forms: --target=VAL, -target=VAL, /TARGET:VAL + if let Some(val) = arg + .strip_prefix("--target=") + .or_else(|| arg.strip_prefix("-target=")) + .or_else(|| arg.strip_prefix("/TARGET:")) + .or_else(|| arg.strip_prefix("/target:")) + { + return (Some(val), false); + } + // Space-separated: --target VAL, -target VAL, /TARGET VAL + if matches!(arg, "--target" | "-target" | "/TARGET" | "/target") { + if let Some(val) = next_arg { + return (Some(val), true); + } + } + (None, false) +} + +/// Pre-scan CLI arguments to determine the output format and architecture. +/// +/// Recognizes: +/// - `--target=` / `-target=` / `/TARGET:` — primary (parsed by target-lexicon) +/// - `-m ` — overrides format to ELF when present +/// +/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only. +pub(crate) fn detect_target(args: &[String]) -> Result { + let mut from_triple: Option<(OutputFormat, Architecture)> = None; + let mut m_implies_elf = false; + + let mut i = 0; + while i < args.len() { + let next = if i + 1 < args.len() { + Some(args[i + 1].as_str()) + } else { + None + }; + let (target_val, consumed_next) = extract_target_value(&args[i], next); + + if let Some(val) = target_val { + let triple: Triple = val + .parse() + .map_err(|e| anyhow::anyhow!("invalid target triple '{val}': {e}"))?; + let format = map_binary_format(triple.binary_format)?; + let arch = map_triple_arch(triple.architecture)?; + from_triple = Some((format, arch)); + if consumed_next { + i += 1; + } + } + // Check for -m (implies ELF) + else if args[i] == "-m" || args[i] == "--m" { + if let Some(next_val) = next { + if ELF_EMULATIONS.contains(&next_val) { + m_implies_elf = true; + } + i += 1; + } + } else if let Some(emu) = args[i].strip_prefix("-m") { + if ELF_EMULATIONS.contains(&emu) { + m_implies_elf = true; + } + } + + i += 1; + } + + match (from_triple, m_implies_elf) { + (Some((_, arch)), true) => { + // -m overrides format to ELF; arch from triple preserved + Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: Some(arch), + }) + } + (Some((format, arch)), false) => Ok(DetectedTarget { + format, + arch: Some(arch), + }), + (None, true) => Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: None, + }), + (None, false) => Ok(DetectedTarget { + format: OutputFormat::default(), + arch: None, + }), + } +} + +/// Map Wild `Architecture` to the GNU ld `-m` emulation name. +fn arch_to_elf_emulation(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "elf_x86_64", + Architecture::AArch64 => "aarch64linux", + Architecture::RISCV64 => "elf64lriscv", + Architecture::LoongArch64 => "elf64loongarch", + } +} + +/// Map Wild `Architecture` to the MSVC `/MACHINE:` value. +fn arch_to_machine_value(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "X64", + Architecture::AArch64 => "ARM64", + Architecture::RISCV64 => "X64", + Architecture::LoongArch64 => "X64", + } +} + +/// Strip `--target`/`-target`/`/TARGET` flags and inject a synthetic `-m` or `/MACHINE:` flag +/// from the detected architecture so the format-specific parser picks it up. +/// +/// The user's explicit `-m` or `/MACHINE:` flags are preserved and will override the injected one +/// since they appear later in the argument list. +pub(crate) fn filter_and_inject_target_flags( + args: &[String], + format: OutputFormat, + arch: Option, +) -> Vec { + let mut result = Vec::with_capacity(args.len() + 2); + + // Inject synthetic arch flag at the front (user's explicit flags override later) + if let Some(arch) = arch { + match format { + OutputFormat::Elf => { + result.push("-m".to_string()); + result.push(arch_to_elf_emulation(arch).to_string()); + } + OutputFormat::Pe => { + result.push(format!("/MACHINE:{}", arch_to_machine_value(arch))); + } + } + } + + // Strip --target flags, keep everything else + let mut i = 0; + while i < args.len() { + let arg = &args[i]; + if arg.starts_with("--target=") + || arg.starts_with("-target=") + || arg.starts_with("/TARGET:") + || arg.starts_with("/target:") + { + // Skip this combined arg + } else if matches!(arg.as_str(), "--target" | "-target" | "/TARGET" | "/target") { + i += 1; // skip value too + } else { + result.push(arg.clone()); + } + i += 1; + } + result +} + +/// Format-specific parsed arguments. +pub enum TargetArgs { + Elf(linux::ElfArgs), + #[allow(dead_code)] + Pe(windows::PeArgs), +} + +/// Parsed linker arguments. Common fields are directly accessible. +/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target_args`. +/// +/// `T` defaults to `TargetArgs` (the enum). During parsing, `T` is set to the +/// concrete format type (e.g. `ElfArgs` or `PeArgs`). +#[derive(Debug)] +pub struct Args { + // ── Infrastructure ─────────────────────────────────────────────────────── + pub should_fork: bool, + pub(crate) output: Arc, + pub(crate) arch: Architecture, + pub(crate) inputs: Vec, + pub(crate) lib_search_path: Vec>, + pub num_threads: Option, + pub(crate) available_threads: NonZeroUsize, + pub(crate) save_dir: SaveDir, + pub(crate) unrecognized_options: Vec, + pub(crate) files_per_group: Option, + pub(crate) write_layout: bool, + pub(crate) write_trace: bool, + pub(crate) jobserver_client: Option, + + // ── Core linker behavior ───────────────────────────────────────────────── + pub(crate) strip: Strip, + pub(crate) gc_sections: bool, + pub(crate) merge_sections: bool, + pub(crate) relax: bool, + pub(crate) demangle: bool, + pub(crate) no_undefined: bool, + pub(crate) allow_shlib_undefined: bool, + pub(crate) error_unresolved_symbols: bool, + pub(crate) allow_multiple_definitions: bool, + pub(crate) unresolved_symbols: UnresolvedSymbols, + pub(crate) undefined: Vec, + pub(crate) copy_relocations: CopyRelocations, + pub(crate) sysroot: Option>, + pub(crate) dynamic_linker: Option>, + pub(crate) entry: Option, + pub(crate) wrap: Vec, + pub(crate) exclude_libs: ExcludeLibs, + pub(crate) b_symbolic: BSymbolicKind, + pub(crate) export_list: Vec, + pub(crate) defsym: Vec<(String, DefsymValue)>, + pub(crate) section_start: HashMap, + pub(crate) max_page_size: Option, + pub(crate) execstack: bool, + pub(crate) version_mode: VersionMode, + pub(crate) relocation_model: RelocationModel, + pub(crate) should_output_executable: bool, + pub(crate) export_all_dynamic_symbols: bool, + + // ── Output/writing ─────────────────────────────────────────────────────── + pub(crate) mmap_output_file: bool, + pub(crate) file_write_mode: Option, + pub(crate) prepopulate_maps: bool, + pub(crate) should_write_linker_identity: bool, + + // ── Debug/diagnostic ───────────────────────────────────────────────────── + pub(crate) debug_fuel: Option, + pub(crate) validate_output: bool, + pub(crate) sym_info: Option, + pub(crate) debug_address: Option, + pub(crate) print_allocations: Option, + pub(crate) verify_allocation_consistency: bool, + pub(crate) time_phase_options: Option>, + pub(crate) numeric_experiments: Vec>, + pub(crate) write_gc_stats: Option, + pub(crate) gc_stats_ignore: Vec, + pub(crate) verbose_gc_stats: bool, + pub(crate) dependency_file: Option, + + // ── Format-specific ────────────────────────────────────────────────────── + pub target_args: T, +} + +impl Default for Args { + fn default() -> Self { + Args { + // Infrastructure + should_fork: true, + arch: Architecture::DEFAULT, + unrecognized_options: Vec::new(), + lib_search_path: Vec::new(), + inputs: Vec::new(), + output: Arc::from(Path::new("a.out")), + num_threads: None, + write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), + write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), + files_per_group: None, + save_dir: Default::default(), + jobserver_client: None, + available_threads: NonZeroUsize::new(1).unwrap(), + // Core linker behavior + strip: Strip::Nothing, + gc_sections: true, + merge_sections: true, + relax: true, + demangle: true, + no_undefined: false, + allow_shlib_undefined: false, + error_unresolved_symbols: true, + allow_multiple_definitions: false, + unresolved_symbols: UnresolvedSymbols::ReportAll, + undefined: Vec::new(), + copy_relocations: CopyRelocations::Allowed, + sysroot: None, + dynamic_linker: None, + entry: None, + wrap: Vec::new(), + exclude_libs: ExcludeLibs::None, + b_symbolic: BSymbolicKind::None, + export_list: Vec::new(), + defsym: Vec::new(), + section_start: HashMap::new(), + max_page_size: None, + execstack: false, + version_mode: VersionMode::None, + relocation_model: RelocationModel::NonRelocatable, + should_output_executable: true, + export_all_dynamic_symbols: false, + // Output/writing + mmap_output_file: true, + file_write_mode: None, + prepopulate_maps: false, + should_write_linker_identity: true, + // Debug/diagnostic + debug_fuel: None, + validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), + sym_info: None, + debug_address: None, + print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") + .ok() + .and_then(|s| s.parse().ok()) + .map(FileId::from_encoded), + verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) + .is_ok_and(|v| v == "1"), + time_phase_options: None, + numeric_experiments: Vec::new(), + write_gc_stats: None, + gc_stats_ignore: Vec::new(), + verbose_gc_stats: false, + dependency_file: None, + // Format-specific + target_args: T::default(), + } + } +} + +impl std::ops::Deref for Args { + type Target = T; + fn deref(&self) -> &T { + &self.target_args + } +} + +impl std::ops::DerefMut for Args { + fn deref_mut(&mut self) -> &mut T { + &mut self.target_args + } +} + +impl Args { + /// Transform the target-specific part while preserving common fields. + pub fn map_target(self, f: impl FnOnce(T) -> U) -> Args { + Args { + // Infrastructure + should_fork: self.should_fork, + output: self.output, + arch: self.arch, + inputs: self.inputs, + lib_search_path: self.lib_search_path, + num_threads: self.num_threads, + available_threads: self.available_threads, + save_dir: self.save_dir, + unrecognized_options: self.unrecognized_options, + files_per_group: self.files_per_group, + write_layout: self.write_layout, + write_trace: self.write_trace, + jobserver_client: self.jobserver_client, + // Core linker behavior + strip: self.strip, + gc_sections: self.gc_sections, + merge_sections: self.merge_sections, + relax: self.relax, + demangle: self.demangle, + no_undefined: self.no_undefined, + allow_shlib_undefined: self.allow_shlib_undefined, + error_unresolved_symbols: self.error_unresolved_symbols, + allow_multiple_definitions: self.allow_multiple_definitions, + unresolved_symbols: self.unresolved_symbols, + undefined: self.undefined, + copy_relocations: self.copy_relocations, + sysroot: self.sysroot, + dynamic_linker: self.dynamic_linker, + entry: self.entry, + wrap: self.wrap, + exclude_libs: self.exclude_libs, + b_symbolic: self.b_symbolic, + export_list: self.export_list, + defsym: self.defsym, + section_start: self.section_start, + max_page_size: self.max_page_size, + execstack: self.execstack, + version_mode: self.version_mode, + relocation_model: self.relocation_model, + should_output_executable: self.should_output_executable, + export_all_dynamic_symbols: self.export_all_dynamic_symbols, + // Output/writing + mmap_output_file: self.mmap_output_file, + file_write_mode: self.file_write_mode, + prepopulate_maps: self.prepopulate_maps, + should_write_linker_identity: self.should_write_linker_identity, + // Debug/diagnostic + debug_fuel: self.debug_fuel, + validate_output: self.validate_output, + sym_info: self.sym_info, + debug_address: self.debug_address, + print_allocations: self.print_allocations, + verify_allocation_consistency: self.verify_allocation_consistency, + time_phase_options: self.time_phase_options, + numeric_experiments: self.numeric_experiments, + write_gc_stats: self.write_gc_stats, + gc_stats_ignore: self.gc_stats_ignore, + verbose_gc_stats: self.verbose_gc_stats, + dependency_file: self.dependency_file, + // Format-specific + target_args: f(self.target_args), + } + } + + /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when + /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the + /// caller should take a different branch depending on whether the value is still positive. You + /// can then do a binary search. + pub(crate) fn use_debug_fuel(&self) -> i64 { + let Some(fuel) = self.debug_fuel.as_ref() else { + return i64::MAX; + }; + fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 + } + + /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls + /// `last_cb`. + #[allow(unused)] + pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { + match self.use_debug_fuel() { + 1.. => true, + 0 => { + last_cb(); + true + } + _ => false, + } + } + + pub(crate) fn trace_span_for_file( + &self, + file_id: FileId, + ) -> Option { + let should_trace = self.print_allocations == Some(file_id); + should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) + } + + pub fn should_fork(&self) -> bool { + self.should_fork + } + + pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { + self.numeric_experiments + .get(exp as usize) + .copied() + .flatten() + .unwrap_or(default) + } + + pub(crate) fn strip_all(&self) -> bool { + matches!(self.strip, Strip::All) + } + + pub(crate) fn strip_debug(&self) -> bool { + matches!(self.strip, Strip::All | Strip::Debug) + } +} + +impl Args { + pub(crate) fn is_elf(&self) -> bool { + std::any::TypeId::of::() == std::any::TypeId::of::() + } + + pub(crate) fn is_pe(&self) -> bool { + std::any::TypeId::of::() == std::any::TypeId::of::() + } +} + +/// Linker args with an activated thread pool. Holds jobserver tokens for the +/// duration of the link to keep the threads available. +pub struct ActivatedArgs { + pub args: Args, + _jobserver_tokens: Vec, +} + +impl ActivatedArgs { + pub fn map_target(self, f: impl FnOnce(T) -> U) -> ActivatedArgs { + ActivatedArgs { + args: self.args.map_target(f), + _jobserver_tokens: self._jobserver_tokens, + } + } +} + +impl Args { + /// Sets up the thread pool, using the explicit number of threads if specified, + /// or falling back to the jobserver protocol if available. + /// + /// + pub fn activate_thread_pool(mut self) -> Result> { + crate::timing_phase!("Activate thread pool"); + + let mut tokens = Vec::new(); + self.available_threads = self.num_threads.unwrap_or_else(|| { + if let Some(client) = &self.jobserver_client { + while let Ok(Some(acquired)) = client.try_acquire() { + tokens.push(acquired); + } + tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); + // Our parent "holds" one jobserver token, add it. + NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() + } else { + std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) + } + }); + + // The pool might be already initialized, suppress the error intentionally. + let _ = rayon::ThreadPoolBuilder::new() + .num_threads(self.available_threads.get()) + .build_global(); + + Ok(ActivatedArgs { + args: self, + _jobserver_tokens: tokens, + }) + } +} + +impl Args { + /// Parse CLI arguments. Detects target format from `--target=`, `-m`, + /// or host default, then routes to the format-specific parser. + pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { + let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); + let detected = detect_target(&all_args)?; + let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); + + match detected.format { + OutputFormat::Elf => { + let elf_args = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(elf_args.map_target(TargetArgs::Elf)) + } + OutputFormat::Pe => { + let pe_args = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(pe_args.map_target(TargetArgs::Pe)) + } + } + } +} + +/// Top-level parse function. +pub fn parse I, S: AsRef, I: Iterator>( + input: F, +) -> Result> { + Args::parse(input) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn to_strings(args: &[&str]) -> Vec { + args.iter().map(|s| s.to_string()).collect() + } + + // ---- detect_target tests ---- + + #[test] + fn test_detect_format_from_triple_linux_x86() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_triple_windows() { + let args = to_strings(&["-target=x86_64-pc-windows-msvc", "/OUT:foo.exe"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_slash_target() { + let args = to_strings(&["/TARGET:aarch64-pc-windows-msvc", "foo.obj"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_space_separated() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_from_m_flag() { + let args = to_strings(&["-m", "elf_x86_64", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, None); + } + + #[test] + fn test_m_flag_overrides_target_format() { + let args = to_strings(&["--target=x86_64-pc-windows-msvc", "-m", "elf_x86_64"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + } + + #[test] + fn test_detect_format_default_no_flags() { + let args = to_strings(&["-o", "out", "foo.o"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::default()); + assert_eq!(result.arch, None); + } + + #[test] + fn test_detect_format_riscv_triple() { + let args = to_strings(&["--target=riscv64gc-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::RISCV64)); + } + + // ---- filter_and_inject_target_flags tests ---- + + #[test] + fn test_filter_strips_target_equals() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert_eq!(filtered[2], "-o"); + assert!(!filtered.iter().any(|a| a.contains("--target"))); + } + + #[test] + fn test_filter_strips_target_space() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "aarch64linux"); + assert!( + !filtered + .iter() + .any(|a| a == "--target" || a.contains("linux-gnu")) + ); + } + + #[test] + fn test_filter_strips_slash_target() { + let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "/MACHINE:X64"); + assert_eq!(filtered[1], "/OUT:foo.exe"); + } + + #[test] + fn test_filter_preserves_m_flag() { + let args = to_strings(&[ + "--target=x86_64-unknown-linux-gnu", + "-m", + "aarch64linux", + "-o", + "out", + ]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert!(filtered.contains(&"-m".to_string())); + assert!(filtered.contains(&"aarch64linux".to_string())); + } + + #[test] + fn test_filter_no_target_no_inject() { + let args = to_strings(&["-o", "out", "foo.o"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, None); + assert_eq!(filtered, args); + } +} diff --git a/libwild/src/args/windows.rs b/libwild/src/args/windows.rs index 819868ac8..b2c487c30 100644 --- a/libwild/src/args/windows.rs +++ b/libwild/src/args/windows.rs @@ -10,7 +10,6 @@ use crate::arch::Architecture; use crate::bail; use crate::ensure; use crate::error::Result; -use crate::output_kind::OutputKind; use crate::save_dir::SaveDir; use jobserver::Client; use std::num::NonZeroUsize; @@ -85,14 +84,6 @@ impl Default for PeArgs { impl super::Args { - pub fn output_kind(&self) -> OutputKind { - if !self.should_output_executable { - OutputKind::SharedObject - } else { - OutputKind::StaticExecutable(self.relocation_model) - } - } - /// Check if a specific library should be ignored due to /NODEFAULTLIB pub fn should_ignore_default_lib(&self, lib_name: &str) -> bool { self.ignore_all_default_libs || self.no_default_libs.contains(&lib_name.to_string()) diff --git a/libwild/src/coff.rs b/libwild/src/coff.rs index 023e03905..8a09fb1dd 100644 --- a/libwild/src/coff.rs +++ b/libwild/src/coff.rs @@ -29,6 +29,14 @@ use object::read::coff::ImageSymbol; use rayon::Scope; use std::borrow::Cow; +// ── PE architecture marker types ──────────────────────────────────────────── + +/// Marker type for PE/COFF linking targeting x86_64. +pub(crate) struct CoffX86_64; + +/// Marker type for PE/COFF linking targeting AArch64. +pub(crate) struct CoffAArch64; + // ── Core COFF object file type ────────────────────────────────────────────── /// A parsed COFF object file that implements the `ObjectFile` trait. diff --git a/libwild/src/file_writer.rs b/libwild/src/file_writer.rs index 2063c045a..b68e72462 100644 --- a/libwild/src/file_writer.rs +++ b/libwild/src/file_writer.rs @@ -1,6 +1,5 @@ use crate::OutputKind; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::args::FileWriteMode; use crate::args::consts::WRITE_VERIFY_ALLOCATIONS_ENV; use crate::error; @@ -111,7 +110,7 @@ struct SectionAllocation { } impl Output { - pub(crate) fn new(args: &Args, output_kind: OutputKind) -> Output { + pub(crate) fn new(args: &Args, output_kind: OutputKind) -> Output { let file_write_mode = args .file_write_mode .unwrap_or_else(|| default_file_write_mode(args, output_kind)); @@ -231,7 +230,7 @@ impl Output { } /// Returns the file write mode that we should use to write to the specified path. -fn default_file_write_mode(args: &Args, output_kind: OutputKind) -> FileWriteMode { +fn default_file_write_mode(args: &Args, output_kind: OutputKind) -> FileWriteMode { if output_kind.is_shared_object() { return FileWriteMode::UnlinkAndReplace; } diff --git a/libwild/src/grouping.rs b/libwild/src/grouping.rs index 8641e5af0..c62d16ce3 100644 --- a/libwild/src/grouping.rs +++ b/libwild/src/grouping.rs @@ -1,5 +1,4 @@ use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::error::Result; use crate::input_data::FileId; use crate::input_data::MAX_FILES_PER_GROUP; @@ -190,7 +189,7 @@ pub(crate) fn create_groups<'data, O: ObjectFile<'data>>( } /// Decides after how many symbols, we should start a new group. -fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usize { +fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usize { let num_threads = args.available_threads.get(); // If we're running with a single thread, then we might as well put everything into a single @@ -214,7 +213,7 @@ fn determine_symbols_per_group(num_symbols: usize, args: &Args) -> usiz } /// Decides the maximum number of files that we'll put into one group. -fn determine_max_files_per_group(args: &Args) -> usize { +fn determine_max_files_per_group(args: &Args) -> usize { if let Some(v) = args.files_per_group { return v as usize; } diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index 4bc5d93ff..c973fafd3 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -206,6 +206,15 @@ pub(crate) struct AuxiliaryFiles<'data> { } impl<'data> AuxiliaryFiles<'data> { + // TODO: When .def file parsing is added, make `new` generic and load .def export lists into + // `export_list_data` so the PE path can use the shared export list pipeline. + pub(crate) fn empty() -> Self { + Self { + version_script_data: None, + export_list_data: None, + } + } + pub(crate) fn new(args: &'data Args, inputs_arena: &'data Arena) -> Result { let resolve_script_path = |path: &Path| -> PathBuf { if path.exists() { diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs index 67af1cdec..ee85ebf60 100644 --- a/libwild/src/layout.rs +++ b/libwild/src/layout.rs @@ -4991,7 +4991,7 @@ type RescanCandidates = Vec>>; /// Run one pass of the relaxation scan across all groups/objects. Returns the total number of /// bytes newly deleted in this pass together with the set of sections that should be rescanned on /// the next iteration. -fn relaxation_scan_pass<'data, P: Platform<'data>>( +fn relaxation_scan_pass<'data, P: Platform<'data, File = crate::elf::File<'data>>>( group_states: &mut [GroupState<'data>], section_part_layouts: &OutputSectionPartMap, symbol_db: &SymbolDb<'data, P::File>, @@ -5144,7 +5144,7 @@ fn relaxation_scan_pass<'data, P: Platform<'data>>( (total_deleted, next_rescan_candidates) } -fn perform_iterative_relaxation<'data, P: Platform<'data>>( +fn perform_iterative_relaxation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( group_states: &mut [GroupState<'data>], section_part_sizes: &mut OutputSectionPartMap, section_part_layouts: &mut OutputSectionPartMap, diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index dc885e20b..b02dcafa4 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -1,427 +1,560 @@ -pub(crate) mod alignment; -pub(crate) mod arch; -pub(crate) mod archive; -pub mod args; -pub(crate) mod coff; -pub(crate) mod debug_trace; -pub(crate) mod diagnostics; -pub(crate) mod diff; -pub(crate) mod dwarf_address_info; -pub(crate) mod elf; -pub(crate) mod elf_aarch64; -pub(crate) mod elf_loongarch64; -pub(crate) mod elf_riscv64; -pub(crate) mod elf_writer; -pub(crate) mod elf_x86_64; -pub mod error; -pub(crate) mod export_list; -pub(crate) mod file_kind; -pub(crate) mod file_writer; -pub(crate) mod fs; -pub(crate) mod gc_stats; -pub(crate) mod grouping; -pub(crate) mod hash; -pub(crate) mod identity; -pub(crate) mod input_data; -pub(crate) mod layout; -pub(crate) mod layout_rules; -#[cfg_attr(not(feature = "plugins"), path = "linker_plugins_disabled.rs")] -mod linker_plugins; -pub(crate) mod linker_script; -pub(crate) mod output_kind; -pub(crate) mod output_section_id; -pub(crate) mod output_section_map; -pub(crate) mod output_section_part_map; -pub(crate) mod output_trace; -pub(crate) mod parsing; -pub(crate) mod part_id; -pub(crate) mod pe_link; -#[cfg(all( - target_os = "linux", - any(target_arch = "x86_64", target_arch = "aarch64") -))] -pub(crate) mod perf; -#[cfg(any( - not(target_os = "linux"), - all( - target_os = "linux", - any(target_arch = "riscv64", target_arch = "loongarch64") - ) -))] -#[path = "perf_unsupported.rs"] -pub(crate) mod perf; -pub(crate) mod platform; -pub(crate) mod program_segments; -pub(crate) mod resolution; -pub(crate) mod save_dir; -pub(crate) mod sframe; -pub(crate) mod sharding; -pub(crate) mod string_merging; -#[cfg(feature = "fork")] -pub(crate) mod subprocess; -#[cfg(not(feature = "fork"))] -#[path = "subprocess_unsupported.rs"] -pub(crate) mod subprocess; -pub(crate) mod symbol; -pub(crate) mod symbol_db; -pub(crate) mod target_os; -pub(crate) mod timing; -pub(crate) mod validation; -pub(crate) mod value_flags; -pub(crate) mod verification; -pub(crate) mod version_script; - -use crate::args::ActivatedArgs; -use crate::error::Context; -use crate::error::Result; -use crate::identity::linker_identity; -use crate::layout_rules::LayoutRulesBuilder; -use crate::output_kind::OutputKind; -use crate::platform::Platform; -use crate::value_flags::PerSymbolFlags; -use crate::version_script::VersionScript; -pub use args::Args; -use args::linux::ElfArgs; -use colosseum::sync::Arena; -use crossbeam_utils::atomic::AtomicCell; -use error::AlreadyInitialised; -use input_data::FileLoader; -use input_data::InputFile; -use input_data::InputLinkerScript; -use layout_rules::LayoutRules; -use output_section_id::OutputSections; -use std::io::BufWriter; -use std::io::Write; -use std::path::Path; -pub use subprocess::run_in_subprocess; -use tracing_subscriber::EnvFilter; -use tracing_subscriber::fmt; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::util::SubscriberInitExt; - -/// Runs the linker and cleans up associated resources. -pub fn run(args: args::Args) -> error::Result { - // Note, we need to setup tracing before we activate the thread pool. In particular, we need to - // initialise the timing module before the worker threads are started, otherwise the threads - // won't contribute to counters such as --time=cycles,instructions etc. - setup_tracing(&args)?; - let args = args.activate_thread_pool()?; - let linker = Linker::new(); - linker.run(args)?; - drop(linker); - timing::finalise_perfetto_trace()?; - Ok(()) -} - -/// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be -/// called once and only if nothing else has already set the global tracing dispatcher. Calling this -/// is optional. If it isn't called, no tracing-based features will function. e.g. --time. -pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { - if let Some(opts) = args.time_phase_options.as_ref() { - timing::init_tracing(opts) - } else if args.print_allocations.is_some() { - debug_trace::init() - } else { - tracing_subscriber::registry() - .with(fmt::layer()) - .with(EnvFilter::from_default_env()) - .try_init() - .map_err(|_| AlreadyInitialised) - } -} - -/// This is effectively a data store for use while linking. It takes ownership of all the input data -/// that we read, which allows the linking stages to borrow that data. Dropping this struct might be -/// expensive, so the caller of the linker might want to think about when best to drop it - probably -/// together with the `LinkerOutput`. Note, calling `exit` without dropping this struct is an -/// option, but likely won't save any time, since the bulk of the work done during drop (unmapping -/// pages) will still happen anyway. -pub struct Linker { - /// We store our input files here once we've read them. - pub(crate) inputs_arena: Arena, - - linker_plugin_arena: Arena, - - /// Anything that doesn't need a custom Drop implementation can go in here. In practice, it's - /// mostly just the decompressed copy of compressed string-merge sections. - herd: bumpalo_herd::Herd, - - /// We'll fill this in when we're done linking and start shutting down. Once this is dropped, - /// that signals the end of shutdown for the purposes of timing measurement. - #[allow(dyn_drop)] - shutdown_scope: AtomicCell>>, - - /// A timing scope that exists for the whole time we're linking. - #[allow(dyn_drop)] - _link_scope: Vec>, -} - -pub struct LinkerOutput<'layout_inputs> { - /// This is just here so that we defer its destruction. This allows us to (a) measure how long - /// it takes to drop and (b) if we forked, signal our parent that we're done, then drop it in - /// the background. - layout: Option>, -} - -impl Linker { - pub fn new() -> Self { - let (guard_a, guard_b) = timing_guard!("Link"); - - Self { - inputs_arena: Arena::new(), - linker_plugin_arena: Arena::new(), - herd: Default::default(), - shutdown_scope: Default::default(), - _link_scope: vec![Box::new(guard_a), Box::new(guard_b)], - } - } - - /// Runs the linker. Takes ownership of the activated args so it can dispatch - /// to the appropriate format-specific linker internally. - pub fn run(&self, args: ActivatedArgs) -> error::Result { - match args.args.version_mode { - args::VersionMode::ExitAfterPrint => { - println!("{}", linker_identity()); - return Ok(()); - } - args::VersionMode::Verbose => { - println!("{}", linker_identity()); - // Continue linking - } - args::VersionMode::None => { - // Don't print version - } - } - - match args.args.target_args { - args::TargetArgs::Elf(_) => { - let args = args.map_target(|t| match t { - args::TargetArgs::Elf(e) => e, - _ => unreachable!(), - }); - let args = &args.args; - match args.arch { - arch::Architecture::X86_64 => { - self.link_for_arch::(args)?; - } - arch::Architecture::AArch64 => { - self.link_for_arch::(args)?; - } - arch::Architecture::RISCV64 => { - self.link_for_arch::(args)?; - } - arch::Architecture::LoongArch64 => { - self.link_for_arch::(args)?; - } - } - } - args::TargetArgs::Pe(_) => { - let args = args.map_target(|t| match t { - args::TargetArgs::Pe(p) => p, - _ => unreachable!(), - }); - pe_link::link_pe(self, &args.args)?; - } - } - - // We've finished linking. We consider everything from this point onwards as shutdown. - let (g1, g2) = timing_guard!("Shutdown"); - self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); - - Ok(()) - } - - fn link_for_arch<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - &'data self, - args: &'data args::Args, - ) -> error::Result> { - let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); - - // Note, we propagate errors from `link_with_input_data` after we've checked if any files - // changed. We want inputs-changed errors to take precedence over all other errors. - let result = self.load_inputs_and_link::

(&mut file_loader, args); - - file_loader.verify_inputs_unchanged()?; - - // Write dependency file after successful linking - if result.is_ok() - && let Some(dep_file_path) = &args.dependency_file - { - write_dependency_file(dep_file_path, &args.output, &file_loader.loaded_files) - .with_context(|| { - format!( - "Failed to write dependency file `{}`", - dep_file_path.display() - ) - })?; - } - - result - } - - fn load_inputs_and_link<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - &'data self, - file_loader: &mut FileLoader<'data>, - args: &'data args::Args, - ) -> error::Result> { - let mut plugin = - linker_plugins::LinkerPlugin::from_args(args, &self.linker_plugin_arena, &self.herd)?; - - let loaded = file_loader.load_inputs(&args.inputs, args, &mut plugin); - - args.save_dir.finish(file_loader, args)?; - - let loaded = loaded?; - - let output_kind = OutputKind::new(args, file_loader); - - let mut output = file_writer::Output::new(args, output_kind); - - let mut output_sections = OutputSections::with_base_address(output_kind.base_address()); - - let mut layout_rules_builder = LayoutRulesBuilder::default(); - - let auxiliary = input_data::AuxiliaryFiles::new(args, &self.inputs_arena)?; - - let mut symbol_db = symbol_db::SymbolDb::new(args, output_kind, &auxiliary, &self.herd)?; - let mut per_symbol_flags = PerSymbolFlags::new(); - - symbol_db.add_inputs( - &mut per_symbol_flags, - &mut output_sections, - &mut layout_rules_builder, - loaded, - )?; - - // TODO: Doing this here means that we can't wrap symbols produced by the linker plugin. - // Moving it earlier or later however requires some rethought as to how this works. - symbol_db.apply_wrapped_symbol_overrides(); - - let mut resolver = resolution::Resolver::default(); - - resolver.resolve_symbols_and_select_archive_entries(&mut symbol_db)?; - - // Now that we know which archive entries are being loaded, we can resolve alternative - // symbol definitions. - crate::symbol_db::resolve_alternative_symbol_definitions( - &mut symbol_db, - &mut per_symbol_flags, - &resolver.resolved_groups, - )?; - - if let Some(plugin) = plugin.as_mut() - && plugin.is_initialised() - { - plugin.all_symbols_read( - &mut symbol_db, - &mut resolver, - file_loader, - &mut per_symbol_flags, - &mut output_sections, - &mut layout_rules_builder, - )?; - } - - // If it's a rust version script, apply the global symbol visibility now. - // We previously downgraded all symbols to local visibility. - if let VersionScript::Rust(rust_vscript) = &symbol_db.version_script { - symbol_db.handle_rust_version_script(rust_vscript, &mut per_symbol_flags); - } - - let layout_rules = layout_rules_builder.build(); - - let resolved = resolver.resolve_sections_and_canonicalise_undefined( - &mut symbol_db, - &mut per_symbol_flags, - &mut output_sections, - &layout_rules, - )?; - - let layout = layout::compute::

( - symbol_db, - per_symbol_flags, - resolved, - output_sections, - &mut output, - )?; - - output.write(&layout, elf_writer::write::

)?; - diff::maybe_diff()?; - - // We've finished linking. We consider everything from this point onwards as shutdown. - let (g1, g2) = timing_guard!("Shutdown"); - self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); - - Ok(LinkerOutput { - layout: Some(layout), - }) - } -} - -impl Default for Linker { - fn default() -> Self { - Self::new() - } -} - -impl Drop for Linker { - fn drop(&mut self) { - timing_phase!("Drop inputs"); - self.inputs_arena = Arena::new(); - self.herd = Default::default(); - } -} - -impl Drop for LinkerOutput<'_> { - fn drop(&mut self) { - timing_phase!("Drop layout"); - self.layout.take(); - } -} - -/// Writes a dependency file in Makefile format. -fn write_dependency_file( - dep_file_path: &Path, - output_path: &Path, - loaded_files: &[&InputFile], -) -> std::io::Result<()> { - timing_phase!("Write dependency file"); - - let file = std::fs::File::create(dep_file_path)?; - let mut writer = BufWriter::new(file); - - // Collect unique dependency paths - let mut seen = std::collections::HashSet::new(); - let mut deps = Vec::new(); - for input_file in loaded_files { - // Skip temporary files. e.g. those generated by linker plugins. - if input_file.modifiers.temporary { - continue; - } - - let path_str = input_file.filename.display().to_string(); - if seen.insert(path_str.clone()) { - deps.push(path_str); - } - } - - write!(writer, "{}:", output_path.display())?; - - for dep in &deps { - write!(writer, " {dep}")?; - } - - writeln!(writer)?; - - for dep in &deps { - writeln!(writer, "\n{dep}:")?; - } - - Ok(()) -} - -/// Possibly initialise timing if a timing-related environment variable is active and it was enabled -/// in the build, otherwise, do nothing. See `BENCHMARKING.md` for details. -pub fn init_timing() -> Result { - timing::setup() -} +pub(crate) mod alignment; +pub(crate) mod arch; +pub(crate) mod archive; +pub mod args; +pub(crate) mod coff; +pub(crate) mod debug_trace; +pub(crate) mod diagnostics; +pub(crate) mod diff; +pub(crate) mod dwarf_address_info; +pub(crate) mod elf; +pub(crate) mod elf_aarch64; +pub(crate) mod elf_loongarch64; +pub(crate) mod elf_riscv64; +pub(crate) mod elf_writer; +pub(crate) mod elf_x86_64; +pub mod error; +pub(crate) mod export_list; +pub(crate) mod file_kind; +pub(crate) mod file_writer; +pub(crate) mod fs; +pub(crate) mod gc_stats; +pub(crate) mod grouping; +pub(crate) mod hash; +pub(crate) mod identity; +pub(crate) mod input_data; +pub(crate) mod layout; +pub(crate) mod layout_rules; +#[cfg_attr(not(feature = "plugins"), path = "linker_plugins_disabled.rs")] +mod linker_plugins; +pub(crate) mod linker_script; +pub(crate) mod output_kind; +pub(crate) mod output_section_id; +pub(crate) mod output_section_map; +pub(crate) mod output_section_part_map; +pub(crate) mod output_trace; +pub(crate) mod parsing; +pub(crate) mod part_id; +#[cfg(all( + target_os = "linux", + any(target_arch = "x86_64", target_arch = "aarch64") +))] +pub(crate) mod perf; +#[cfg(any( + not(target_os = "linux"), + all( + target_os = "linux", + any(target_arch = "riscv64", target_arch = "loongarch64") + ) +))] +#[path = "perf_unsupported.rs"] +pub(crate) mod perf; +pub(crate) mod platform; +pub(crate) mod program_segments; +pub(crate) mod resolution; +pub(crate) mod save_dir; +pub(crate) mod sframe; +pub(crate) mod sharding; +pub(crate) mod string_merging; +#[cfg(feature = "fork")] +pub(crate) mod subprocess; +#[cfg(not(feature = "fork"))] +#[path = "subprocess_unsupported.rs"] +pub(crate) mod subprocess; +pub(crate) mod symbol; +pub(crate) mod symbol_db; +pub(crate) mod target_os; +pub(crate) mod timing; +pub(crate) mod validation; +pub(crate) mod value_flags; +pub(crate) mod verification; +pub(crate) mod version_script; + +use crate::args::ActivatedArgs; +use crate::error::Context; +use crate::error::Result; +use crate::identity::linker_identity; +use crate::layout_rules::LayoutRulesBuilder; +use crate::output_kind::OutputKind; +use crate::platform::ObjectFile; +use crate::platform::Platform; +use crate::value_flags::PerSymbolFlags; +use crate::version_script::VersionScript; +pub use args::Args; +use args::linux::ElfArgs; +use colosseum::sync::Arena; +use crossbeam_utils::atomic::AtomicCell; +use error::AlreadyInitialised; +use input_data::FileLoader; +use input_data::InputFile; +use input_data::InputLinkerScript; +use layout_rules::LayoutRules; +use output_section_id::OutputSections; +use std::io::BufWriter; +use std::io::Write; +use std::path::Path; +pub use subprocess::run_in_subprocess; +use tracing_subscriber::EnvFilter; +use tracing_subscriber::fmt; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +/// A target architecture for linking. Each implementor provides the linking +/// pipeline for a specific format + CPU architecture combination. +pub(crate) trait LinkTarget<'data> { + type File: ObjectFile<'data>; + + /// Create a linker plugin for this target. Returns None for formats without plugin support. + fn create_plugin( + _linker: &'data Linker, + _args: &'data Args<>::ArgsType>, + ) -> error::Result>> { + Ok(None) + } + + /// Load auxiliary files (version scripts, export lists). Returns empty by default. + fn load_auxiliary( + _linker: &'data Linker, + _args: &'data Args<>::ArgsType>, + ) -> error::Result> { + Ok(input_data::AuxiliaryFiles::empty()) + } + + /// Format-specific post-resolve processing: layout computation and output writing. + fn finish_link( + linker: &'data Linker, + file_loader: &mut FileLoader<'data>, + args: &'data Args<>::ArgsType>, + plugin: &mut Option>, + symbol_db: symbol_db::SymbolDb<'data, Self::File>, + per_symbol_flags: PerSymbolFlags, + resolver: resolution::Resolver<'data, Self::File>, + output_sections: OutputSections<'data>, + layout_rules_builder: LayoutRulesBuilder<'data>, + output_kind: OutputKind, + ) -> error::Result>>; +} + +/// Blanket impl: every ELF Platform is a LinkTarget. +impl<'data, P: Platform<'data, File = crate::elf::File<'data>>> LinkTarget<'data> for P { + type File = crate::elf::File<'data>; + + fn create_plugin( + linker: &'data Linker, + args: &'data Args, + ) -> error::Result>> { + linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) + } + + fn load_auxiliary( + linker: &'data Linker, + args: &'data Args, + ) -> error::Result> { + input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) + } + + fn finish_link( + _linker: &'data Linker, + file_loader: &mut FileLoader<'data>, + args: &'data Args, + plugin: &mut Option>, + mut symbol_db: symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + mut per_symbol_flags: PerSymbolFlags, + mut resolver: resolution::Resolver<'data, crate::elf::File<'data>>, + mut output_sections: OutputSections<'data>, + mut layout_rules_builder: LayoutRulesBuilder<'data>, + output_kind: OutputKind, + ) -> error::Result>> { + if let Some(plugin) = plugin.as_mut() + && plugin.is_initialised() + { + plugin.all_symbols_read( + &mut symbol_db, + &mut resolver, + file_loader, + &mut per_symbol_flags, + &mut output_sections, + &mut layout_rules_builder, + )?; + } + + // If it's a rust version script, apply the global symbol visibility now. + // We previously downgraded all symbols to local visibility. + if let VersionScript::Rust(rust_vscript) = &symbol_db.version_script { + symbol_db.handle_rust_version_script(rust_vscript, &mut per_symbol_flags); + } + + let layout_rules = layout_rules_builder.build(); + + let resolved = resolver.resolve_sections_and_canonicalise_undefined( + &mut symbol_db, + &mut per_symbol_flags, + &mut output_sections, + &layout_rules, + )?; + + let mut output = file_writer::Output::new(args, output_kind); + + let layout = layout::compute::

( + symbol_db, + per_symbol_flags, + resolved, + output_sections, + &mut output, + )?; + + output.write(&layout, elf_writer::write::

)?; + + Ok(Some(layout)) + } +} + +/// PE LinkTarget impls. +impl<'data> LinkTarget<'data> for coff::CoffX86_64 { + type File = coff::CoffObjectFile<'data>; + + fn finish_link( + _linker: &'data Linker, + _file_loader: &mut FileLoader<'data>, + _args: &'data Args, + _plugin: &mut Option>, + _symbol_db: symbol_db::SymbolDb<'data, coff::CoffObjectFile<'data>>, + _per_symbol_flags: PerSymbolFlags, + _resolver: resolution::Resolver<'data, coff::CoffObjectFile<'data>>, + _output_sections: OutputSections<'data>, + _layout_rules_builder: LayoutRulesBuilder<'data>, + _output_kind: OutputKind, + ) -> error::Result>> { + crate::bail!("PE layout and output writing not yet implemented"); + } +} + +impl<'data> LinkTarget<'data> for coff::CoffAArch64 { + type File = coff::CoffObjectFile<'data>; + + fn finish_link( + _linker: &'data Linker, + _file_loader: &mut FileLoader<'data>, + _args: &'data Args, + _plugin: &mut Option>, + _symbol_db: symbol_db::SymbolDb<'data, coff::CoffObjectFile<'data>>, + _per_symbol_flags: PerSymbolFlags, + _resolver: resolution::Resolver<'data, coff::CoffObjectFile<'data>>, + _output_sections: OutputSections<'data>, + _layout_rules_builder: LayoutRulesBuilder<'data>, + _output_kind: OutputKind, + ) -> error::Result>> { + crate::bail!("PE layout and output writing not yet implemented"); + } +} + +/// Runs the linker and cleans up associated resources. +pub fn run(args: args::Args) -> error::Result { + // Note, we need to setup tracing before we activate the thread pool. In particular, we need to + // initialise the timing module before the worker threads are started, otherwise the threads + // won't contribute to counters such as --time=cycles,instructions etc. + setup_tracing(&args)?; + let args = args.activate_thread_pool()?; + let linker = Linker::new(); + linker.run(args)?; + drop(linker); + timing::finalise_perfetto_trace()?; + Ok(()) +} + +/// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be +/// called once and only if nothing else has already set the global tracing dispatcher. Calling this +/// is optional. If it isn't called, no tracing-based features will function. e.g. --time. +pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { + if let Some(opts) = args.time_phase_options.as_ref() { + timing::init_tracing(opts) + } else if args.print_allocations.is_some() { + debug_trace::init() + } else { + tracing_subscriber::registry() + .with(fmt::layer()) + .with(EnvFilter::from_default_env()) + .try_init() + .map_err(|_| AlreadyInitialised) + } +} + +/// This is effectively a data store for use while linking. It takes ownership of all the input data +/// that we read, which allows the linking stages to borrow that data. Dropping this struct might be +/// expensive, so the caller of the linker might want to think about when best to drop it - probably +/// together with the `LinkerOutput`. Note, calling `exit` without dropping this struct is an +/// option, but likely won't save any time, since the bulk of the work done during drop (unmapping +/// pages) will still happen anyway. +pub struct Linker { + /// We store our input files here once we've read them. + pub(crate) inputs_arena: Arena, + + linker_plugin_arena: Arena, + + /// Anything that doesn't need a custom Drop implementation can go in here. In practice, it's + /// mostly just the decompressed copy of compressed string-merge sections. + herd: bumpalo_herd::Herd, + + /// We'll fill this in when we're done linking and start shutting down. Once this is dropped, + /// that signals the end of shutdown for the purposes of timing measurement. + #[allow(dyn_drop)] + shutdown_scope: AtomicCell>>, + + /// A timing scope that exists for the whole time we're linking. + #[allow(dyn_drop)] + _link_scope: Vec>, +} + +pub struct LinkerOutput<'layout_inputs> { + /// This is just here so that we defer its destruction. This allows us to (a) measure how long + /// it takes to drop and (b) if we forked, signal our parent that we're done, then drop it in + /// the background. + layout: Option>, +} + +impl Linker { + pub fn new() -> Self { + let (guard_a, guard_b) = timing_guard!("Link"); + + Self { + inputs_arena: Arena::new(), + linker_plugin_arena: Arena::new(), + herd: Default::default(), + shutdown_scope: Default::default(), + _link_scope: vec![Box::new(guard_a), Box::new(guard_b)], + } + } + + /// Runs the linker. Takes ownership of the activated args so it can dispatch + /// to the appropriate format-specific linker internally. + pub fn run(&self, args: ActivatedArgs) -> error::Result { + match args.args.version_mode { + args::VersionMode::ExitAfterPrint => { + println!("{}", linker_identity()); + return Ok(()); + } + args::VersionMode::Verbose => { + println!("{}", linker_identity()); + // Continue linking + } + args::VersionMode::None => { + // Don't print version + } + } + + match args.args.target_args { + args::TargetArgs::Elf(_) => { + let args = args.map_target(|t| match t { + args::TargetArgs::Elf(e) => e, + _ => unreachable!(), + }); + let args = &args.args; + match args.arch { + arch::Architecture::X86_64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::AArch64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::RISCV64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::LoongArch64 => { + self.link_for_arch::(args)?; + } + } + } + args::TargetArgs::Pe(_) => { + let args = args.map_target(|t| match t { + args::TargetArgs::Pe(p) => p, + _ => unreachable!(), + }); + let args = &args.args; + match args.arch { + arch::Architecture::X86_64 => { + self.link_for_arch::(args)?; + } + arch::Architecture::AArch64 => { + self.link_for_arch::(args)?; + } + _ => { + crate::bail!("PE format only supports x86_64 and aarch64"); + } + } + } + } + + // We've finished linking. We consider everything from this point onwards as shutdown. + let (g1, g2) = timing_guard!("Shutdown"); + self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); + + Ok(()) + } + + fn link_for_arch<'data, T: LinkTarget<'data>>( + &'data self, + args: &'data args::Args<>::ArgsType>, + ) -> error::Result> { + let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); + + // Note, we propagate errors from `link_with_input_data` after we've checked if any files + // changed. We want inputs-changed errors to take precedence over all other errors. + let result = self.load_inputs_and_link::(&mut file_loader, args); + + file_loader.verify_inputs_unchanged()?; + + // Write dependency file after successful linking + if result.is_ok() + && let Some(dep_file_path) = &args.dependency_file + { + write_dependency_file(dep_file_path, &args.output, &file_loader.loaded_files) + .with_context(|| { + format!( + "Failed to write dependency file `{}`", + dep_file_path.display() + ) + })?; + } + + result + } + + fn load_inputs_and_link<'data, T: LinkTarget<'data>>( + &'data self, + file_loader: &mut FileLoader<'data>, + args: &'data args::Args<>::ArgsType>, + ) -> error::Result> { + let mut plugin = T::create_plugin(self, args)?; + + let loaded = file_loader.load_inputs::(&args.inputs, args, &mut plugin); + + args.save_dir.finish(file_loader, args)?; + + let loaded = loaded?; + + let output_kind = OutputKind::new(args, file_loader); + + let mut output_sections = OutputSections::with_base_address(output_kind.base_address()); + + let mut layout_rules_builder = LayoutRulesBuilder::default(); + + let auxiliary = T::load_auxiliary(self, args)?; + + let mut symbol_db = symbol_db::SymbolDb::new(args, output_kind, &auxiliary, &self.herd)?; + let mut per_symbol_flags = PerSymbolFlags::new(); + + symbol_db.add_inputs( + &mut per_symbol_flags, + &mut output_sections, + &mut layout_rules_builder, + loaded, + )?; + + // TODO: Doing this here means that we can't wrap symbols produced by the linker plugin. + // Moving it earlier or later however requires some rethought as to how this works. + symbol_db.apply_wrapped_symbol_overrides(); + + let mut resolver = resolution::Resolver::default(); + + resolver.resolve_symbols_and_select_archive_entries(&mut symbol_db)?; + + // Now that we know which archive entries are being loaded, we can resolve alternative + // symbol definitions. + crate::symbol_db::resolve_alternative_symbol_definitions( + &mut symbol_db, + &mut per_symbol_flags, + &resolver.resolved_groups, + )?; + + let layout = T::finish_link( + self, + file_loader, + args, + &mut plugin, + symbol_db, + per_symbol_flags, + resolver, + output_sections, + layout_rules_builder, + output_kind, + )?; + + if args.is_elf() { + diff::maybe_diff()?; + } + + // We've finished linking. We consider everything from this point onwards as shutdown. + let (g1, g2) = timing_guard!("Shutdown"); + self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); + + Ok(LinkerOutput { layout }) + } +} + +impl Default for Linker { + fn default() -> Self { + Self::new() + } +} + +impl Drop for Linker { + fn drop(&mut self) { + timing_phase!("Drop inputs"); + self.inputs_arena = Arena::new(); + self.herd = Default::default(); + } +} + +impl Drop for LinkerOutput<'_> { + fn drop(&mut self) { + timing_phase!("Drop layout"); + self.layout.take(); + } +} + +/// Writes a dependency file in Makefile format. +fn write_dependency_file( + dep_file_path: &Path, + output_path: &Path, + loaded_files: &[&InputFile], +) -> std::io::Result<()> { + timing_phase!("Write dependency file"); + + let file = std::fs::File::create(dep_file_path)?; + let mut writer = BufWriter::new(file); + + // Collect unique dependency paths + let mut seen = std::collections::HashSet::new(); + let mut deps = Vec::new(); + for input_file in loaded_files { + // Skip temporary files. e.g. those generated by linker plugins. + if input_file.modifiers.temporary { + continue; + } + + let path_str = input_file.filename.display().to_string(); + if seen.insert(path_str.clone()) { + deps.push(path_str); + } + } + + write!(writer, "{}:", output_path.display())?; + + for dep in &deps { + write!(writer, " {dep}")?; + } + + writeln!(writer)?; + + for dep in &deps { + writeln!(writer, "\n{dep}:")?; + } + + Ok(()) +} + +/// Possibly initialise timing if a timing-related environment variable is active and it was enabled +/// in the build, otherwise, do nothing. See `BENCHMARKING.md` for details. +pub fn init_timing() -> Result { + timing::setup() +} diff --git a/libwild/src/linker_plugins_disabled.rs b/libwild/src/linker_plugins_disabled.rs index 596f9f033..5977f0d95 100644 --- a/libwild/src/linker_plugins_disabled.rs +++ b/libwild/src/linker_plugins_disabled.rs @@ -34,8 +34,8 @@ impl<'data> LinkerPlugin<'data> { unreachable!(); } - pub(crate) fn from_args( - _args: &'data crate::args::Args, + pub(crate) fn from_args( + _args: &'data crate::args::Args, _linker_plugin_arena: &colosseum::sync::Arena, _herd: &bumpalo_herd::Herd, ) -> Result> { diff --git a/libwild/src/output_kind.rs b/libwild/src/output_kind.rs index f6b543dbb..d670dbe79 100644 --- a/libwild/src/output_kind.rs +++ b/libwild/src/output_kind.rs @@ -1,5 +1,4 @@ use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::args::RelocationModel; use crate::input_data::FileLoader; @@ -11,7 +10,7 @@ pub(crate) enum OutputKind { } impl OutputKind { - pub(crate) fn new(args: &Args, input_data: &FileLoader<'_>) -> OutputKind { + pub(crate) fn new(args: &Args, input_data: &FileLoader<'_>) -> OutputKind { if !args.should_output_executable { OutputKind::SharedObject } else if args.dynamic_linker.is_some() diff --git a/libwild/src/output_section_id.rs b/libwild/src/output_section_id.rs index 463dc0f5a..29dcb6e08 100644 --- a/libwild/src/output_section_id.rs +++ b/libwild/src/output_section_id.rs @@ -19,7 +19,6 @@ use crate::alignment; use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::elf; use crate::elf::DynamicEntry; use crate::elf::GLOBAL_POINTER_SYMBOL_NAME; @@ -1013,11 +1012,11 @@ impl<'data> OutputSections<'data> { pub(crate) fn secondary_order(&self, id: OutputSectionId) -> Option { self.section_infos.get(id).secondary_order } - pub(crate) fn add_sections( + pub(crate) fn add_sections( &mut self, custom_sections: &[CustomSectionDetails<'data>], sections: &mut [SectionSlot], - args: &Args, + args: &Args, ) { for custom in custom_sections { let name_str = std::str::from_utf8(custom.name.bytes()).ok(); diff --git a/libwild/src/part_id.rs b/libwild/src/part_id.rs index 7c942b7c5..6e7d6140b 100644 --- a/libwild/src/part_id.rs +++ b/libwild/src/part_id.rs @@ -1,7 +1,6 @@ use crate::alignment::Alignment; use crate::alignment::NUM_ALIGNMENTS; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::output_section_id::BuiltInSectionDetails; use crate::output_section_id::FINI; use crate::output_section_id::INIT; @@ -58,10 +57,10 @@ pub(crate) const CUSTOM_PLACEHOLDER: PartId = PartId(u32::MAX); /// Returns whether the supplied section meets our criteria for section merging. Section merging is /// optional, so there are cases where we might be able to merge, but don't currently. For example /// if alignment is > 1. -pub(crate) fn should_merge_sections( +pub(crate) fn should_merge_sections( section_flags: S, section_alignment: u64, - args: &Args, + args: &Args, ) -> bool { if !args.merge_sections { return false; diff --git a/libwild/src/pe_link.rs b/libwild/src/pe_link.rs deleted file mode 100644 index 4a8e39a27..000000000 --- a/libwild/src/pe_link.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! PE/COFF linking pipeline. - -use crate::args::windows::PeArgs; -use crate::args::Args; -use crate::bail; -use crate::coff::CoffObjectFile; -use crate::error::Result; -use crate::input_data::FileLoader; - -pub(crate) fn link_pe<'data>( - linker: &'data crate::Linker, - args: &'data Args, -) -> Result { - let mut file_loader = FileLoader::new(&linker.inputs_arena); - let loaded = file_loader.load_inputs::(&args.inputs, args, &mut None)?; - - let num_objects = loaded.objects.len(); - let mut num_symbols = 0; - for obj in &loaded.objects { - if let Ok(obj) = obj { - num_symbols += obj.num_symbols(); - } - } - - eprintln!("PE link: {num_objects} COFF objects, {num_symbols} symbols"); - - bail!("PE layout and output writing not yet implemented"); -} diff --git a/libwild/src/resolution.rs b/libwild/src/resolution.rs index 9dc212a14..f22d3f7b7 100644 --- a/libwild/src/resolution.rs +++ b/libwild/src/resolution.rs @@ -5,7 +5,6 @@ use crate::LayoutRules; use crate::alignment::Alignment; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::bail; use crate::debug_assert_bail; use crate::elf::RawSymbolName; @@ -689,7 +688,7 @@ pub(crate) struct ResolvedLtoInput { fn assign_section_ids<'data, O: ObjectFile<'data>>( resolved: &mut [ResolvedGroup<'data, O>], output_sections: &mut OutputSections<'data>, - args: &Args, + args: &Args, ) { timing_phase!("Assign section IDs"); @@ -1124,7 +1123,7 @@ impl<'data, O: ObjectFile<'data>> ResolvedDynamic<'data, O> { fn resolve_sections_for_object<'data, O: ObjectFile<'data>>( obj: &mut ResolvedObject<'data, O>, - args: &Args, + args: &Args, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, @@ -1152,7 +1151,7 @@ fn resolve_section<'data, O: ObjectFile<'data>>( input_section_index: SectionIndex, input_section: &O::SectionHeader, obj: &mut ResolvedObject<'data, O>, - args: &Args, + args: &Args, allocator: &bumpalo_herd::Member<'data>, loaded_metrics: &LoadedMetrics, rules: &SectionRules, diff --git a/libwild/src/save_dir.rs b/libwild/src/save_dir.rs index 5e77c926b..cfcddba5b 100644 --- a/libwild/src/save_dir.rs +++ b/libwild/src/save_dir.rs @@ -1,7 +1,6 @@ //! Support for saving inputs for later use. use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::archive::ArchiveEntry; use crate::archive::ArchiveIterator; use crate::args::Modifiers; @@ -49,7 +48,7 @@ impl SaveDir { )))) } - pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &Args) -> Result { + pub(crate) fn finish(&self, input_data: &FileLoader, parsed_args: &Args) -> Result { if let Some(state) = self.0.as_ref() { let mut files_to_copy = state.files_to_copy.clone(); files_to_copy.extend( @@ -130,10 +129,10 @@ impl SaveDirState { /// Finalise the save directory. Makes sure that all `filenames` have been copied, writes the /// `run-with` file and if the environment variable is set to indicate that we should skip /// linking, then exit. - fn finish<'a, I: Iterator>( + fn finish<'a, T, I: Iterator>( &self, filenames: I, - parsed_args: &Args, + parsed_args: &Args, ) -> Result { for filename in filenames { self.copy_file(&std::path::absolute(filename)?, parsed_args)?; @@ -149,7 +148,7 @@ impl SaveDirState { Ok(()) } - fn write_args_file(&self, run_file: &Path, args: &Args) -> Result { + fn write_args_file(&self, run_file: &Path, args: &Args) -> Result { let mut file = std::fs::File::create(run_file)?; let mut out = BufWriter::new(&mut file); out.write_all(PRELUDE.as_bytes())?; @@ -230,7 +229,7 @@ impl SaveDirState { } /// Copies `source_path` to our output directory. - fn copy_file(&self, source_path: &Path, parsed_args: &Args) -> Result { + fn copy_file(&self, source_path: &Path, parsed_args: &Args) -> Result { let dest_path = self.output_path(source_path); if dest_path.exists() || !source_path.exists() { @@ -341,7 +340,7 @@ impl SaveDirState { } /// Copies the files listed by the thin archive. - fn handle_thin_archive(&self, path: &Path, parsed_args: &Args) -> Result { + fn handle_thin_archive(&self, path: &Path, parsed_args: &Args) -> Result { let file_bytes = std::fs::read(path)?; let parent_path = path.parent().unwrap(); @@ -469,7 +468,7 @@ fn to_output_relative_path(path: &Path) -> PathBuf { /// Saves certain environment variables into the script. We only propagate environment variables /// that are known to be used for communication between the compiler and say linker plugins. -fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &Args) -> Result { +fn write_env(out: &mut BufWriter<&mut std::fs::File>, args: &Args) -> Result { for var in &["COLLECT_GCC", "COLLECT_GCC_OPTIONS"] { if let Ok(mut value) = std::env::var(var) { // COLLECT_GCC_OPTIONS has things like "-o /path/to/output-file" in it. Update these so diff --git a/libwild/src/symbol_db.rs b/libwild/src/symbol_db.rs index 0c450605e..ea6b5e09b 100644 --- a/libwild/src/symbol_db.rs +++ b/libwild/src/symbol_db.rs @@ -5,7 +5,6 @@ use crate::InputLinkerScript; use crate::OutputKind; use crate::args; use crate::args::Args; -use crate::args::linux::ElfArgs; use crate::bail; use crate::elf::RawSymbolName; use crate::error; @@ -70,9 +69,12 @@ use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering; use symbolic_demangle::demangle; +/// The `A` parameter exists to work around Rust's variance analysis treating associated type +/// projections as invariant. By making it a separate type parameter (defaulting to +/// `O::ArgsType`), the struct remains covariant in `'data`. #[derive(Debug)] -pub struct SymbolDb<'data, O: ObjectFile<'data>> { - pub(crate) args: &'data Args, +pub struct SymbolDb<'data, O: ObjectFile<'data>, A: Send + Sync + 'static = >::ArgsType> { + pub(crate) args: &'data Args, pub(crate) groups: Vec>, @@ -322,7 +324,7 @@ impl<'data, O: ObjectFile<'data>> SymbolDb<'data, O> { } pub(crate) fn new( - args: &'data Args, + args: &'data Args, output_kind: OutputKind, auxiliary: &AuxiliaryFiles<'data>, herd: &'data bumpalo_herd::Herd, @@ -1394,7 +1396,7 @@ pub(crate) fn is_mapping_symbol_name(name: &[u8]) -> bool { fn read_symbols<'data, O: ObjectFile<'data>>( version_script: &VersionScript, shards: &mut [SymbolWriterShard<'_, '_, 'data, O>], - args: &Args, + args: &Args, export_list: &Option>, output_kind: OutputKind, ) -> Result>> { @@ -1422,7 +1424,7 @@ fn read_symbols_for_group<'data, O: ObjectFile<'data>>( version_script: &VersionScript, export_list: &Option>, num_buckets: usize, - args: &Args, + args: &Args, output_kind: OutputKind, ) -> Result> { verbose_timing_phase!( @@ -1559,7 +1561,7 @@ fn load_symbols_from_file<'data, O: ObjectFile<'data>>( version_script: &VersionScript, symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, outputs: &mut SymbolLoadOutputs<'data>, - args: &Args, + args: &Args, export_list: &Option>, output_kind: OutputKind, ) -> Result { @@ -1686,7 +1688,7 @@ trait SymbolLoader<'data, O: ObjectFile<'data>> { struct RegularObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { object: &'a O, - args: &'a Args, + args: &'a Args, version_script: &'a VersionScript<'a>, archive_semantics: bool, lib_name: &'data [u8], @@ -2071,7 +2073,7 @@ impl<'data> PendingVersionedSymbol<'data> { } /// Decides how many buckets we should use for symbol names. -fn num_symbol_hash_buckets(args: &Args) -> usize { +fn num_symbol_hash_buckets(args: &Args) -> usize { args.available_threads.get() } From 19c588ed2c646e25a5d7c863b236a9855491c2e5 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Thu, 5 Mar 2026 22:38:30 +1300 Subject: [PATCH 07/10] add pe test --- justfile | 25 ++++++++++++++++--------- libwild/src/args/windows.rs | 5 +++-- test_pe/test.c | 4 ++++ 3 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 test_pe/test.c diff --git a/justfile b/justfile index 3455f99cc..932442935 100644 --- a/justfile +++ b/justfile @@ -1,9 +1,16 @@ -mod w "windows/wlibwild/w.just" - - -default: - @just w - - -dump-kernel32: - @llvm-objdump -a -t "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib" > kernel32.dump \ No newline at end of file +mod w "windows/wlibwild/w.just" + + +default: + @just w + + +dump-kernel32: + @llvm-objdump -a -t "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib" > kernel32.dump + +# Compile and link a minimal PE test using clang with wild as the linker +test-pe: + cargo build -p wild-linker --bin wild + mkdir -p target/testing + clang -B./target/debug/ -fuse-ld=wild -target x86_64-pc-windows-msvc -nostdlib -e entry test_pe/test.c -o target/testing/test.exe + ./target/testing/test.exe || echo $? \ No newline at end of file diff --git a/libwild/src/args/windows.rs b/libwild/src/args/windows.rs index b2c487c30..d67c1e705 100644 --- a/libwild/src/args/windows.rs +++ b/libwild/src/args/windows.rs @@ -408,10 +408,11 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .long("DYNAMICDEOPT") .help("/DYNAMICDEOPT - Enable C++ Dynamic Debugging (Preview) and step in anywhere with on-demand function deoptimization.") .execute(|_, _, _| unimplemented_option("/DYNAMICDEOPT")); - // /ENTRY - Sets the starting address. + // /ENTRY - Sets the starting address. Also accepts -e (used by clang driver). parser .declare_with_param() .long("ENTRY") + .short("e") .help("/ENTRY - Sets the starting address.") .execute(|args, _modifier_stack, value| { args.entry = Some(value.to_string()); @@ -800,7 +801,7 @@ pub(crate) fn setup_windows_argument_parser() -> ArgumentParser { .declare_with_optional_param() .long("NOLOGO") .help("/NOLOGO - Suppresses the startup banner.") - .execute(|_, _, _| unimplemented_option("/NOLOGO")); + .execute(|_, _, _| Ok(())); // /NXCOMPAT - Marks an executable as verified to be compatible with the Windows Data Execution Prevention feature. parser .declare_with_optional_param() diff --git a/test_pe/test.c b/test_pe/test.c new file mode 100644 index 000000000..e82db2eb9 --- /dev/null +++ b/test_pe/test.c @@ -0,0 +1,4 @@ +// Minimal PE entry point — no CRT, just return an exit code which apparently works without c runtime on windows +int entry(void) { + return 42; +} From 59b9e945d2821d79b1a14e323582397ef4eecaa2 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Thu, 5 Mar 2026 01:01:36 +1300 Subject: [PATCH 08/10] basci working windows linker --- libwild/src/args/mod.rs | 10 - libwild/src/coff.rs | 103 +- libwild/src/dwarf_address_info.rs | 8 +- libwild/src/elf.rs | 70 +- libwild/src/elf_aarch64.rs | 39 +- libwild/src/elf_layout.rs | 6037 ++++++++++++++++++++++++++++ libwild/src/elf_loongarch64.rs | 38 +- libwild/src/elf_riscv64.rs | 38 +- libwild/src/elf_writer.rs | 259 +- libwild/src/elf_x86_64.rs | 1090 ++--- libwild/src/file_writer.rs | 24 +- libwild/src/gc_stats.rs | 4 +- libwild/src/layout.rs | 6131 +---------------------------- libwild/src/lib.rs | 194 +- libwild/src/pe_writer.rs | 691 ++++ libwild/src/platform.rs | 1297 +++--- libwild/src/resolution.rs | 2 +- libwild/src/symbol_db.rs | 2 +- libwild/src/validation.rs | 7 +- libwild/src/verification.rs | 2 +- 20 files changed, 8489 insertions(+), 7557 deletions(-) create mode 100644 libwild/src/elf_layout.rs create mode 100644 libwild/src/pe_writer.rs diff --git a/libwild/src/args/mod.rs b/libwild/src/args/mod.rs index 9b82bab19..a9323dbce 100644 --- a/libwild/src/args/mod.rs +++ b/libwild/src/args/mod.rs @@ -1430,16 +1430,6 @@ impl Args { } } -impl Args { - pub(crate) fn is_elf(&self) -> bool { - std::any::TypeId::of::() == std::any::TypeId::of::() - } - - pub(crate) fn is_pe(&self) -> bool { - std::any::TypeId::of::() == std::any::TypeId::of::() - } -} - /// Linker args with an activated thread pool. Holds jobserver tokens for the /// duration of the link to keep the threads available. pub struct ActivatedArgs { diff --git a/libwild/src/coff.rs b/libwild/src/coff.rs index 8a09fb1dd..864a2dba0 100644 --- a/libwild/src/coff.rs +++ b/libwild/src/coff.rs @@ -10,7 +10,7 @@ use crate::bail; use crate::error::Context as _; use crate::error::Result; use crate::input_data::InputBytes; -use crate::layout; +use crate::elf_layout; use crate::layout::DynamicSymbolDefinition; use crate::layout::OutputRecordLayout; use crate::output_section_id::OutputSectionId; @@ -29,13 +29,43 @@ use object::read::coff::ImageSymbol; use rayon::Scope; use std::borrow::Cow; -// ── PE architecture marker types ──────────────────────────────────────────── - -/// Marker type for PE/COFF linking targeting x86_64. -pub(crate) struct CoffX86_64; - -/// Marker type for PE/COFF linking targeting AArch64. -pub(crate) struct CoffAArch64; +// ── PE Platform ───────────────────────────────────────────────────────────── + +pub(crate) struct PePlatform; + +impl<'data> platform::Platform<'data> for PePlatform { + type File = CoffObjectFile<'data>; + + fn finish_link( + _file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data Args, + _plugin: &mut Option>, + mut symbol_db: SymbolDb<'data, CoffObjectFile<'data>>, + mut per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, CoffObjectFile<'data>>, + mut output_sections: OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> Result>> { + let layout_rules = layout_rules_builder.build(); + let resolved = resolver.resolve_sections_and_canonicalise_undefined( + &mut symbol_db, + &mut per_symbol_flags, + &mut output_sections, + &layout_rules, + )?; + + let pe_layout = crate::pe_writer::compute_layout(&symbol_db, &resolved, args)?; + + let mut output = crate::file_writer::Output::new(args, output_kind); + output.set_size(pe_layout.file_size); + output.write(&pe_layout, |sized_output, layout| { + crate::pe_writer::write(sized_output, layout) + })?; + + Ok(Some(pe_layout.into_erased())) + } +} // ── Core COFF object file type ────────────────────────────────────────────── @@ -525,23 +555,18 @@ impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { fn enumerate_symbols( &self, ) -> impl Iterator { - let mut i = 0; - let symbols = self.symbols; - std::iter::from_fn(move || { - while i < symbols.len() { - let idx = i; - let sym = &symbols[idx]; - i += 1 + sym.number_of_aux_symbols as usize; - if sym.storage_class != pe::IMAGE_SYM_CLASS_NULL || idx == 0 { - return Some((object::SymbolIndex(idx), sym)); - } - } - None - }) + // We must yield one entry per symbol table slot (including auxiliary symbol + // padding entries) so that the count matches `num_symbols()`. Auxiliary + // entries have storage_class == IMAGE_SYM_CLASS_NULL and section_number == 0, + // so they are treated as harmless local symbols by the symbol loading code. + self.symbols + .iter() + .enumerate() + .map(|(i, s)| (object::SymbolIndex(i), s)) } fn symbols_iter(&self) -> impl Iterator { - self.enumerate_symbols().map(|(_, s)| s) + self.symbols.iter() } fn symbol(&self, index: object::SymbolIndex) -> Result<&'data CoffSymbol> { @@ -831,7 +856,7 @@ impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { Ok(()) } - fn create_layout_properties<'states, 'files, P: platform::Platform<'data, File = Self>>( + fn create_layout_properties<'states, 'files, P: platform::ElfPlatform<'data>>( _args: &Args, _objects: impl Iterator, _states: impl Iterator + Clone, @@ -843,23 +868,23 @@ impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { Ok(()) } - fn load_exception_frame_data<'scope, P: platform::Platform<'data, File = Self>>( - _object: &mut layout::ObjectLayoutState<'data>, - _common: &mut layout::CommonGroupState<'data>, + fn load_exception_frame_data<'scope, P: platform::ElfPlatform<'data>>( + _object: &mut elf_layout::ObjectLayoutState<'data>, + _common: &mut elf_layout::CommonGroupState<'data>, _eh_frame_section_index: object::SectionIndex, - _resources: &'scope layout::GraphResources<'data, '_>, - _queue: &mut layout::LocalWorkQueue, + _resources: &'scope elf_layout::GraphResources<'data, '_>, + _queue: &mut elf_layout::LocalWorkQueue, _scope: &Scope<'scope>, ) -> Result { Ok(()) } - fn non_empty_section_loaded<'scope, P: platform::Platform<'data, File = Self>>( - _object: &mut layout::ObjectLayoutState<'data>, - _common: &mut layout::CommonGroupState<'data>, - _queue: &mut layout::LocalWorkQueue, + fn non_empty_section_loaded<'scope, P: platform::ElfPlatform<'data>>( + _object: &mut elf_layout::ObjectLayoutState<'data>, + _common: &mut elf_layout::CommonGroupState<'data>, + _queue: &mut elf_layout::LocalWorkQueue, _unloaded: UnloadedSection, - _resources: &'scope layout::GraphResources<'data, 'scope>, + _resources: &'scope elf_layout::GraphResources<'data, 'scope>, _scope: &Scope<'scope>, ) -> Result { Ok(()) @@ -867,28 +892,28 @@ impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { fn finalise_group_layout(_memory_offsets: &OutputSectionPartMap) {} - fn finalise_find_required_sections(_groups: &[layout::GroupState]) {} + fn finalise_find_required_sections(_groups: &[elf_layout::GroupState]) {} fn pre_finalise_sizes_prelude( - _common: &mut layout::CommonGroupState, + _common: &mut elf_layout::CommonGroupState, _args: &Args, ) { } fn finalise_object_sizes( - _object: &mut layout::ObjectLayoutState<'data>, - _common: &mut layout::CommonGroupState, + _object: &mut elf_layout::ObjectLayoutState<'data>, + _common: &mut elf_layout::CommonGroupState, ) { } fn finalise_object_layout( - _object: &layout::ObjectLayoutState<'data>, + _object: &elf_layout::ObjectLayoutState<'data>, _memory_offsets: &mut OutputSectionPartMap, ) { } fn compute_object_addresses( - _object: &layout::ObjectLayoutState<'data>, + _object: &elf_layout::ObjectLayoutState<'data>, _memory_offsets: &mut OutputSectionPartMap, ) { } diff --git a/libwild/src/dwarf_address_info.rs b/libwild/src/dwarf_address_info.rs index bb46364d6..e352cd3fc 100644 --- a/libwild/src/dwarf_address_info.rs +++ b/libwild/src/dwarf_address_info.rs @@ -5,7 +5,7 @@ use crate::elf::File; use crate::elf::Rela; use crate::error::Result; use crate::platform::ObjectFile as _; -use crate::platform::Platform; +use crate::platform::ElfPlatform; use crate::platform::Relocation; use crate::platform::RelocationSequence as _; use crate::platform::SourceInfo; @@ -29,7 +29,7 @@ use std::path::PathBuf; const SECTION_LOAD_ADDRESS: u64 = 0x1_000_000_000; /// Attempts to locate source info for `offset_in_section` within `section`. -pub(crate) fn get_source_info<'data, P: Platform<'data>>( +pub(crate) fn get_source_info<'data, P: ElfPlatform<'data>>( object: &File, relocations: &RelocationSections, section: &object::elf::SectionHeader64, @@ -112,7 +112,7 @@ pub(crate) fn get_source_info<'data, P: Platform<'data>>( } /// Gets the data for section `id` from `object` and applies relocations to it. -fn section_data_with_relocations<'data, P: Platform<'data>>( +fn section_data_with_relocations<'data, P: ElfPlatform<'data>>( object: &File, relocations: &RelocationSections, id: gimli::SectionId, @@ -150,7 +150,7 @@ fn section_data_with_relocations<'data, P: Platform<'data>>( Ok(data) } -fn apply_section_relocations<'data, P: Platform<'data>, R: Relocation>( +fn apply_section_relocations<'data, P: ElfPlatform<'data>, R: Relocation>( object: &File<'_>, section_of_interest: &object::elf::SectionHeader64, section_data: &mut [u8], diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index 4abb4ea5d..43578ef90 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -10,7 +10,7 @@ use crate::error::Result; use crate::file_kind::FileKind; use crate::input_data::InputBytes; use crate::input_data::InputRef; -use crate::layout; +use crate::elf_layout; use crate::layout::DynamicSymbolDefinition; use crate::layout::OutputRecordLayout; use crate::output_kind::OutputKind; @@ -25,7 +25,7 @@ use crate::platform::CommonSymbol; use crate::platform::PropertyClass; use crate::platform::FrameIndex; use crate::platform::ObjectFile; -use crate::platform::Platform; +use crate::platform::ElfPlatform; use crate::platform::Relocation; use crate::platform::RelocationSequence; use crate::resolution::LoadedMetrics; @@ -657,7 +657,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { Ok(()) } - fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( + fn create_layout_properties<'states, 'files, P: ElfPlatform<'data>>( args: &Args, objects: impl Iterator, states: impl Iterator + Clone, @@ -1001,12 +1001,12 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { finalise_gnu_version_size(mem_sizes, symbol_db); } - fn load_exception_frame_data<'scope, P: Platform<'data, File = Self>>( - object: &mut crate::layout::ObjectLayoutState<'data>, - common: &mut crate::layout::CommonGroupState<'data>, + fn load_exception_frame_data<'scope, P: ElfPlatform<'data>>( + object: &mut crate::elf_layout::ObjectLayoutState<'data>, + common: &mut crate::elf_layout::CommonGroupState<'data>, eh_frame_section_index: object::SectionIndex, - resources: &'scope crate::layout::GraphResources<'data, '_>, - queue: &mut crate::layout::LocalWorkQueue, + resources: &'scope crate::elf_layout::GraphResources<'data, '_>, + queue: &mut crate::elf_layout::LocalWorkQueue, scope: &rayon::Scope<'scope>, ) -> Result { let file_symbol_id_range = object.symbol_id_range; @@ -1053,12 +1053,12 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } } - fn non_empty_section_loaded<'scope, P: Platform<'data, File = Self>>( - object: &mut layout::ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState<'data>, - queue: &mut layout::LocalWorkQueue, + fn non_empty_section_loaded<'scope, P: ElfPlatform<'data>>( + object: &mut elf_layout::ObjectLayoutState<'data>, + common: &mut elf_layout::CommonGroupState<'data>, + queue: &mut elf_layout::LocalWorkQueue, unloaded: crate::resolution::UnloadedSection, - resources: &'scope layout::GraphResources<'data, 'scope>, + resources: &'scope elf_layout::GraphResources<'data, 'scope>, scope: &Scope<'scope>, ) -> Result { let sizes = match &object.format_specific_layout_state.exception_frames { @@ -1094,7 +1094,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { Ok(()) } - fn finalise_find_required_sections(groups: &[layout::GroupState]) { + fn finalise_find_required_sections(groups: &[elf_layout::GroupState]) { tracing::debug!(target: "metrics", total = groups .iter() .map(|g| g.common.format_specific.exception_frame_count) @@ -1106,15 +1106,15 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { .sum::(), "resolved relocations"); } - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args) { + fn pre_finalise_sizes_prelude(common: &mut elf_layout::CommonGroupState, args: &Args) { if args.should_write_eh_frame_hdr { common.allocate(part_id::EH_FRAME_HDR, size_of::() as u64); } } fn finalise_object_sizes( - object: &mut layout::ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState, + object: &mut elf_layout::ObjectLayoutState<'data>, + common: &mut elf_layout::CommonGroupState, ) { // TODO: Deduplicate CIEs from different objects, then only allocate space for those CIEs // that we "won". @@ -1135,7 +1135,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn finalise_object_layout( - object: &layout::ObjectLayoutState<'data>, + object: &elf_layout::ObjectLayoutState<'data>, memory_offsets: &mut OutputSectionPartMap, ) { memory_offsets.increment( @@ -1145,7 +1145,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn compute_object_addresses( - object: &layout::ObjectLayoutState<'data>, + object: &elf_layout::ObjectLayoutState<'data>, memory_offsets: &mut OutputSectionPartMap, ) { // Note, this is currently identical to finalise_object_layout above. The two functions are @@ -1160,14 +1160,14 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { fn process_eh_frame_relocations< 'data, 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( - object: &mut layout::ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState<'data>, + object: &mut elf_layout::ObjectLayoutState<'data>, + common: &mut elf_layout::CommonGroupState<'data>, file_symbol_id_range: SymbolIdRange, - resources: &'scope layout::GraphResources<'data, '_>, - queue: &mut layout::LocalWorkQueue, + resources: &'scope elf_layout::GraphResources<'data, '_>, + queue: &mut elf_layout::LocalWorkQueue, eh_frame_section: &'data object::elf::SectionHeader64, data: &'data [u8], relocations: &R::Sequence<'data>, @@ -1209,7 +1209,7 @@ fn process_eh_frame_relocations< // We currently always load all CIEs, so any relocations found in CIEs always need // to be processed. - layout::process_relocation:: as RelocationSequence>::Rel>( + elf_layout::process_relocation:: as RelocationSequence>::Rel>( object, common, rel, @@ -1293,14 +1293,14 @@ fn process_eh_frame_relocations< fn process_section_exception_frames< 'data, 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( - object: &layout::ObjectLayoutState<'data>, + object: &elf_layout::ObjectLayoutState<'data>, frame_index: Option, - common: &mut layout::CommonGroupState<'data>, - resources: &'scope layout::GraphResources<'data, '_>, - queue: &mut layout::LocalWorkQueue, + common: &mut elf_layout::CommonGroupState<'data>, + resources: &'scope elf_layout::GraphResources<'data, '_>, + queue: &mut elf_layout::LocalWorkQueue, scope: &Scope<'scope>, exception_frames: &[ExceptionFrame<'data, R>], ) -> Result { @@ -1319,7 +1319,7 @@ fn process_section_exception_frames< // section. if let Some(eh_frame_section) = object.format_specific_layout_state.eh_frame_section { for rel in frame_data.relocations.rel_iter() { - layout::process_relocation:: as RelocationSequence>::Rel>( + elf_layout::process_relocation:: as RelocationSequence>::Rel>( object, common, &rel, @@ -1913,7 +1913,7 @@ pub(crate) struct ElfLayoutProperties { } impl ElfLayoutProperties { - pub(crate) fn new<'files, 'states, 'data: 'files + 'states, P: Platform<'data>>( + pub(crate) fn new<'files, 'states, 'data: 'files + 'states, P: ElfPlatform<'data>>( objects: impl Iterator>, states: impl Iterator> + Clone, args: &Args, @@ -1930,7 +1930,7 @@ impl ElfLayoutProperties { } } -fn merge_gnu_property_notes<'states, 'data: 'states, P: Platform<'data>>( +fn merge_gnu_property_notes<'states, 'data: 'states, P: ElfPlatform<'data>>( states: impl Iterator>, isa_needed: Option, ) -> Result> { @@ -1994,7 +1994,7 @@ fn merge_gnu_property_notes<'states, 'data: 'states, P: Platform<'data>>( Ok(output_properties) } -fn merge_eflags<'files, 'data: 'files, P: Platform<'data>>( +fn merge_eflags<'files, 'data: 'files, P: ElfPlatform<'data>>( objects: impl Iterator>, ) -> Result { timing_phase!("Merge e_flags"); @@ -2004,7 +2004,7 @@ fn merge_eflags<'files, 'data: 'files, P: Platform<'data>>( )?)) } -fn merge_riscv_attributes<'groups, 'data: 'groups, P: Platform<'data>>( +fn merge_riscv_attributes<'groups, 'data: 'groups, P: ElfPlatform<'data>>( states: impl Iterator>, ) -> Result { timing_phase!("Merge .riscv.attributes sections"); diff --git a/libwild/src/elf_aarch64.rs b/libwild/src/elf_aarch64.rs index 8b249a683..ca41b3af1 100644 --- a/libwild/src/elf_aarch64.rs +++ b/libwild/src/elf_aarch64.rs @@ -3,6 +3,7 @@ use crate::platform::PropertyClass; use crate::ensure; use crate::error; use crate::error::Result; +use crate::elf_layout::ElfLayout; use crate::layout::Layout; use crate::platform::ObjectFile as _; use linker_utils::aarch64::RelaxationKind; @@ -38,9 +39,43 @@ macro_rules! rel_info_from_type { } impl<'data> crate::platform::Platform<'data> for ElfAArch64 { - type Relaxation = Relaxation; type File = crate::elf::File<'data>; + fn create_plugin( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result>> { + crate::linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) + } + + fn load_auxiliary( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result> { + crate::input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) + } + + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data crate::Args, + plugin: &mut Option>, + symbol_db: crate::symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, crate::elf::File<'data>>, + output_sections: crate::output_section_id::OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> crate::error::Result>> { + ::finish_link( + file_loader, args, plugin, symbol_db, per_symbol_flags, + resolver, output_sections, layout_rules_builder, output_kind, + ) + } +} + +impl<'data> crate::platform::ElfPlatform<'data> for ElfAArch64 { + type Relaxation = Relaxation; + fn elf_header_arch_magic() -> u16 { object::elf::EM_AARCH64 } @@ -97,7 +132,7 @@ impl<'data> crate::platform::Platform<'data> for ElfAArch64 { false } - fn tp_offset_start(layout: &Layout<'_>) -> u64 { + fn tp_offset_start(layout: &Layout<'data, ElfLayout<'data>>) -> u64 { layout.tls_start_address_aarch64() } diff --git a/libwild/src/elf_layout.rs b/libwild/src/elf_layout.rs new file mode 100644 index 000000000..1b1e36cc6 --- /dev/null +++ b/libwild/src/elf_layout.rs @@ -0,0 +1,6037 @@ +//! ELF-specific layout computation. Traverses the graph of symbol references to figure out what +//! sections from the input files are referenced. Determines which sections need to be linked, sums +//! their sizes, decides what goes where in the output file, then allocates addresses for each symbol. + +use crate::OutputKind; +use crate::alignment; +use crate::alignment::Alignment; +use crate::args::Args; +use crate::args::linux::ElfArgs; +use crate::args::linux::BuildIdOption; +use crate::args::Strip; +use crate::bail; +use crate::debug_assert_bail; +use crate::diagnostics::SymbolInfoPrinter; +use crate::elf; +use crate::elf::ElfLayoutProperties; +use crate::elf::File; +use crate::elf::GNU_NOTE_NAME; +use crate::elf::NoteHeader; +use crate::elf::RawSymbolName; +use crate::elf::Rela; +use crate::elf::RelocationList; +use crate::elf::SectionAttributes; +use crate::elf::Symbol; +use crate::elf::Versym; +use crate::elf_writer; +use crate::ensure; +use crate::error; +use crate::error::Context; +use crate::error::Error; +use crate::error::Result; +use crate::error::warning; +use crate::file_writer; +use crate::grouping::Group; +use crate::input_data::FileId; +use crate::input_data::InputRef; +use crate::input_data::PRELUDE_FILE_ID; +use crate::layout::DynamicSymbolDefinition; +use crate::layout::InternalSymbols; +use crate::layout::OutputRecordLayout; +use crate::layout::Section; +use crate::layout::Resolution; +use crate::layout::SectionResolution; +use crate::layout_rules::SectionKind; +use crate::output_section_id; +use crate::output_section_id::FILE_HEADER; +use crate::output_section_id::OrderEvent; +use crate::output_section_id::OutputOrder; +use crate::output_section_id::OutputSectionId; +use crate::output_section_id::OutputSections; +use crate::output_section_map::OutputSectionMap; +use crate::output_section_part_map::OutputSectionPartMap; +use crate::parsing::InternalSymDefInfo; +use crate::parsing::SymbolPlacement; +use crate::part_id; +use crate::part_id::NUM_SINGLE_PART_SECTIONS; +use crate::part_id::PartId; +use crate::platform::DynamicTagValues as _; +use crate::platform::NonAddressableIndexes as _; +use crate::platform::ObjectFile; +use crate::platform::ElfPlatform; +use crate::platform::RawSymbolName as _; +use crate::platform::RelaxSymbolInfo; +use crate::platform::Relaxation as _; +use crate::platform::Relocation; +use crate::platform::RelocationSequence; +use crate::platform::SectionAttributes as _; +use crate::platform::SectionFlags as _; +use crate::platform::SectionHeader as _; +use crate::platform::Symbol as _; +use crate::program_segments::ProgramSegmentId; +use crate::program_segments::ProgramSegments; +use crate::resolution; +use crate::resolution::NotLoaded; +use crate::resolution::ResolvedGroup; +use crate::resolution::ResolvedLinkerScript; +use crate::resolution::ResolvedSyntheticSymbols; +use crate::resolution::SectionSlot; +use crate::resolution::UnloadedSection; +use crate::sharding::ShardKey; +use crate::string_merging::MergedStringStartAddresses; +use crate::string_merging::MergedStringsSection; +use crate::string_merging::get_merged_string_output_address; +use crate::symbol::UnversionedSymbolName; +use crate::symbol_db::SymbolDb; +use crate::symbol_db::SymbolDebug; +use crate::symbol_db::SymbolId; +use crate::symbol_db::SymbolIdRange; +use crate::symbol_db::Visibility; +use crate::symbol_db::is_mapping_symbol_name; +use crate::timing_phase; +use crate::value_flags::AtomicPerSymbolFlags; +use crate::value_flags::FlagsForSymbol as _; +use crate::value_flags::PerSymbolFlags; +use crate::value_flags::ValueFlags; +use crate::verbose_timing_phase; +use crossbeam_queue::ArrayQueue; +use crossbeam_queue::SegQueue; +use foldhash::HashSet; +use hashbrown::HashMap; +use itertools::Itertools; +use linker_utils::elf::RelocationKind; +use linker_utils::elf::SectionFlags; +use linker_utils::elf::pt; +use linker_utils::elf::secnames; +use linker_utils::elf::shf; +use linker_utils::elf::sht; +use linker_utils::elf::sht::NOTE; +use linker_utils::elf::sht::RISCV_ATTRIBUTES; +use linker_utils::relaxation::RelaxDeltaMap; +use linker_utils::relaxation::RelocationModifier; +use linker_utils::relaxation::SectionRelaxDeltas; +use linker_utils::relaxation::opt_input_to_output; +use object::LittleEndian; +use object::SectionIndex; +use object::elf::gnu_hash; +use object::read::elf::Crel; +use object::read::elf::Dyn as _; +use object::read::elf::RelocationSections; +use rayon::Scope; +use rayon::iter::IndexedParallelIterator; +use rayon::iter::IntoParallelIterator; +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::IntoParallelRefMutIterator; +use rayon::iter::ParallelIterator; +use smallvec::SmallVec; +use std::ffi::CString; +use std::fmt::Display; +use std::mem::replace; +use std::mem::size_of; +use std::mem::swap; +use std::mem::take; +use std::num::NonZeroU32; +use std::num::NonZeroU64; +use std::sync::Mutex; +use std::sync::atomic; +use std::sync::atomic::AtomicBool; +use std::sync::atomic::AtomicU64; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering::Relaxed; + +pub fn compute<'data, P: ElfPlatform<'data>>( + symbol_db: SymbolDb<'data, crate::elf::File<'data>>, + mut per_symbol_flags: PerSymbolFlags, + mut groups: Vec>>, + mut output_sections: OutputSections<'data>, + output: &mut file_writer::Output, +) -> Result>> { + timing_phase!("Layout"); + + let sonames = Sonames::new(&symbol_db.groups); + + let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); + + let symbol_info_printer = symbol_db.args.sym_info.as_ref().map(|sym_name| { + SymbolInfoPrinter::new(&symbol_db, sym_name, &atomic_per_symbol_flags, &groups) + }); + + let string_merge_inputs = + crate::string_merging::StringMergeInputs::new(&mut groups, &output_sections)?; + + let (merged_strings, gc_outputs) = rayon::join( + || { + crate::string_merging::merge_strings( + &string_merge_inputs, + &output_sections, + symbol_db.args, + ) + }, + || { + find_required_sections::

( + groups, + &symbol_db, + &atomic_per_symbol_flags, + &output_sections, + sonames, + ) + }, + ); + let merged_strings = merged_strings?; + let gc_outputs = gc_outputs?; + + let mut group_states = gc_outputs.group_states; + + let epilogue_file_id = FileId::new(group_states.len() as u32, 0); + + finalise_copy_relocations(&mut group_states, &symbol_db, &atomic_per_symbol_flags)?; + let mut dynamic_symbol_definitions = + merge_dynamic_symbol_definitions(&group_states, &symbol_db)?; + + group_states.push(GroupState { + files: vec![FileLayoutState::Epilogue(EpilogueLayoutState::new( + symbol_db.args, + symbol_db.output_kind, + &mut dynamic_symbol_definitions, + ))], + queue: LocalWorkQueue::new(epilogue_file_id.group()), + common: CommonGroupState::new(&output_sections), + num_symbols: 0, + }); + + let properties_and_attributes = crate::elf::File::create_layout_properties::

( + symbol_db.args, + objects_iter(&group_states).map(|obj| obj.object), + objects_iter(&group_states).map(|obj| &obj.format_specific_layout_state), + )?; + + let finalise_sizes_resources = FinaliseSizesResources { + dynamic_symbol_definitions: &dynamic_symbol_definitions, + symbol_db: &symbol_db, + merged_strings: &merged_strings, + format_specific: &properties_and_attributes, + }; + + finalise_all_sizes( + &mut group_states, + &output_sections, + &atomic_per_symbol_flags, + &finalise_sizes_resources, + )?; + + // Dropping `symbol_info_printer` will cause it to print. So we'll either print now, or, if we + // got an error, then we'll have printed at that point. + drop(symbol_info_printer); + + let non_addressable_counts = apply_non_addressable_indexes(&mut group_states, &symbol_db)?; + + propagate_section_attributes(&group_states, &mut output_sections); + + let (output_order, program_segments) = output_sections.output_order(); + + tracing::trace!( + "Output order:\n{}", + output_order.display(&output_sections, &program_segments) + ); + + let mut section_part_sizes = compute_total_section_part_sizes( + &mut group_states, + &mut output_sections, + &output_order, + &program_segments, + &mut per_symbol_flags, + gc_outputs.must_keep_sections, + &finalise_sizes_resources, + )?; + + let mut section_part_layouts = layout_section_parts( + §ion_part_sizes, + &output_sections, + &program_segments, + &output_order, + symbol_db.args, + ); + + if symbol_db.args.relax && P::supports_size_reduction_relaxations() { + perform_iterative_relaxation::

( + &mut group_states, + &mut section_part_sizes, + &mut section_part_layouts, + &output_sections, + &program_segments, + &output_order, + &symbol_db, + &per_symbol_flags, + ); + } + + let section_layouts = layout_sections(&output_sections, §ion_part_layouts); + let mut merged_section_layouts = section_layouts.clone(); + merge_secondary_parts(&output_sections, &mut merged_section_layouts); + + let file_size = compute_total_file_size(§ion_layouts); + output.set_size(file_size); + + let Some(FileLayoutState::Prelude(internal)) = + &group_states.first().and_then(|g| g.files.first()) + else { + unreachable!(); + }; + let header_info = internal.header_info.as_ref().unwrap(); + let segment_layouts = compute_segment_layout( + §ion_layouts, + &output_sections, + &output_order, + &program_segments, + header_info, + symbol_db.args, + )?; + + let mem_offsets: OutputSectionPartMap = starting_memory_offsets(§ion_part_layouts); + let starting_mem_offsets_by_group = compute_start_offsets_by_group(&group_states, mem_offsets); + + let merged_string_start_addresses = MergedStringStartAddresses::compute( + &output_sections, + &starting_mem_offsets_by_group, + &merged_strings, + ); + + let mut symbol_resolutions = SymbolResolutions { + resolutions: Vec::with_capacity(symbol_db.num_symbols()), + }; + + let mut res_writer = sharded_vec_writer::VecWriter::new(&mut symbol_resolutions.resolutions); + + let mut per_group_res_writers = group_states + .iter() + .map(|group| res_writer.take_shard(group.num_symbols)) + .collect_vec(); + + let resources = FinaliseLayoutResources { + symbol_db: &symbol_db, + output_sections: &output_sections, + output_order: &output_order, + section_layouts: §ion_layouts, + merged_string_start_addresses: &merged_string_start_addresses, + merged_strings: &merged_strings, + per_symbol_flags: &per_symbol_flags, + dynamic_symbol_definitions: &dynamic_symbol_definitions, + segment_layouts: &segment_layouts, + program_segments: &program_segments, + format_specific: &properties_and_attributes, + }; + + let group_layouts = compute_symbols_and_layouts( + group_states, + starting_mem_offsets_by_group, + &mut per_group_res_writers, + &resources, + )?; + + for shard in per_group_res_writers { + res_writer + .try_return_shard(shard) + .context("Group resolutions not filled")?; + } + + update_dynamic_symbol_resolutions( + &resources, + &group_layouts, + &mut symbol_resolutions.resolutions, + ); + update_defsym_symbol_resolutions(&symbol_db, &mut symbol_resolutions.resolutions)?; + crate::gc_stats::maybe_write_gc_stats(&group_layouts, symbol_db.args)?; + + let relocation_statistics = OutputSectionMap::with_size(section_layouts.len()); + + // Build the shared CommonLayout from ELF-specific data. + let symbol_addresses: Vec = symbol_resolutions + .resolutions + .iter() + .map(|r| r.map_or(0, |r| r.raw_value)) + .collect(); + + Ok(crate::layout::Layout::new( + file_size, + 0, // entry_address filled in lazily via entry_symbol_address() + symbol_addresses, + ElfLayout { + symbol_db, + symbol_resolutions, + segment_layouts, + section_part_layouts, + section_layouts, + merged_section_layouts, + group_layouts, + output_sections, + program_segments, + output_order, + non_addressable_counts, + merged_strings, + merged_string_start_addresses, + has_static_tls: gc_outputs.has_static_tls, + has_variant_pcs: gc_outputs.has_variant_pcs, + relocation_statistics, + per_symbol_flags, + dynamic_symbol_definitions, + properties_and_attributes, + }, + )) +} + +struct FinaliseSizesResources<'data, 'scope> { + dynamic_symbol_definitions: &'scope [DynamicSymbolDefinition<'data>], + symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, + merged_strings: &'scope OutputSectionMap>, + format_specific: &'scope as ObjectFile<'data>>::LayoutProperties, +} + +/// Update resolutions for defsym symbols that reference other symbols. +fn update_defsym_symbol_resolutions<'data>( + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + resolutions: &mut [Option], +) -> Result { + verbose_timing_phase!("Update symdef resolutions"); + + for group in &symbol_db.groups { + let mut symbol_id = group.symbol_id_range().start(); + + match group { + Group::Prelude(prelude) => { + for def_info in &prelude.symbol_definitions { + update_defsym_symbol_resolution(symbol_id, def_info, symbol_db, resolutions)?; + symbol_id = symbol_id.next(); + } + } + Group::LinkerScripts(scripts) => { + for script in scripts { + for def_info in &script.parsed.symbol_defs { + update_defsym_symbol_resolution( + symbol_id, + def_info, + symbol_db, + resolutions, + )?; + symbol_id = symbol_id.next(); + } + } + } + Group::Objects(_) | Group::SyntheticSymbols(_) => {} + #[cfg(feature = "plugins")] + Group::LtoInputs(_) => {} + } + } + + Ok(()) +} + +fn update_defsym_symbol_resolution<'data>( + symbol_id: SymbolId, + def_info: &InternalSymDefInfo, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + resolutions: &mut [Option], +) -> Result { + let SymbolPlacement::DefsymSymbol(target_name, offset) = def_info.placement else { + return Ok(()); + }; + + if !symbol_db.is_canonical(symbol_id) { + return Ok(()); + } + + let Some(target_symbol_id) = + symbol_db.get_unversioned(&UnversionedSymbolName::prehashed(target_name.as_bytes())) + else { + return Err(symbol_db.missing_defsym_target_error(def_info.name, target_name)); + }; + + let canonical_target_id = symbol_db.definition(target_symbol_id); + if let Some(target_value) = resolutions[canonical_target_id.as_usize()] + .as_ref() + .map(|r| r.raw_value) + && let Some(resolution) = &mut resolutions[symbol_id.as_usize()] + { + // Apply the offset from the defsym expression. + resolution.raw_value = (target_value as i64).wrapping_add(offset) as u64; + } + + Ok(()) +} + +/// Update resolutions for all dynamic symbols that our output file defines. +fn update_dynamic_symbol_resolutions( + resources: &FinaliseLayoutResources, + layouts: &[GroupLayout], + resolutions: &mut [Option], +) { + timing_phase!("Update dynamic symbol resolutions"); + + let Some(FileLayout::Epilogue(epilogue)) = layouts.last().and_then(|g| g.files.last()) else { + panic!("Epilogue should be the last file"); + }; + + for (index, sym) in resources.dynamic_symbol_definitions.iter().enumerate() { + let dynamic_symbol_index = NonZeroU32::try_from(epilogue.dynsym_start_index + index as u32) + .expect("Dynamic symbol definitions should start > 0"); + if let Some(res) = &mut resolutions[sym.symbol_id.as_usize()] { + res.dynamic_symbol_index = Some(dynamic_symbol_index); + } + } +} + +/// Where we've decided that we need copy relocations, look for symbols with the same address as the +/// symbols with copy relocations. If the other symbol is non-weak, then we do the copy relocation +/// for that symbol instead. We also request dynamic symbol definitions for each copy relocation. +/// For that reason, this needs to be done before we merge dynamic symbol definitions. +fn finalise_copy_relocations<'data>( + group_states: &mut [GroupState<'data>], + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + symbol_flags: &AtomicPerSymbolFlags, +) -> Result { + timing_phase!("Finalise copy relocations"); + + group_states.par_iter_mut().try_for_each(|group| { + verbose_timing_phase!("Finalise copy relocations for group"); + for file in &mut group.files { + if let FileLayoutState::Dynamic(dynamic) = file { + dynamic.finalise_copy_relocations(&mut group.common, symbol_db, symbol_flags)?; + } + } + + Ok(()) + }) +} + +fn finalise_all_sizes<'data>( + group_states: &mut [GroupState<'data>], + output_sections: &OutputSections, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources<'data, '_>, +) -> Result { + timing_phase!("Finalise per-object sizes"); + + group_states.par_iter_mut().try_for_each(|state| { + verbose_timing_phase!("Finalise sizes for group"); + state.finalise_sizes(output_sections, per_symbol_flags, resources) + }) +} + +fn merge_dynamic_symbol_definitions<'data>( + group_states: &[GroupState<'data>], + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, +) -> Result>> { + timing_phase!("Merge dynamic symbol definitions"); + + let mut dynamic_symbol_definitions = Vec::new(); + for group in group_states { + dynamic_symbol_definitions.extend(group.common.dynamic_symbol_definitions.iter().copied()); + } + + append_prelude_defsym_dynamic_symbols( + group_states, + symbol_db, + &mut dynamic_symbol_definitions, + )?; + + Ok(dynamic_symbol_definitions) +} + +fn append_prelude_defsym_dynamic_symbols<'data>( + group_states: &[GroupState<'data>], + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + dynamic_symbol_definitions: &mut Vec>, +) -> Result { + if symbol_db.output_kind.needs_dynsym() + && let Some(first_group) = group_states.first() + && let Some(FileLayoutState::Prelude(prelude)) = first_group.files.first() + { + let symbol_id_range = prelude.symbol_id_range; + for (index, def_info) in prelude + .internal_symbols + .symbol_definitions + .iter() + .enumerate() + { + if !matches!(def_info.placement, SymbolPlacement::DefsymSymbol(_, _)) { + continue; + } + + let symbol_id = symbol_id_range.offset_to_id(index); + if !symbol_db.is_canonical(symbol_id) + || dynamic_symbol_definitions + .iter() + .any(|def| def.symbol_id == symbol_id) + { + continue; + } + + let symbol_name = symbol_db.symbol_name(symbol_id)?; + let RawSymbolName { + name, + version_name, + is_default, + } = RawSymbolName::parse(symbol_name.bytes()); + + let mut version = object::elf::VER_NDX_GLOBAL; + if symbol_db.version_script.version_count() > 0 + && let Some(v) = symbol_db + .version_script + .version_for_symbol(&UnversionedSymbolName::prehashed(name), version_name)? + { + version = v; + if !is_default { + version |= object::elf::VERSYM_HIDDEN; + } + } + dynamic_symbol_definitions.push(DynamicSymbolDefinition::new(symbol_id, name, version)); + } + } + + Ok(()) +} + +fn objects_iter<'groups, 'data>( + group_states: &'groups [GroupState<'data>], +) -> impl Iterator> + Clone { + group_states.iter().flat_map(|group| { + group.files.iter().filter_map(|file| match file { + FileLayoutState::Object(object) => Some(object), + _ => None, + }) + }) +} + +fn compute_total_file_size(section_layouts: &OutputSectionMap) -> u64 { + let mut file_size = 0; + section_layouts.for_each(|_, s| file_size = file_size.max(s.file_offset + s.file_size)); + file_size as u64 +} + + +/// ELF-specific layout data. Wrapped in `crate::layout::Layout` which provides the +/// common fields (file_size, entry_address, symbol_addresses). +#[derive(Debug)] +pub(crate) struct ElfLayout<'data> { + pub(crate) symbol_db: SymbolDb<'data, crate::elf::File<'data>>, + pub(crate) symbol_resolutions: SymbolResolutions, + pub(crate) section_part_layouts: OutputSectionPartMap, + + pub(crate) section_layouts: OutputSectionMap, + + /// This is like `section_layouts`, but where secondary sections are merged into their primary + /// section. Values for secondary sections are reset to 0 and should not be used. + pub(crate) merged_section_layouts: OutputSectionMap, + + pub(crate) group_layouts: Vec>, + pub(crate) segment_layouts: SegmentLayouts, + pub(crate) output_sections: OutputSections<'data>, + pub(crate) program_segments: ProgramSegments, + pub(crate) output_order: OutputOrder, + pub(crate) non_addressable_counts: + as ObjectFile<'data>>::NonAddressableCounts, + pub(crate) merged_strings: OutputSectionMap>, + pub(crate) merged_string_start_addresses: MergedStringStartAddresses, + pub(crate) relocation_statistics: OutputSectionMap, + pub(crate) has_static_tls: bool, + pub(crate) has_variant_pcs: bool, + pub(crate) per_symbol_flags: PerSymbolFlags, + pub(crate) dynamic_symbol_definitions: Vec>, + pub(crate) properties_and_attributes: as ObjectFile<'data>>::LayoutProperties, +} + +impl<'data> crate::layout::LayoutTarget<'data> for ElfLayout<'data> { + type ArgsType = crate::args::linux::ElfArgs; + + fn args(&self) -> &crate::args::Args { + self.symbol_db.args + } + + fn layout_data(&self) -> linker_layout::Layout { + self.layout_data() + } + + fn into_target_layout(self) -> crate::layout::TargetLayout<'data> { + crate::layout::TargetLayout::Elf(self) + } +} + +#[derive(Debug)] +pub(crate) struct SegmentLayouts { + /// The layout of each of our segments. Segments containing no active output sections will have + /// been filtered, so don't try to index this by our internal segment IDs. + pub(crate) segments: Vec, + pub(crate) tls_layout: Option, +} + +#[derive(Debug, Default, Clone)] +pub(crate) struct SegmentLayout { + pub(crate) id: ProgramSegmentId, + pub(crate) sizes: OutputRecordLayout, +} + +#[derive(Debug)] +pub(crate) struct SymbolResolutions { + resolutions: Vec>, +} + +pub(crate) enum FileLayout<'data> { + Prelude(PreludeLayout<'data>), + Object(ObjectLayout<'data>), + Dynamic(DynamicLayout<'data>), + SyntheticSymbols(SyntheticSymbolsLayout<'data>), + Epilogue(EpilogueLayout), + NotLoaded, + LinkerScript(LinkerScriptLayoutState<'data>), +} + +enum FileLayoutState<'data> { + Prelude(PreludeLayoutState<'data>), + Object(ObjectLayoutState<'data>), + Dynamic(DynamicLayoutState<'data>), + NotLoaded(NotLoaded), + SyntheticSymbols(SyntheticSymbolsLayoutState<'data>), + Epilogue(EpilogueLayoutState), + LinkerScript(LinkerScriptLayoutState<'data>), +} + +/// Data that doesn't come from any input files, but needs to be written by the linker. +struct PreludeLayoutState<'data> { + file_id: FileId, + symbol_id_range: SymbolIdRange, + internal_symbols: InternalSymbols<'data>, + entry_symbol_id: Option, + needs_tlsld_got_entry: bool, + identity: String, + header_info: Option, + dynamic_linker: Option, + shstrtab_size: u64, +} + +pub(crate) struct SyntheticSymbolsLayoutState<'data> { + file_id: FileId, + symbol_id_range: SymbolIdRange, + internal_symbols: InternalSymbols<'data>, +} + +pub(crate) struct EpilogueLayoutState { + format_specific: crate::elf::EpilogueLayout, + build_id_size: Option, +} + +pub(crate) struct LinkerScriptLayoutState<'data> { + file_id: FileId, + input: InputRef<'data>, + symbol_id_range: SymbolIdRange, + pub(crate) internal_symbols: InternalSymbols<'data>, +} + +#[derive(Debug)] +pub(crate) struct SyntheticSymbolsLayout<'data> { + pub(crate) internal_symbols: InternalSymbols<'data>, +} + +#[derive(Debug)] +pub(crate) struct EpilogueLayout { + pub(crate) format_specific: crate::elf::EpilogueLayout, + pub(crate) dynsym_start_index: u32, +} + +#[derive(Debug)] +pub(crate) struct ObjectLayout<'data> { + pub(crate) input: InputRef<'data>, + pub(crate) file_id: FileId, + pub(crate) object: &'data File<'data>, + pub(crate) sections: Vec, + pub(crate) relocations: RelocationSections, + pub(crate) section_resolutions: Vec, + pub(crate) symbol_id_range: SymbolIdRange, + /// SFrame section ranges for this object, relative to the start of the .sframe output section. + pub(crate) sframe_ranges: Vec>, + /// Sparse map from section index to relaxation delta details. + pub(crate) section_relax_deltas: RelaxDeltaMap, +} + +#[derive(Debug)] +pub(crate) struct PreludeLayout<'data> { + pub(crate) entry_symbol_id: Option, + pub(crate) tlsld_got_entry: Option, + pub(crate) identity: String, + pub(crate) header_info: HeaderInfo, + pub(crate) internal_symbols: InternalSymbols<'data>, + pub(crate) dynamic_linker: Option, +} + +pub(crate) struct DynamicLayout<'data> { + pub(crate) file_id: FileId, + input: InputRef<'data>, + + /// The name we'll put into the binary to tell the dynamic loader what to load. + pub(crate) lib_name: &'data [u8], + + pub(crate) symbol_id_range: SymbolIdRange, + + pub(crate) object: &'data crate::elf::File<'data>, + + pub(crate) copy_relocation_symbols: Vec, + + pub(crate) format_specific_layout: + as ObjectFile<'data>>::DynamicLayout, +} + +trait HandlerData { + fn symbol_id_range(&self) -> SymbolIdRange; + + fn file_id(&self) -> FileId; +} + +trait SymbolRequestHandler<'data>: std::fmt::Display + HandlerData { + fn finalise_symbol_sizes( + &mut self, + common: &mut CommonGroupState, + symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources, + ) -> Result { + let symbol_db = resources.symbol_db; + + let _file_span = symbol_db.args.trace_span_for_file(self.file_id()); + let symbol_id_range = self.symbol_id_range(); + + for (local_index, atomic_flags) in symbol_flags.range(symbol_id_range).iter().enumerate() { + let symbol_id = symbol_id_range.offset_to_id(local_index); + if !symbol_db.is_canonical(symbol_id) { + continue; + } + let flags = atomic_flags.get(); + + // It might be tempting to think that this code should only be run for dynamic objects, + // however regular objects can own dynamic symbols too if the symbol is an undefined + // weak symbol. + if flags.is_dynamic() && flags.has_resolution() { + let name = symbol_db.symbol_name(symbol_id)?; + let name = RawSymbolName::parse(name.bytes()).name; + + if flags.needs_copy_relocation() { + // The dynamic symbol is a definition, so is handled by the epilogue. We only + // need to deal with the symtab entry here. + let entry_size = size_of::() as u64; + common.allocate(part_id::SYMTAB_GLOBAL, entry_size); + common.allocate(part_id::STRTAB, name.len() as u64 + 1); + } else { + common.allocate(part_id::DYNSTR, name.len() as u64 + 1); + common.allocate(part_id::DYNSYM, crate::elf::SYMTAB_ENTRY_SIZE); + } + } + + if symbol_db.args.verify_allocation_consistency { + verify_consistent_allocation_handling(flags, symbol_db.output_kind)?; + } + + allocate_symbol_resolution(flags, &mut common.mem_sizes, symbol_db.output_kind); + + if symbol_db.args.got_plt_syms && flags.needs_got() { + let name = symbol_db.symbol_name(symbol_id)?; + let name = RawSymbolName::parse(name.bytes()).name; + let name_len = name.len() + 4; // "$got" or "$plt" suffix + + let entry_size = size_of::() as u64; + common.allocate(part_id::SYMTAB_LOCAL, entry_size); + common.allocate(part_id::STRTAB, name_len as u64 + 1); + + if flags.needs_plt() { + common.allocate(part_id::SYMTAB_LOCAL, entry_size); + common.allocate(part_id::STRTAB, name_len as u64 + 1); + } + } + } + + Ok(()) + } + + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result; +} + +fn export_dynamic<'data>( + common: &mut CommonGroupState<'data>, + symbol_id: SymbolId, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, +) -> Result { + let name = symbol_db.symbol_name(symbol_id)?; + let RawSymbolName { + name, + version_name, + is_default, + } = RawSymbolName::parse(name.bytes()); + + let mut version = object::elf::VER_NDX_GLOBAL; + if symbol_db.version_script.version_count() > 0 { + // TODO: We already hashed this symbol at some point previously. See if we can avoid + // rehashing it here and if that actually saves us time. + if let Some(v) = symbol_db + .version_script + .version_for_symbol(&UnversionedSymbolName::prehashed(name), version_name)? + { + version = v; + if !is_default { + version |= object::elf::VERSYM_HIDDEN; + } + } + } + + common + .dynamic_symbol_definitions + .push(DynamicSymbolDefinition::new(symbol_id, name, version)); + + Ok(()) +} + +fn allocate_symbol_resolution( + flags: ValueFlags, + mem_sizes: &mut OutputSectionPartMap, + output_kind: OutputKind, +) { + allocate_resolution(flags, mem_sizes, output_kind); +} + +/// Computes how much to allocate for a particular resolution. This is intended for debug assertions +/// when we're writing, to make sure that we would have allocated memory before we write. +pub(crate) fn compute_allocations( + resolution: &Resolution, + output_kind: OutputKind, +) -> OutputSectionPartMap { + let mut sizes = OutputSectionPartMap::with_size(NUM_SINGLE_PART_SECTIONS as usize); + allocate_resolution(resolution.flags, &mut sizes, output_kind); + sizes +} + +fn allocate_resolution( + flags: ValueFlags, + mem_sizes: &mut OutputSectionPartMap, + output_kind: OutputKind, +) { + let has_dynamic_symbol = flags.is_dynamic() || flags.needs_export_dynamic(); + + if flags.needs_got() && !flags.is_tls() { + mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); + if flags.needs_plt() { + mem_sizes.increment(part_id::PLT_GOT, elf::PLT_ENTRY_SIZE); + } + if flags.is_ifunc() { + mem_sizes.increment(part_id::RELA_PLT, elf::RELA_ENTRY_SIZE); + } else if flags.is_interposable() && has_dynamic_symbol { + mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } else if flags.is_address() && output_kind.is_relocatable() { + mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); + } + } + + if flags.needs_ifunc_got_for_address() { + mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); + if output_kind.is_relocatable() { + mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); + } + } + + if flags.needs_got_tls_offset() { + mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); + if flags.is_interposable() || output_kind.is_shared_object() { + mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } + } + + if flags.needs_got_tls_module() { + mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); + // For executables, the TLS module ID is known at link time. For shared objects, we + // need a runtime relocation to fill it in. + if !output_kind.is_executable() || flags.is_dynamic() { + mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } + if flags.is_interposable() && has_dynamic_symbol { + mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } + } + + if flags.needs_got_tls_descriptor() { + mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); + mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } +} + +impl HandlerData for ObjectLayoutState<'_> { + fn file_id(&self) -> FileId { + self.file_id + } + + fn symbol_id_range(&self) -> SymbolIdRange { + self.symbol_id_range + } +} + +impl<'data> SymbolRequestHandler<'data> for ObjectLayoutState<'data> { + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + symbol_id: SymbolId, + resources: &GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + debug_assert_bail!( + resources.symbol_db.is_canonical(symbol_id), + "Tried to load symbol in a file that doesn't hold the definition: {}", + resources.symbol_debug(symbol_id) + ); + + let object_symbol_index = self.symbol_id_range.id_to_input(symbol_id); + let local_symbol = self.object.symbol(object_symbol_index)?; + + if let Some(section_id) = self + .object + .symbol_section(local_symbol, object_symbol_index)? + { + queue + .local_work + .push(WorkItem::LoadSection(SectionLoadRequest::new( + self.file_id, + section_id, + ))); + } else if let Some(common_symbol) = local_symbol.as_common() { + common.allocate(common_symbol.part_id, common_symbol.size); + } + + Ok(()) + } +} + +impl HandlerData for DynamicLayoutState<'_> { + fn symbol_id_range(&self) -> SymbolIdRange { + self.symbol_id_range + } + + fn file_id(&self) -> FileId { + self.file_id + } +} + +impl<'data> SymbolRequestHandler<'data> for DynamicLayoutState<'data> { + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + _common: &mut CommonGroupState, + symbol_id: SymbolId, + resources: &GraphResources<'data, 'scope>, + _queue: &mut LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + let local_index = object::SymbolIndex(symbol_id.to_offset(self.symbol_id_range())); + self.object + .dynamic_symbol_used(local_index, &mut self.format_specific_state)?; + + // Check for arch-specific VARIANT_PCS flags. + if P::is_symbol_variant_pcs(self.object, local_index) { + resources + .has_variant_pcs + .store(true, atomic::Ordering::Relaxed); + } + + Ok(()) + } +} + +impl HandlerData for PreludeLayoutState<'_> { + fn file_id(&self) -> FileId { + self.file_id + } + + fn symbol_id_range(&self) -> SymbolIdRange { + self.symbol_id_range + } +} + +impl<'data> SymbolRequestHandler<'data> for PreludeLayoutState<'data> { + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + _common: &mut CommonGroupState, + _symbol_id: SymbolId, + _resources: &GraphResources<'data, 'scope>, + _queue: &mut LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + Ok(()) + } +} + +impl HandlerData for LinkerScriptLayoutState<'_> { + fn symbol_id_range(&self) -> SymbolIdRange { + self.symbol_id_range + } + + fn file_id(&self) -> FileId { + self.file_id + } +} + +impl<'data> SymbolRequestHandler<'data> for LinkerScriptLayoutState<'data> { + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + _common: &mut CommonGroupState<'data>, + _symbol_id: SymbolId, + _resources: &GraphResources<'data, 'scope>, + _queue: &mut LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + Ok(()) + } +} + +impl HandlerData for SyntheticSymbolsLayoutState<'_> { + fn file_id(&self) -> FileId { + self.file_id + } + + fn symbol_id_range(&self) -> SymbolIdRange { + self.symbol_id_range + } +} + +impl<'data> SymbolRequestHandler<'data> for SyntheticSymbolsLayoutState<'data> { + fn load_symbol<'scope, P: ElfPlatform<'data>>( + &mut self, + _common: &mut CommonGroupState, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, 'scope>, + _queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + let def_info = + &self.internal_symbols.symbol_definitions[self.symbol_id_range.id_to_offset(symbol_id)]; + + if let Some(output_section_id) = def_info.section_id() { + // We've gotten a request to load a __start_ / __stop_ symbol, sent requests to load all + // sections that would go into that section. + let sections = resources.start_stop_sections.get(output_section_id); + while let Some(request) = sections.pop() { + resources.send_work::

( + request.file_id, + WorkItem::LoadSection(request), + resources, + scope, + ); + } + } + + Ok(()) + } +} + +#[derive(Debug)] +pub(crate) struct CommonGroupState<'data> { + mem_sizes: OutputSectionPartMap, + + section_attributes: OutputSectionMap>, + + /// Dynamic symbols that need to be defined. Because of the ordering requirements for symbol + /// hashes, these get defined by the epilogue. The object on which a particular dynamic symbol + /// is stored is non-deterministic and is whichever object first requested export of that + /// symbol. That's OK though because the epilogue will sort all dynamic symbols. + dynamic_symbol_definitions: Vec>, + + pub(crate) format_specific: as ObjectFile<'data>>::CommonGroupStateExt, +} + +impl CommonGroupState<'_> { + fn new(output_sections: &OutputSections) -> Self { + Self { + mem_sizes: output_sections.new_part_map(), + section_attributes: output_sections.new_section_map(), + dynamic_symbol_definitions: Default::default(), + format_specific: Default::default(), + } + } + + fn validate_sizes(&self) -> Result { + if *self.mem_sizes.get(part_id::GNU_VERSION) > 0 { + let num_dynamic_symbols = + self.mem_sizes.get(part_id::DYNSYM) / crate::elf::SYMTAB_ENTRY_SIZE; + let num_versym = self.mem_sizes.get(part_id::GNU_VERSION) / size_of::() as u64; + if num_versym != num_dynamic_symbols { + bail!( + "Object has {num_dynamic_symbols} dynamic symbols, but \ + has {num_versym} versym entries" + ); + } + } + + Ok(()) + } + + fn finalise_layout( + &self, + memory_offsets: &mut OutputSectionPartMap, + section_layouts: &OutputSectionMap, + ) -> u32 { + // strtab + let offset = memory_offsets.get_mut(part_id::STRTAB); + let strtab_offset_start = (*offset + - section_layouts.get(output_section_id::STRTAB).mem_offset) + .try_into() + .expect("Symbol string table overflowed 32 bits"); + *offset += self.mem_sizes.get(part_id::STRTAB); + + // symtab + memory_offsets.increment( + part_id::SYMTAB_LOCAL, + *self.mem_sizes.get(part_id::SYMTAB_LOCAL), + ); + memory_offsets.increment( + part_id::SYMTAB_GLOBAL, + *self.mem_sizes.get(part_id::SYMTAB_GLOBAL), + ); + + strtab_offset_start + } + + pub(crate) fn allocate(&mut self, part_id: PartId, size: u64) { + self.mem_sizes.increment(part_id, size); + } + + /// Allocate resources and update attributes based on a section having been loaded. + fn section_loaded( + &mut self, + part_id: PartId, + header: &object::elf::SectionHeader64, + section: Section, + ) { + self.allocate(part_id, section.capacity()); + self.store_section_attributes(part_id, header); + } + + fn store_section_attributes( + &mut self, + part_id: PartId, + header: &object::elf::SectionHeader64, + ) { + let existing_attributes = self.section_attributes.get_mut(part_id.output_section_id()); + + let new_attributes = header.attributes(); + + if let Some(existing) = existing_attributes { + existing.merge(new_attributes); + } else { + *existing_attributes = Some(new_attributes); + } + } +} + +pub(crate) struct ObjectLayoutState<'data> { + input: InputRef<'data>, + file_id: FileId, + pub(crate) symbol_id_range: SymbolIdRange, + pub(crate) object: &'data File<'data>, + + /// Info about each of our sections. Indexed the same as the sections in the input object. + pub(crate) sections: Vec, + + /// Mapping from sections to their corresponding relocation section. + relocations: object::read::elf::RelocationSections, + + pub(crate) format_specific_layout_state: as ObjectFile<'data>>::FileLayoutState, + + /// Sparse map from section index to relaxation delta details, built during `finalise_sizes` + /// and later transferred to `ObjectLayout`. + section_relax_deltas: RelaxDeltaMap, +} + +#[derive(Debug, Default)] +pub(crate) struct LocalWorkQueue { + /// The index of the worker that owns this queue. + index: usize, + + /// Work that needs to be processed by the worker that owns this queue. + local_work: Vec, +} + +struct DynamicLayoutState<'data> { + object: &'data File<'data>, + input: InputRef<'data>, + file_id: FileId, + symbol_id_range: SymbolIdRange, + lib_name: &'data [u8], + + format_specific_state: as ObjectFile<'data>>::DynamicLayoutState, + + /// Maps from addresses within the shared object to copy relocations at that address. + copy_relocations: HashMap, +} + +struct CopyRelocationInfo { + /// The symbol ID for which we'll actually generate the copy relocation. Initially, this is + /// just the first symbol at a particular address for which we requested a copy relocation, + /// then later we may update it to point to a different symbol if that first symbol was + /// weak. + symbol_id: SymbolId, + + is_weak: bool, +} + +#[derive(Debug)] +pub(crate) struct GroupLayout<'data> { + pub(crate) files: Vec>, + + /// The offset in .dynstr at which we'll start writing. + pub(crate) dynstr_start_offset: u32, + + /// The offset in .strtab at which we'll start writing. + pub(crate) strtab_start_offset: u32, + + pub(crate) mem_sizes: OutputSectionPartMap, + pub(crate) file_sizes: OutputSectionPartMap, + + pub(crate) format_specific: as ObjectFile<'data>>::GroupLayoutExt, +} + +#[derive(Debug)] +pub(crate) struct GroupState<'data> { + queue: LocalWorkQueue, + files: Vec>, + pub(crate) common: CommonGroupState<'data>, + num_symbols: usize, +} + +pub(crate) struct GraphResources<'data, 'scope> { + pub(crate) symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, + + output_sections: &'scope OutputSections<'data>, + + worker_slots: Vec>>, + + errors: Mutex>, + + per_symbol_flags: &'scope AtomicPerSymbolFlags<'scope>, + + /// Sections that we'll keep, even if their total size is zero. + must_keep_sections: OutputSectionMap, + + has_static_tls: AtomicBool, + + has_variant_pcs: AtomicBool, + + uses_tlsld: AtomicBool, + + /// For each OutputSectionId, this tracks a list of sections that should be loaded if that + /// section gets referenced. The sections here will only be those that are eligible for having + /// __start_ / __stop_ symbols. i.e. sections that don't start their names with a ".". + start_stop_sections: OutputSectionMap>, + + /// The number of groups that haven't yet completed activation. + activations_remaining: AtomicUsize, + + /// Groups that cannot be processed until all groups have completed activation. + delay_processing: ArrayQueue>, + + sonames: Sonames<'data>, +} + +struct FinaliseLayoutResources<'scope, 'data> { + symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: &'scope PerSymbolFlags, + output_sections: &'scope OutputSections<'data>, + output_order: &'scope OutputOrder, + section_layouts: &'scope OutputSectionMap, + merged_string_start_addresses: &'scope MergedStringStartAddresses, + merged_strings: &'scope OutputSectionMap>, + dynamic_symbol_definitions: &'scope Vec>, + segment_layouts: &'scope SegmentLayouts, + program_segments: &'scope ProgramSegments, + format_specific: &'scope ElfLayoutProperties, +} + +#[derive(Copy, Clone, Debug)] +enum WorkItem { + /// The symbol's resolution flags have been made non-empty. The object that owns the symbol + /// should perform any additional actions required, e.g. load the section that contains the + /// symbol and process any relocations for that section. + LoadGlobalSymbol(SymbolId), + + /// A direct reference to a dynamic symbol has been encountered. The symbol should be defined in + /// BSS with a copy relocation. + CopyRelocateSymbol(SymbolId), + + /// A request to load a particular section. + LoadSection(SectionLoadRequest), + + /// Requests that the specified symbol be exported as a dynamic symbol. Will be ignored if the + /// object that defines the symbol is not loaded or is itself a shared object. + ExportDynamic(SymbolId), +} + +#[derive(Copy, Clone, Debug)] +struct SectionLoadRequest { + file_id: FileId, + + /// The offset of the section within the file's sections. i.e. the same as + /// object::SectionIndex, but stored as a u32 for compactness. + section_index: u32, +} + +impl WorkItem { + fn file_id<'data>(self, symbol_db: &SymbolDb<'data, crate::elf::File<'data>>) -> FileId { + match self { + WorkItem::LoadGlobalSymbol(s) | WorkItem::CopyRelocateSymbol(s) => { + symbol_db.file_id_for_symbol(s) + } + WorkItem::LoadSection(s) => s.file_id, + WorkItem::ExportDynamic(symbol_id) => symbol_db.file_id_for_symbol(symbol_id), + } + } +} + +impl<'data> ElfLayout<'data> { + pub(crate) fn prelude(&self) -> &PreludeLayout<'data> { + let Some(FileLayout::Prelude(i)) = self.group_layouts.first().and_then(|g| g.files.first()) + else { + panic!("Prelude layout not found at expected offset"); + }; + i + } + + pub(crate) fn args(&self) -> &'data Args { + self.symbol_db.args + } + + pub(crate) fn symbol_debug<'layout>( + &'layout self, + symbol_id: SymbolId, + ) -> SymbolDebug<'layout, 'data, crate::elf::File<'data>> { + self.symbol_db + .symbol_debug(&self.per_symbol_flags, symbol_id) + } + + #[inline(always)] + pub(crate) fn merged_symbol_resolution(&self, symbol_id: SymbolId) -> Option { + self.local_symbol_resolution(self.symbol_db.definition(symbol_id)) + .copied() + .map(|mut res| { + res.flags.merge( + self.symbol_db + .flags_for_symbol(&self.per_symbol_flags, symbol_id), + ); + res + }) + } + + pub(crate) fn local_symbol_resolution(&self, symbol_id: SymbolId) -> Option<&Resolution> { + self.symbol_resolutions.resolutions[symbol_id.as_usize()].as_ref() + } + + pub(crate) fn resolutions_in_range( + &self, + range: SymbolIdRange, + ) -> impl Iterator)> { + self.symbol_resolutions.resolutions[range.as_usize()] + .iter() + .enumerate() + .map(move |(i, res)| (range.offset_to_id(i), res.as_ref())) + } + + pub(crate) fn entry_symbol_address(&self) -> Result { + let Some(symbol_id) = self.prelude().entry_symbol_id else { + if self.symbol_db.output_kind == OutputKind::SharedObject { + // Shared objects don't have an implicit entry point. + return Ok(0); + } + + // There's no entry point specified, set it to the start of .text. This is pretty weird, + // but it's what GNU ld does. + let text_layout = self.section_layouts.get(output_section_id::TEXT); + if text_layout.mem_size == 0 { + crate::error::warning( + "cannot find entry symbol `_start` and .text is empty, not setting entry point", + ); + + return Ok(0); + } + + crate::error::warning(&format!( + "cannot find entry symbol `_start`, defaulting to 0x{}", + text_layout.mem_offset + )); + return Ok(text_layout.mem_offset); + }; + + let resolution = self.local_symbol_resolution(symbol_id).with_context(|| { + format!( + "Entry point symbol was defined, but didn't get loaded. {}", + self.symbol_debug(symbol_id) + ) + })?; + + if !resolution.flags().is_address() && !resolution.flags().is_absolute() { + bail!( + "Entry point must be an address or absolute value. {}", + self.symbol_debug(symbol_id) + ); + } + + Ok(resolution.value()) + } + + pub(crate) fn tls_start_address(&self) -> u64 { + // If we don't have a TLS segment then the value we return won't really matter. + self.segment_layouts + .tls_layout + .as_ref() + .map_or(0, |seg| seg.mem_offset) + } + + /// Returns the memory address of the end of the TLS segment including any padding required to + /// make sure that the TCB will be usize-aligned. + pub(crate) fn tls_end_address(&self) -> u64 { + self.segment_layouts.tls_layout.as_ref().map_or(0, |seg| { + seg.alignment.align_up(seg.mem_offset + seg.mem_size) + }) + } + + /// Returns the memory address of the start of the TLS segment used by the AArch64. + pub(crate) fn tls_start_address_aarch64(&self) -> u64 { + self.segment_layouts.tls_layout.as_ref().map_or(0, |seg| { + // Two words at TP are reserved by the arch. + seg.alignment.align_down(seg.mem_offset - 2 * 8) + }) + } + + pub(crate) fn layout_data(&self) -> linker_layout::Layout { + let files = self + .group_layouts + .iter() + .flat_map(|group| { + group.files.iter().filter_map(|file| match file { + FileLayout::Object(obj) => Some(linker_layout::InputFile { + path: obj.input.file.filename.clone(), + archive_entry: obj.input.entry.as_ref().map(|e| { + linker_layout::ArchiveEntryInfo { + range: e.byte_range(), + identifier: e.identifier.as_slice().to_owned(), + } + }), + sections: obj + .section_resolutions + .iter() + .zip(obj.object.section_iter()) + .zip(&obj.sections) + .map(|((res, section), section_slot)| { + (matches!(section_slot, SectionSlot::Loaded(..)) + && section.flags().is_alloc() + && obj.object.section_size(section).is_ok_and(|s| s > 0)) + .then(|| { + let address = res.address; + let size = match section_slot { + SectionSlot::Loaded(sec) => sec.size, + _ => obj.object.section_size(section).unwrap(), + }; + linker_layout::Section { + mem_range: address..(address + size), + } + }) + }) + .collect(), + temporary: obj.input.file.modifiers.temporary, + }), + _ => None, + }) + }) + .collect(); + linker_layout::Layout { files } + } + + pub(crate) fn flags_for_symbol(&self, symbol_id: SymbolId) -> ValueFlags { + self.symbol_db + .flags_for_symbol(&self.per_symbol_flags, symbol_id) + } + + pub(crate) fn file_layout(&self, file_id: FileId) -> &FileLayout<'data> { + let group_layout = &self.group_layouts[file_id.group()]; + &group_layout.files[file_id.file()] + } + + /// Returns the base address of the global offset table. This needs to be consistent with the + /// symbol `_GLOBAL_OFFSET_TABLE_`. + pub(crate) fn got_base(&self) -> u64 { + let got_layout = self.section_layouts.get(output_section_id::GOT); + got_layout.mem_offset + } + + /// Returns whether we're going to output the .gnu.version section. + pub(crate) fn gnu_version_enabled(&self) -> bool { + self.section_part_layouts + .get(part_id::GNU_VERSION) + .file_size + > 0 + } +} + +fn layout_sections( + output_sections: &OutputSections, + section_part_layouts: &OutputSectionPartMap, +) -> OutputSectionMap { + section_part_layouts.merge_parts(|section_id, layouts| { + let info = output_sections.section_infos.get(section_id); + let mut file_offset = usize::MAX; + let mut mem_offset = u64::MAX; + let mut file_end = 0; + let mut mem_end = 0; + let mut alignment = info.min_alignment; + + for part in layouts { + file_offset = file_offset.min(part.file_offset); + mem_offset = mem_offset.min(part.mem_offset); + file_end = file_end.max(part.file_offset + part.file_size); + mem_end = mem_end.max(part.mem_offset + part.mem_size); + if part.mem_size > 0 { + alignment = alignment.max(part.alignment); + } + } + OutputRecordLayout { + file_size: file_end - file_offset, + mem_size: mem_end - mem_offset, + alignment, + file_offset, + mem_offset, + } + }) +} + +fn merge_secondary_parts( + output_sections: &OutputSections, + section_layouts: &mut OutputSectionMap, +) { + for (id, info) in output_sections.ids_with_info() { + if let SectionKind::Secondary(primary_id) = info.kind { + let secondary_layout = take(section_layouts.get_mut(id)); + section_layouts.get_mut(primary_id).merge(&secondary_layout); + } + } +} + +fn compute_start_offsets_by_group( + group_states: &[GroupState<'_>], + mut mem_offsets: OutputSectionPartMap, +) -> Vec> { + timing_phase!("Compute per-group start offsets"); + + group_states + .iter() + .map(|group| { + let group_mem_starts = mem_offsets.clone(); + mem_offsets.merge(&group.common.mem_sizes); + group_mem_starts + }) + .collect_vec() +} + +fn compute_symbols_and_layouts<'data>( + group_states: Vec>, + starting_mem_offsets_by_group: Vec>, + per_group_res_writers: &mut [sharded_vec_writer::Shard>], + resources: &FinaliseLayoutResources<'_, 'data>, +) -> Result>> { + timing_phase!("Assign symbol addresses"); + + group_states + .into_par_iter() + .zip(starting_mem_offsets_by_group) + .zip(per_group_res_writers) + .map(|((state, mut memory_offsets), symbols_out)| { + verbose_timing_phase!("Assign addresses for group"); + + if cfg!(debug_assertions) { + let offset_verifier = crate::verification::OffsetVerifier::new( + &memory_offsets, + &state.common.mem_sizes, + ); + + // Make sure that ignored offsets really aren't used by `finalise_layout` by setting + // them to an arbitrary value. If they are used, we'll quickly notice. + crate::verification::clear_ignored(&mut memory_offsets); + + let layout = state.finalise_layout(&mut memory_offsets, symbols_out, resources)?; + + offset_verifier.verify( + &memory_offsets, + resources.output_sections, + resources.output_order, + &layout.files, + )?; + Ok(layout) + } else { + state.finalise_layout(&mut memory_offsets, symbols_out, resources) + } + }) + .collect() +} + +fn compute_segment_layout( + section_layouts: &OutputSectionMap, + output_sections: &OutputSections, + output_order: &OutputOrder, + program_segments: &ProgramSegments, + header_info: &HeaderInfo, + args: &Args, +) -> Result { + #[derive(Clone)] + struct Record { + segment_id: ProgramSegmentId, + file_start: usize, + file_end: usize, + mem_start: u64, + mem_end: u64, + alignment: Alignment, + } + + timing_phase!("Compute segment layouts"); + + use output_section_id::OrderEvent; + let mut complete = Vec::with_capacity(program_segments.len()); + let mut active_segments = vec![None; program_segments.len()]; + + for event in output_order { + match event { + OrderEvent::SegmentStart(segment_id) => { + if program_segments.is_stack_segment(segment_id) { + // STACK segment is special as it does not contain any section. + active_segments[segment_id.as_usize()] = Some(Record { + segment_id, + file_start: 0, + file_end: 0, + mem_start: 0, + mem_end: args.z_stack_size.map_or(0, |size| size.get()), + alignment: alignment::MIN, + }); + } else { + active_segments[segment_id.as_usize()] = Some(Record { + segment_id, + file_start: usize::MAX, + file_end: 0, + mem_start: u64::MAX, + mem_end: 0, + alignment: alignment::MIN, + }); + } + } + OrderEvent::SegmentEnd(segment_id) => { + let record = active_segments[segment_id.as_usize()] + .take() + .context("SegmentEnd without matching SegmentStart")?; + + complete.push(record); + } + OrderEvent::Section(section_id) => { + let section_layout = section_layouts.get(section_id); + let merge_target = output_sections.primary_output_section(section_id); + + // Skip all ignored sections that will not end up in the final file. + if section_layout.file_size == 0 + && section_layout.mem_size == 0 + && output_sections.output_section_indexes[merge_target.as_usize()].is_none() + { + continue; + } + let section_flags = output_sections.section_flags(merge_target); + let section_info = output_sections.output_info(section_id); + + if active_segments.iter().all(|s| s.is_none()) { + ensure!( + section_layout.mem_offset == 0, + "Expected zero address for section {} not present in any program segment.", + output_sections.section_debug(section_id) + ); + ensure!( + !section_flags.contains(shf::ALLOC), + "Section with SHF_ALLOC flag {} not present in any program segment.", + output_sections.section_debug(section_id) + ); + } else { + // TODO: Remove the NOTE exception. Non-alloc sections should be placed outside + // of program segments. NOTE sections are sometimes alloc and sometimes not. + // Alloc NOTE sections should be placed within a LOAD segment and within a NOTE + // segment. Non-alloc NOTE sections shouldn't be in any segment. + + // The .riscv.attributes section is non-alloc but is expected to be put into a + // RISCV_ATTRIBUTES segment. + if [NOTE, RISCV_ATTRIBUTES].contains(§ion_info.ty) { + } else { + // All segments should only cover sections that are allocated and have a + // non-zero address. + ensure!( + section_layout.mem_offset != 0 || merge_target == FILE_HEADER, + "Missing memory offset for section {} present in a program segment.", + output_sections.section_debug(section_id), + ); + ensure!( + section_flags.contains(shf::ALLOC), + "Missing SHF_ALLOC section flag for section {} present in a program \ + segment.", + output_sections.section_debug(section_id) + ); + } + for opt_rec in &mut active_segments { + let Some(rec) = opt_rec.as_mut() else { + continue; + }; + + rec.file_start = rec.file_start.min(section_layout.file_offset); + rec.mem_start = rec.mem_start.min(section_layout.mem_offset); + rec.file_end = rec + .file_end + .max(section_layout.file_offset + section_layout.file_size); + rec.mem_end = rec + .mem_end + .max(section_layout.mem_offset + section_layout.mem_size); + rec.alignment = rec.alignment.max(section_layout.alignment); + } + } + } + OrderEvent::SetLocation(_) => {} + } + } + + complete.sort_by_key(|r| r.segment_id); + + assert_eq!(complete.len(), program_segments.len()); + let mut tls_layout = None; + + let mut segments: Vec = header_info + .active_segment_ids + .iter() + .map(|&id| { + let r = &complete[id.as_usize()]; + + let sizes = OutputRecordLayout { + file_size: r.file_end - r.file_start, + mem_size: r.mem_end - r.mem_start, + alignment: r.alignment, + file_offset: r.file_start, + mem_offset: r.mem_start, + }; + + if program_segments.is_tls_segment(id) { + tls_layout = Some(sizes); + } + + SegmentLayout { id, sizes } + }) + .collect(); + + segments.sort_by_key(|s| program_segments.order_key(s.id, s.sizes.mem_offset)); + + Ok(SegmentLayouts { + segments, + tls_layout, + }) +} + +fn compute_total_section_part_sizes( + group_states: &mut [GroupState], + output_sections: &mut OutputSections, + output_order: &OutputOrder, + program_segments: &ProgramSegments, + per_symbol_flags: &mut PerSymbolFlags, + must_keep_sections: OutputSectionMap, + resources: &FinaliseSizesResources, +) -> Result> { + timing_phase!("Compute total section sizes"); + + let mut total_sizes: OutputSectionPartMap = output_sections.new_part_map(); + for group_state in group_states.iter() { + total_sizes.merge(&group_state.common.mem_sizes); + } + + // We need to apply late-stage adjustments for the epilogue before we do so for the prelude, + // since the prelude needs to know if the .hash section will be written, which is decided by the + // epilogue. + let last_group = group_states.last_mut().unwrap(); + let Some(FileLayoutState::Epilogue(epilogue)) = last_group.files.last_mut() else { + unreachable!(); + }; + + epilogue.apply_late_size_adjustments(&mut last_group.common, &mut total_sizes, resources)?; + + let first_group = group_states.first_mut().unwrap(); + let Some(FileLayoutState::Prelude(prelude)) = first_group.files.first_mut() else { + unreachable!(); + }; + + prelude.apply_late_size_adjustments( + &mut first_group.common, + &mut total_sizes, + must_keep_sections, + output_sections, + output_order, + program_segments, + per_symbol_flags, + resources, + )?; + + Ok(total_sizes) +} + +/// Propagates attributes from input sections to the output sections into which they were placed. +fn propagate_section_attributes(group_states: &[GroupState], output_sections: &mut OutputSections) { + timing_phase!("Propagate section attributes"); + + for group_state in group_states { + group_state + .common + .section_attributes + .for_each(|section_id, attributes| { + if let Some(attributes) = attributes { + attributes.apply(output_sections, section_id); + } + }); + } +} + +/// This is similar to computing start addresses, but is used for things that aren't addressable, +/// but which need to be unique. It's non parallel. It could potentially be run in parallel with +/// some of the stages that run after it, that don't need access to the file states. +fn apply_non_addressable_indexes<'data>( + group_states: &mut [GroupState], + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, +) -> Result { + timing_phase!("Apply non-addressable indexes"); + + let mut indexes = ::NonAddressableIndexes::new(symbol_db); + + let mut counts = ::NonAddressableCounts::default(); + + for g in group_states.iter_mut() { + for s in &mut g.files { + match s { + FileLayoutState::Dynamic(s) => { + s.object.apply_non_addressable_indexes_dynamic( + &mut indexes, + &mut counts, + &mut s.format_specific_state, + )?; + } + FileLayoutState::Epilogue(s) => { + as ObjectFile<'data>>::apply_non_addressable_indexes_epilogue( + &mut counts, + &mut s.format_specific, + ); + } + _ => {} + } + } + } + + as ObjectFile<'data>>::apply_non_addressable_indexes( + symbol_db, + &counts, + group_states.iter_mut().map(|g| &mut g.common.mem_sizes), + ); + + Ok(counts) +} + +/// Returns the starting memory address for each alignment within each segment. +fn starting_memory_offsets( + section_layouts: &OutputSectionPartMap, +) -> OutputSectionPartMap { + timing_phase!("Compute per-alignment offsets"); + + section_layouts.map(|_, rec| rec.mem_offset) +} + +#[derive(Default)] +struct WorkerSlot<'data> { + work: Vec, + worker: Option>, +} + +#[derive(Debug)] +struct GcOutputs<'data> { + group_states: Vec>, + must_keep_sections: OutputSectionMap, + has_static_tls: bool, + has_variant_pcs: bool, +} + +struct GroupActivationInputs<'data> { + resolved: ResolvedGroup<'data, crate::elf::File<'data>>, + num_symbols: usize, + group_index: usize, +} + +impl<'data> GroupActivationInputs<'data> { + fn activate_group<'scope, P: ElfPlatform<'data>>( + self, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) { + let GroupActivationInputs { + resolved, + num_symbols, + group_index, + } = self; + + let files = resolved + .files + .into_iter() + .map(|file| file.create_layout_state()) + .collect(); + let mut group = GroupState { + queue: LocalWorkQueue::new(group_index), + num_symbols, + files, + common: CommonGroupState::new(resources.output_sections), + }; + + let mut should_delay_processing = false; + + for file in &mut group.files { + let r = activate::

(&mut group.common, file, &mut group.queue, resources, scope) + .with_context(|| format!("Failed to activate {file}")); + + // SyntheticSymbols can't be processed until all groups have completed activation, since + // it can read from `start_stop_sections` which gets populated by other objects during + // activation. + should_delay_processing |= matches!(file, FileLayoutState::SyntheticSymbols(_)); + + if let Err(error) = r { + resources.errors.lock().unwrap().push(error); + } + } + + if should_delay_processing { + resources.delay_processing.push(group).unwrap(); + } else { + group.do_pending_work::

(resources, scope); + } + + let remaining = resources + .activations_remaining + .fetch_sub(1, atomic::Ordering::Relaxed) + - 1; + + if remaining == 0 { + while let Some(group) = resources.delay_processing.pop() { + group.do_pending_work::

(resources, scope); + } + } + } +} + +fn find_required_sections<'data, P: ElfPlatform<'data>>( + groups_in: Vec>>, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: &AtomicPerSymbolFlags, + output_sections: &OutputSections<'data>, + sonames: Sonames<'data>, +) -> Result> { + timing_phase!("Find required sections"); + + let num_groups = groups_in.len(); + + let mut worker_slots = Vec::with_capacity(num_groups); + worker_slots.resize_with(num_groups, || { + Mutex::new(WorkerSlot { + work: Default::default(), + worker: None, + }) + }); + + let resources = GraphResources { + symbol_db, + output_sections, + worker_slots, + errors: Mutex::new(Vec::new()), + per_symbol_flags, + must_keep_sections: output_sections.new_section_map(), + has_static_tls: AtomicBool::new(false), + has_variant_pcs: AtomicBool::new(false), + uses_tlsld: AtomicBool::new(false), + start_stop_sections: output_sections.new_section_map(), + activations_remaining: AtomicUsize::new(num_groups), + delay_processing: ArrayQueue::new(1), + sonames, + }; + let resources_ref = &resources; + + rayon::in_place_scope(|scope| { + queue_initial_group_processing::

(groups_in, symbol_db, resources_ref, scope); + }); + + let mut errors: Vec = take(resources.errors.lock().unwrap().as_mut()); + // TODO: Figure out good way to report more than one error. + if let Some(error) = errors.pop() { + return Err(error); + } + + let mut group_states = unwrap_worker_states(&resources.worker_slots); + let must_keep_sections = resources.must_keep_sections.into_map(|v| v.into_inner()); + + as ObjectFile<'data>>::finalise_find_required_sections(&group_states); + + // Give our prelude a chance to tie up a few last sizes while we still have access to + // `resources`. + let prelude_group = &mut group_states[0]; + let FileLayoutState::Prelude(prelude) = &mut prelude_group.files[0] else { + unreachable!("Prelude must be first"); + }; + prelude.pre_finalise_sizes( + &mut prelude_group.common, + &resources.uses_tlsld, + resources.symbol_db.args, + resources.symbol_db.output_kind, + ); + + Ok(GcOutputs { + group_states, + must_keep_sections, + has_static_tls: resources.has_static_tls.load(atomic::Ordering::Relaxed), + has_variant_pcs: resources.has_variant_pcs.load(atomic::Ordering::Relaxed), + }) +} + +fn queue_initial_group_processing< + 'data, + 'scope, + P: ElfPlatform<'data>, +>( + groups_in: Vec>>, + symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, +) { + verbose_timing_phase!("Create worker slots"); + + assert_eq!(groups_in.len(), symbol_db.groups.len()); + + groups_in + .into_iter() + .enumerate() + .zip(&symbol_db.groups) + .for_each(|((group_index, resolved), group)| { + scope.spawn(move |scope| { + verbose_timing_phase!("Activate group"); + let inputs = GroupActivationInputs { + resolved, + num_symbols: group.num_symbols(), + group_index, + }; + inputs.activate_group::

(resources, scope); + }); + }); +} + +fn unwrap_worker_states<'data>( + worker_slots: &[Mutex>], +) -> Vec> { + worker_slots + .iter() + .filter_map(|w| w.lock().unwrap().worker.take()) + .collect() +} + +impl<'data> GroupState<'data> { + /// Does work until there's nothing left in the queue, then returns our worker to its slot and + /// shuts down. + fn do_pending_work<'scope, P: ElfPlatform<'data>>( + mut self, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) { + loop { + while let Some(work_item) = self.queue.local_work.pop() { + let file_id = work_item.file_id(resources.symbol_db); + let file = &mut self.files[file_id.file()]; + if let Err(error) = file.do_work::

( + &mut self.common, + work_item, + resources, + &mut self.queue, + scope, + ) { + resources.report_error(error); + return; + } + } + { + let mut slot = resources.worker_slots[self.queue.index].lock().unwrap(); + if slot.work.is_empty() { + slot.worker = Some(self); + return; + } + swap(&mut slot.work, &mut self.queue.local_work); + }; + } + } + + fn finalise_sizes( + &mut self, + output_sections: &OutputSections, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources<'data, '_>, + ) -> Result { + for file_state in &mut self.files { + file_state.finalise_sizes( + &mut self.common, + output_sections, + per_symbol_flags, + resources, + )?; + } + + self.common.validate_sizes()?; + Ok(()) + } + + fn finalise_layout( + self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut sharded_vec_writer::Shard>, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result> { + let format_specific = + as ObjectFile<'data>>::finalise_group_layout(memory_offsets); + let files = self + .files + .into_iter() + .map(|file| file.finalise_layout(memory_offsets, resolutions_out, resources)) + .collect::>>()?; + + let strtab_start_offset = self + .common + .finalise_layout(memory_offsets, resources.section_layouts); + let dynstr_start_offset = (memory_offsets.get(part_id::DYNSTR) + - resources + .section_layouts + .get(output_section_id::DYNSTR) + .mem_offset) as u32; + memory_offsets.increment(part_id::DYNSTR, *self.common.mem_sizes.get(part_id::DYNSTR)); + + Ok(GroupLayout { + files, + strtab_start_offset, + dynstr_start_offset, + file_sizes: compute_file_sizes(&self.common.mem_sizes, resources.output_sections), + mem_sizes: self.common.mem_sizes, + format_specific, + }) + } +} + +fn activate<'data, 'scope, P: ElfPlatform<'data>>( + common: &mut CommonGroupState<'data>, + file: &mut FileLayoutState<'data>, + queue: &mut LocalWorkQueue, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, +) -> Result { + match file { + FileLayoutState::Object(s) => s.activate::

(common, resources, queue, scope)?, + FileLayoutState::Prelude(s) => s.activate::

(common, resources, queue, scope)?, + FileLayoutState::Dynamic(s) => s.activate::

(common, resources, queue, scope)?, + FileLayoutState::LinkerScript(s) => s.activate(common, resources)?, + FileLayoutState::Epilogue(_) => {} + FileLayoutState::NotLoaded(_) => {} + FileLayoutState::SyntheticSymbols(_) => {} + } + Ok(()) +} + +impl LocalWorkQueue { + #[inline(always)] + fn send_work<'data, 'scope, P: ElfPlatform<'data>>( + &mut self, + resources: &'scope GraphResources<'data, '_>, + file_id: FileId, + work: WorkItem, + scope: &Scope<'scope>, + ) { + if file_id.group() == self.index { + self.local_work.push(work); + } else { + resources.send_work::

(file_id, work, resources, scope); + } + } + + fn new(index: usize) -> LocalWorkQueue { + Self { + index, + local_work: Default::default(), + } + } + + #[inline(always)] + fn send_symbol_request<'data, 'scope, P: ElfPlatform<'data>>( + &mut self, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) { + debug_assert!(resources.symbol_db.is_canonical(symbol_id)); + let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); + self.send_work::

( + resources, + symbol_file_id, + WorkItem::LoadGlobalSymbol(symbol_id), + scope, + ); + } + + fn send_copy_relocation_request< + 'data, + 'scope, + P: ElfPlatform<'data>, + >( + &mut self, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) { + debug_assert!(resources.symbol_db.is_canonical(symbol_id)); + let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); + self.send_work::

( + resources, + symbol_file_id, + WorkItem::CopyRelocateSymbol(symbol_id), + scope, + ); + } +} + +impl<'data> GraphResources<'data, '_> { + fn report_error(&self, error: Error) { + self.errors.lock().unwrap().push(error); + } + + /// Sends all work in `work` to the worker for `file_id`. Leaves `work` empty so that it can be + /// reused. + #[inline(always)] + fn send_work<'scope, P: ElfPlatform<'data>>( + &self, + file_id: FileId, + work: WorkItem, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) { + let worker; + { + let mut slot = self.worker_slots[file_id.group()].lock().unwrap(); + worker = slot.worker.take(); + slot.work.push(work); + }; + if let Some(worker) = worker { + scope.spawn(|scope| { + verbose_timing_phase!("Work with object"); + worker.do_pending_work::

(resources, scope); + }); + } + } + + fn local_flags_for_symbol(&self, symbol_id: SymbolId) -> ValueFlags { + self.per_symbol_flags.flags_for_symbol(symbol_id) + } + + fn symbol_debug<'a>( + &'a self, + symbol_id: SymbolId, + ) -> SymbolDebug<'a, 'data, crate::elf::File<'data>> { + self.symbol_db + .symbol_debug(self.per_symbol_flags, symbol_id) + } + + fn keep_section(&self, section_id: OutputSectionId) { + let keep = self.must_keep_sections.get(section_id); + + // We only write after reading and determining that we need to write. This likely makes the + // case where we do write slower, but the case where we don't write faster and also avoids + // gaining exclusive access to the cache line unless necessary. This has a small but + // measurable performance effect. + if !keep.load(atomic::Ordering::Relaxed) { + keep.store(true, atomic::Ordering::Relaxed); + } + } +} + +impl<'data> FileLayoutState<'data> { + fn finalise_sizes( + &mut self, + common: &mut CommonGroupState<'data>, + output_sections: &OutputSections, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources<'data, '_>, + ) -> Result { + match self { + FileLayoutState::Object(s) => { + s.finalise_sizes(common, output_sections, per_symbol_flags, resources); + s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; + } + FileLayoutState::Dynamic(s) => { + s.finalise_sizes(common)?; + s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; + } + FileLayoutState::Prelude(s) => { + PreludeLayoutState::finalise_sizes(common, resources.merged_strings); + s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; + } + FileLayoutState::SyntheticSymbols(s) => { + s.finalise_sizes(common, per_symbol_flags, resources)?; + s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; + } + FileLayoutState::Epilogue(s) => { + s.finalise_sizes(common, resources); + } + FileLayoutState::LinkerScript(s) => { + s.finalise_sizes(common, per_symbol_flags, resources)?; + s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; + } + FileLayoutState::NotLoaded(_) => {} + } + + as ObjectFile<'data>>::finalise_sizes_all( + &mut common.mem_sizes, + resources.symbol_db, + ); + + Ok(()) + } + + fn do_work<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + work_item: WorkItem, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + match work_item { + WorkItem::LoadGlobalSymbol(symbol_id) => self + .handle_symbol_request::

(common, symbol_id, resources, queue, scope) + .with_context(|| { + format!( + "Failed to load {} from {self}", + resources.symbol_debug(symbol_id), + ) + }), + WorkItem::CopyRelocateSymbol(symbol_id) => match self { + FileLayoutState::Dynamic(state) => state.copy_relocate_symbol(symbol_id, resources), + + _ => { + bail!( + "Internal error: ExportCopyRelocation sent to non-dynamic object for: {}", + resources.symbol_debug(symbol_id) + ) + } + }, + WorkItem::LoadSection(request) => match self { + FileLayoutState::Object(object_layout_state) => object_layout_state + .handle_section_load_request::

( + common, + resources, + queue, + request.section_index(), + scope, + ), + _ => bail!("Request to load section from non-object: {self}"), + }, + WorkItem::ExportDynamic(symbol_id) => match self { + FileLayoutState::Object(object) => { + object.export_dynamic::

(common, symbol_id, resources, queue, scope) + } + _ => { + // Non-loaded and dynamic objects don't do anything in response to a request to + // export a dynamic symbol. + Ok(()) + } + }, + } + } + + fn handle_symbol_request<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + match self { + FileLayoutState::Object(state) => { + state.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + FileLayoutState::Prelude(state) => { + state.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + FileLayoutState::Dynamic(state) => { + state.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + FileLayoutState::LinkerScript(_) => {} + FileLayoutState::NotLoaded(_) => {} + FileLayoutState::SyntheticSymbols(state) => { + state.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + FileLayoutState::Epilogue(_) => { + // The epilogue doesn't define symbols. In fact, it isn't even created until after + // the GC phase graph traversal. + unreachable!(); + } + } + Ok(()) + } + + fn finalise_layout( + self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut sharded_vec_writer::Shard>, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result> { + let resolutions_out = &mut ResolutionWriter { resolutions_out }; + let file_layout = match self { + Self::Object(s) => { + let _span = tracing::debug_span!( + "finalise_layout", + file = %s.input + ) + .entered(); + FileLayout::Object(s.finalise_layout(memory_offsets, resolutions_out, resources)?) + } + Self::Prelude(s) => FileLayout::Prelude(s.finalise_layout( + memory_offsets, + resolutions_out, + resources, + )?), + Self::Epilogue(s) => { + FileLayout::Epilogue(s.finalise_layout(memory_offsets, resources)?) + } + Self::SyntheticSymbols(s) => FileLayout::SyntheticSymbols(s.finalise_layout( + memory_offsets, + resolutions_out, + resources, + )?), + Self::Dynamic(s) => FileLayout::Dynamic(s.finalise_layout( + memory_offsets, + resolutions_out, + resources, + )?), + Self::LinkerScript(s) => { + s.finalise_layout(memory_offsets, resolutions_out, resources)?; + FileLayout::LinkerScript(s) + } + Self::NotLoaded(s) => { + for _ in 0..s.symbol_id_range.len() { + resolutions_out.write(None)?; + } + FileLayout::NotLoaded + } + }; + Ok(file_layout) + } +} + +fn compute_file_sizes( + mem_sizes: &OutputSectionPartMap, + output_sections: &OutputSections<'_>, +) -> OutputSectionPartMap { + mem_sizes.map(|part_id, size| { + if output_sections.has_data_in_file(part_id.output_section_id()) { + *size as usize + } else { + 0 + } + }) +} + +impl std::fmt::Display for PreludeLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt("", f) + } +} + +impl std::fmt::Display for EpilogueLayoutState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt("", f) + } +} + +impl std::fmt::Display for SyntheticSymbolsLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt("", f) + } +} + +impl std::fmt::Display for LinkerScriptLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f) + } +} + +impl std::fmt::Display for FileLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FileLayoutState::Object(s) => std::fmt::Display::fmt(s, f), + FileLayoutState::Dynamic(s) => std::fmt::Display::fmt(s, f), + FileLayoutState::LinkerScript(s) => std::fmt::Display::fmt(s, f), + FileLayoutState::Prelude(_) => std::fmt::Display::fmt("", f), + FileLayoutState::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), + FileLayoutState::NotLoaded(_) => std::fmt::Display::fmt("", f), + FileLayoutState::Epilogue(_) => std::fmt::Display::fmt("", f), + } + } +} + +impl std::fmt::Display for FileLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Object(s) => std::fmt::Display::fmt(s, f), + Self::Dynamic(s) => std::fmt::Display::fmt(s, f), + Self::LinkerScript(s) => std::fmt::Display::fmt(s, f), + Self::Prelude(_) => std::fmt::Display::fmt("", f), + Self::Epilogue(_) => std::fmt::Display::fmt("", f), + Self::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), + Self::NotLoaded => std::fmt::Display::fmt("", f), + } + } +} + +impl std::fmt::Display for GroupLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.files.len() == 1 { + self.files[0].fmt(f) + } else { + write!( + f, + "Group with {} files. Rerun with {}=1", + self.files.len(), + crate::args::consts::FILES_PER_GROUP_ENV + ) + } + } +} + +impl std::fmt::Display for GroupState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.files.len() == 1 { + self.files[0].fmt(f) + } else { + write!( + f, + "Group with {} files. Rerun with {}=1", + self.files.len(), + crate::args::consts::FILES_PER_GROUP_ENV + ) + } + } +} + +impl std::fmt::Debug for FileLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self, f) + } +} + +impl std::fmt::Display for ObjectLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f)?; + // TODO: This is mostly for debugging use. Consider only showing this if some environment + // variable is set, or only in debug builds. + write!(f, " ({})", self.file_id()) + } +} + +impl std::fmt::Display for DynamicLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f)?; + write!(f, " ({})", self.file_id()) + } +} + +impl std::fmt::Display for DynamicLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f)?; + write!(f, " ({})", self.file_id) + } +} + +impl std::fmt::Display for ObjectLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f)?; + // TODO: This is mostly for debugging use. Consider only showing this if some environment + // variable is set, or only in debug builds. + write!(f, " ({})", self.file_id) + } +} + +impl Section { + fn create( + header: &crate::elf::SectionHeader, + object_state: &mut ObjectLayoutState, + section_index: object::SectionIndex, + part_id: PartId, + ) -> Result

{ + let size = object_state.object.section_size(header)?; + let section = Section { + index: section_index, + part_id, + size, + flags: ValueFlags::empty(), + is_writable: header.flags().is_writable(), + }; + Ok(section) + } + + /// Returns whether to reverse the contents of this section. This is true for .ctors/.dtors + /// sections. + pub(crate) fn should_reverse_contents( + &self, + file: &crate::elf::File, + output_sections: &OutputSections, + ) -> bool { + // Getting the section name is expensive, so we only do it when the output section is + // .init_array / .fini_array. + let section_id = output_sections.primary_output_section(self.part_id.output_section_id()); + if section_id != output_section_id::INIT_ARRAY + && section_id != output_section_id::FINI_ARRAY + { + return false; + } + + file.section(self.index) + .and_then(|header| file.section_name(header)) + .is_ok_and(|section_name| { + // .ctors and .dtors sections need their contents reversed when merged into + // .init_array/.fini_array + section_name.starts_with(secnames::CTORS_SECTION_NAME) + || section_name.starts_with(secnames::DTORS_SECTION_NAME) + }) + } +} + +#[inline(always)] +pub(crate) fn process_relocation< + 'data, + 'scope, + P: ElfPlatform<'data>, + R: Relocation, +>( + object: &ObjectLayoutState<'data>, + common: &mut CommonGroupState, + rel: &R, + section: &object::elf::SectionHeader64, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + is_debug_section: bool, + scope: &Scope<'scope>, +) -> Result { + let args = resources.symbol_db.args; + let mut next_modifier = RelocationModifier::Normal; + if let Some(local_sym_index) = rel.symbol() { + let symbol_db = resources.symbol_db; + let local_symbol_id = object.symbol_id_range.input_to_id(local_sym_index); + let symbol_id = symbol_db.definition(local_symbol_id); + let mut flags = resources.local_flags_for_symbol(symbol_id); + flags.merge(resources.local_flags_for_symbol(local_symbol_id)); + let rel_offset = rel.offset(); + let r_type = rel.raw_type(); + let section_flags = SectionFlags::from_header(section); + + let rel_info = if let Some(relaxation) = P::new_relaxation( + r_type, + object.object.raw_section_data(section)?, + rel_offset, + flags, + symbol_db.output_kind, + section_flags, + true, + None, + ) + .filter(|relaxation| args.relax || relaxation.is_mandatory()) + { + next_modifier = relaxation.next_modifier(); + relaxation.rel_info() + } else { + P::relocation_from_raw(r_type)? + }; + + let section_is_writable = section_flags.is_writable(); + let mut flags_to_add = resolution_flags(rel_info.kind); + + if !section_flags.contains(shf::ALLOC) { + // Non-alloc sections never get dynamic relocations, so there's nothing to do here. + } else if rel_info.kind.is_tls() { + if does_relocation_require_static_tls(rel_info.kind) { + resources + .has_static_tls + .store(true, atomic::Ordering::Relaxed); + } + + if needs_tlsld(rel_info.kind) && !resources.uses_tlsld.load(atomic::Ordering::Relaxed) { + resources.uses_tlsld.store(true, atomic::Ordering::Relaxed); + } + } else if flags_to_add.needs_direct() && flags.is_interposable() { + if section_is_writable { + common.allocate(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } else if flags.is_function() { + // Create a PLT entry for the function and refer to that instead. + flags_to_add.remove(ValueFlags::DIRECT); + flags_to_add |= ValueFlags::PLT | ValueFlags::GOT; + } else if !flags.is_absolute() { + match args.copy_relocations { + crate::args::CopyRelocations::Allowed => { + flags_to_add |= ValueFlags::COPY_RELOCATION; + } + crate::args::CopyRelocations::Disallowed(reason) => { + // We don't at present support text relocations, so if we can't apply a copy + // relocation, we error instead. + bail!( + "Direct relocation ({}) to dynamic symbol from non-writable section, \ + but copy relocations are disabled because {reason}. {}", + P::rel_type_to_string(r_type), + resources.symbol_debug(symbol_id), + ); + } + } + } + } else if flags.is_ifunc() + && rel_info.kind == RelocationKind::Absolute + && section_is_writable + && symbol_db.output_kind.is_relocatable() + { + common.allocate(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); + } else if symbol_db.output_kind.is_relocatable() + && rel_info.kind == RelocationKind::Absolute + && flags.is_address() + { + if section_is_writable { + common.allocate(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); + } else if !is_debug_section { + bail!( + "Cannot apply relocation {} to read-only section. \ + Please recompile with -fPIC or link with -no-pie", + P::rel_type_to_string(r_type), + ); + } + } + + // For ifunc symbols with GOT-relative references (like R_X86_64_GOTPCRELX), we need a + // separate GOT entry for address equality. The main GOT entry will be used by the PLT stub + // with an IRELATIVE relocation, while this extra entry will contain the PLT stub address so + // that all references to the ifunc return the same address. + + let relocation_needs_got = flags_to_add.needs_got(); + + if flags.is_ifunc() && !symbol_db.output_kind.is_static_executable() { + flags_to_add |= ValueFlags::GOT | ValueFlags::PLT; + } + + if flags.is_ifunc() && relocation_needs_got && !symbol_db.output_kind.is_relocatable() { + flags_to_add |= ValueFlags::IFUNC_GOT_FOR_ADDRESS; + } + + let atomic_flags = &resources.per_symbol_flags.get_atomic(symbol_id); + let previous_flags = atomic_flags.fetch_or(flags_to_add); + + if !previous_flags.has_resolution() { + if flags.is_ifunc() && symbol_db.output_kind.is_static_executable() { + atomic_flags.fetch_or(ValueFlags::GOT | ValueFlags::PLT); + } + + queue.send_symbol_request::

(symbol_id, resources, scope); + if should_emit_undefined_error( + object.object.symbol(local_sym_index)?, + object.file_id, + symbol_db.file_id_for_symbol(symbol_id), + flags, + args, + symbol_db.output_kind, + ) { + let symbol_name = symbol_db.symbol_name_for_display(symbol_id); + let source_info = + P::get_source_info(object.object, &object.relocations, section, rel_offset) + .context("Failed to get source info")?; + + if args.error_unresolved_symbols { + resources.report_error(error!( + "Undefined symbol {symbol_name}, referenced by {}\n {}", + source_info, object.input, + )); + } else { + crate::error::warning(&format!( + "Undefined symbol {symbol_name}, referenced by {}\n {}", + source_info, object.input, + )); + } + } + } + + if flags_to_add.needs_copy_relocation() && !previous_flags.needs_copy_relocation() { + queue.send_copy_relocation_request::

(symbol_id, resources, scope); + } + } + Ok(next_modifier) +} + +/// Returns whether the supplied relocation type requires static TLS. If true and we're writing a +/// shared object, then the STATIC_TLS will be set in the shared object which is a signal to the +/// runtime loader that the shared object cannot be loaded at runtime (e.g. with dlopen). +fn does_relocation_require_static_tls(rel_kind: RelocationKind) -> bool { + resolution_flags(rel_kind) == ValueFlags::GOT_TLS_OFFSET +} + +fn resolution_flags(rel_kind: RelocationKind) -> ValueFlags { + match rel_kind { + RelocationKind::PltRelative | RelocationKind::PltRelGotBase => { + ValueFlags::PLT | ValueFlags::GOT + } + RelocationKind::Got + | RelocationKind::GotRelGotBase + | RelocationKind::GotRelative + | RelocationKind::GotRelativeLoongArch64 => ValueFlags::GOT, + RelocationKind::GotTpOff + | RelocationKind::GotTpOffLoongArch64 + | RelocationKind::GotTpOffGot + | RelocationKind::GotTpOffGotBase => ValueFlags::GOT_TLS_OFFSET, + RelocationKind::TlsGd | RelocationKind::TlsGdGot | RelocationKind::TlsGdGotBase => { + ValueFlags::GOT_TLS_MODULE + } + RelocationKind::TlsDesc + | RelocationKind::TlsDescLoongArch64 + | RelocationKind::TlsDescGot + | RelocationKind::TlsDescGotBase + | RelocationKind::TlsDescCall => ValueFlags::GOT_TLS_DESCRIPTOR, + RelocationKind::TlsLd | RelocationKind::TlsLdGot | RelocationKind::TlsLdGotBase => { + ValueFlags::empty() + } + RelocationKind::Absolute + | RelocationKind::AbsoluteSet + | RelocationKind::AbsoluteSetWord6 + | RelocationKind::AbsoluteAddition + | RelocationKind::AbsoluteAdditionWord6 + | RelocationKind::AbsoluteSubtraction + | RelocationKind::AbsoluteSubtractionWord6 + | RelocationKind::Relative + | RelocationKind::RelativeRiscVLow12 + | RelocationKind::RelativeLoongArchHigh + | RelocationKind::DtpOff + | RelocationKind::TpOff + | RelocationKind::SymRelGotBase + | RelocationKind::PairSubtractionULEB128(..) => ValueFlags::DIRECT, + RelocationKind::None | RelocationKind::AbsoluteLowPart | RelocationKind::Alignment => { + ValueFlags::empty() + } + } +} + +impl<'data> PreludeLayoutState<'data> { + fn new(input_state: resolution::ResolvedPrelude<'data>) -> Self { + Self { + file_id: PRELUDE_FILE_ID, + symbol_id_range: SymbolIdRange::prelude(input_state.symbol_definitions.len()), + internal_symbols: InternalSymbols { + symbol_definitions: input_state.symbol_definitions, + start_symbol_id: SymbolId::zero(), + }, + entry_symbol_id: None, + needs_tlsld_got_entry: false, + identity: format!("Linker: {}", crate::identity::linker_identity()), + header_info: None, + dynamic_linker: None, + shstrtab_size: 0, + } + } + + fn activate<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + if resources.symbol_db.args.should_write_linker_identity { + // Allocate space to store the identity of the linker in the .comment section. + common.allocate( + output_section_id::COMMENT.part_id_with_alignment(alignment::MIN), + self.identity.len() as u64, + ); + } + + // The first entry in the symbol table must be null. Similarly, the first string in the + // strings table must be empty. + if !resources.symbol_db.args.strip_all() { + common.allocate(part_id::SYMTAB_LOCAL, size_of::() as u64); + common.allocate(part_id::STRTAB, 1); + } + + self.load_entry_point::

(resources, queue, scope); + + if resources.symbol_db.output_kind.needs_dynsym() { + // Allocate space for the null symbol. + common.allocate(part_id::DYNSTR, 1); + common.allocate(part_id::DYNSYM, size_of::() as u64); + } + + if resources.symbol_db.output_kind.is_dynamic_executable() { + self.dynamic_linker = resources + .symbol_db + .args + .dynamic_linker + .as_ref() + .map(|p| CString::new(p.as_os_str().as_encoded_bytes())) + .transpose()?; + } + if let Some(dynamic_linker) = self.dynamic_linker.as_ref() { + common.allocate( + part_id::INTERP, + dynamic_linker.as_bytes_with_nul().len() as u64, + ); + } + + self.mark_defsyms_as_used::

(resources, queue, scope); + + Ok(()) + } + + /// Mark defsyms from the command-line as being directly referenced so that we emit the symbols + /// even if nothing in the code references them. + fn mark_defsyms_as_used<'scope, P: ElfPlatform<'data>>( + &self, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) { + for (index, def_info) in self.internal_symbols.symbol_definitions.iter().enumerate() { + let symbol_id = self.symbol_id_range.offset_to_id(index); + if !resources.symbol_db.is_canonical(symbol_id) { + continue; + } + + match def_info.placement { + SymbolPlacement::DefsymAbsolute(_) => { + resources + .per_symbol_flags + .get_atomic(symbol_id) + .or_assign(ValueFlags::DIRECT); + } + SymbolPlacement::DefsymSymbol(target_name, _offset) => { + resources + .per_symbol_flags + .get_atomic(symbol_id) + .or_assign(ValueFlags::DIRECT); + + // Also mark the target symbol as used and queue it for loading to prevent it + // from being GC'd. + if let Some(target_symbol_id) = resources + .symbol_db + .get_unversioned(&UnversionedSymbolName::prehashed(target_name.as_bytes())) + { + let canonical_target_id = resources.symbol_db.definition(target_symbol_id); + let file_id = resources.symbol_db.file_id_for_symbol(canonical_target_id); + let old_flags = resources + .per_symbol_flags + .get_atomic(canonical_target_id) + .fetch_or(ValueFlags::DIRECT); + + if !old_flags.has_resolution() { + queue.send_work::

( + resources, + file_id, + WorkItem::LoadGlobalSymbol(canonical_target_id), + scope, + ); + } + } + } + _ => {} + } + } + } + + fn load_entry_point<'scope, P: ElfPlatform<'data>>( + &mut self, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) { + let Some(symbol_id) = + resources + .symbol_db + .get_unversioned(&UnversionedSymbolName::prehashed( + resources.symbol_db.entry_symbol_name(), + )) + else { + // We'll emit a warning when writing the file if it's an executable. + return; + }; + + let symbol_id = resources.symbol_db.definition(symbol_id); + + self.entry_symbol_id = Some(symbol_id); + let file_id = resources.symbol_db.file_id_for_symbol(symbol_id); + let old_flags = resources + .per_symbol_flags + .get_atomic(symbol_id) + .fetch_or(ValueFlags::DIRECT); + if !old_flags.has_resolution() { + queue.send_work::

( + resources, + file_id, + WorkItem::LoadGlobalSymbol(symbol_id), + scope, + ); + } + } + + fn pre_finalise_sizes( + &mut self, + common: &mut CommonGroupState, + uses_tlsld: &AtomicBool, + args: &Args, + output_kind: OutputKind, + ) { + if uses_tlsld.load(atomic::Ordering::Relaxed) { + // Allocate space for a TLS module number and offset for use with TLSLD relocations. + common.allocate(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); + self.needs_tlsld_got_entry = true; + // For shared objects, we'll need to use a DTPMOD relocation to fill in the TLS module + // number. + if !output_kind.is_executable() { + common.allocate(part_id::RELA_DYN_GENERAL, crate::elf::RELA_ENTRY_SIZE); + } + } + + as ObjectFile<'data>>::pre_finalise_sizes_prelude(common, args); + } + + fn finalise_sizes( + common: &mut CommonGroupState<'data>, + merged_strings: &OutputSectionMap>, + ) { + merged_strings.for_each(|section_id, merged| { + if merged.len() > 0 { + common.allocate( + section_id.part_id_with_alignment(alignment::MIN), + merged.len(), + ); + } + }); + } + + /// This function is where we determine sizes that depend on other sizes. For example, the size + /// of the section headers table, which depends on which sections we're writing, which depends + /// on which sections are non-empty. We also decide which internal symtab entries we'll write + /// here, since that also depends on which sections we're writing. + fn apply_late_size_adjustments( + &mut self, + common: &mut CommonGroupState, + total_sizes: &mut OutputSectionPartMap, + must_keep_sections: OutputSectionMap, + output_sections: &mut OutputSections, + output_order: &OutputOrder, + program_segments: &ProgramSegments, + per_symbol_flags: &mut PerSymbolFlags, + resources: &FinaliseSizesResources, + ) -> Result { + // Total section sizes have already been computed. So any allocations we do need to update + // both `total_sizes` and the size records in `common`. We track the extra sizes in + // `extra_sizes` which we can then later add to both. + let mut extra_sizes = OutputSectionPartMap::with_size(common.mem_sizes.num_parts()); + + self.determine_header_sizes( + total_sizes, + &mut extra_sizes, + must_keep_sections, + output_sections, + program_segments, + output_order, + resources, + per_symbol_flags, + ); + + self.allocate_symbol_table_sizes( + output_sections, + per_symbol_flags, + resources.symbol_db, + &mut extra_sizes, + )?; + + // We need to allocate both our own size record and the group totals, since they've already + // been computed. + common.mem_sizes.merge(&extra_sizes); + total_sizes.merge(&extra_sizes); + + Ok(()) + } + + /// Allocates space for our internal symbols. For unreferenced symbols, we also update the + /// symbol so that it is treated as referenced, but only for symbols in sections that we're + /// going to emit. + fn allocate_symbol_table_sizes( + &self, + output_sections: &OutputSections, + per_symbol_flags: &mut PerSymbolFlags, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + extra_sizes: &mut OutputSectionPartMap, + ) -> Result<(), Error> { + if symbol_db.args.strip_all() { + return Ok(()); + } + + self.internal_symbols.allocate_symbol_table_sizes( + extra_sizes, + symbol_db, + |symbol_id, def_info| { + let flags = per_symbol_flags.flags_for_symbol(symbol_id); + + // If the symbol is referenced, then we keep it. + if flags.has_resolution() { + return true; + } + + // We always emit symbols that the user requested be undefined. + let mut should_emit = def_info.placement == SymbolPlacement::ForceUndefined; + + // Keep the symbol if we're going to write the section, even though the symbol isn't + // referenced. It can be useful to have symbols like _GLOBAL_OFFSET_TABLE_ when + // using a debugger. + should_emit |= def_info.section_id().is_some_and(|output_section_id| { + output_sections.will_emit_section(output_section_id) + }); + + if should_emit { + // Mark the symbol as referenced so that we later generate a resolution for + // it and subsequently write it to the symbol table. + per_symbol_flags.set_flag(symbol_id, ValueFlags::DIRECT); + } + + should_emit + }, + ) + } + + fn determine_header_sizes( + &mut self, + total_sizes: &OutputSectionPartMap, + extra_sizes: &mut OutputSectionPartMap, + must_keep_sections: OutputSectionMap, + output_sections: &mut OutputSections, + program_segments: &ProgramSegments, + output_order: &OutputOrder, + resources: &FinaliseSizesResources, + symbol_flags: &PerSymbolFlags, + ) { + use output_section_id::OrderEvent; + + // Determine which sections to keep. To start with, we keep all sections that we've + // previously marked as needing to be kept. These may include sections that are empty, but + // into which we've loaded an empty input section. + let mut keep_sections = must_keep_sections; + + // Next, keep any sections for which we've recorded a non-zero size. + total_sizes.map(|part_id, size| { + if *size > 0 { + *keep_sections.get_mut(part_id.output_section_id()) = true; + } + }); + + // Keep any sections that we've said we want to keep regardless. + for section_id in output_section_id::built_in_section_ids() { + if section_id.built_in_details().keep_if_empty { + // Don't keep .relro_padding if relro is disabled. + if section_id == output_section_id::RELRO_PADDING && !resources.symbol_db.args.relro + { + continue; + } + *keep_sections.get_mut(section_id) = true; + } + } + + // Keep any sections that have a start/stop symbol which is referenced. + symbol_flags + .raw_range(self.symbol_id_range()) + .iter() + .zip(self.internal_symbols.symbol_definitions.iter()) + .for_each(|(raw_flags, definition)| { + if raw_flags.get().has_resolution() + && let Some(section_id) = definition.section_id() + { + *keep_sections.get_mut(section_id) = true; + } + }); + + for i in 0..output_sections.num_sections() { + let section_id = OutputSectionId::from_usize(i); + + // If any secondary sections were marked to be kept, then unmark them and mark the + // primary instead. + if let Some(primary_id) = output_sections.merge_target(section_id) { + let keep_secondary = replace(keep_sections.get_mut(section_id), false); + *keep_sections.get_mut(primary_id) |= keep_secondary; + } + + // Remove any built-in sections without a type except for section 0 (the file header). + // This should just be the .phdr and .shdr sections which contain the program headers + // and section headers. We need these sections in order to allocate space for those + // structures, but other linkers don't emit section headers for them, so neither should + // we. Custom sections (e.g. from linker scripts) that still have NULL type get + // PROGBITS assigned instead, since an empty but explicitly defined section should still + // be emitted if something references it. + let section_info = output_sections.section_infos.get(section_id); + if section_info.ty == sht::NULL && section_id != output_section_id::FILE_HEADER { + if section_id.as_usize() >= output_section_id::NUM_BUILT_IN_SECTIONS { + output_sections.section_infos.get_mut(section_id).ty = sht::PROGBITS; + } else { + *keep_sections.get_mut(section_id) = false; + } + } + } + + let num_sections = keep_sections.values_iter().filter(|p| **p).count(); + + // Compute output indexes of each section. + let mut next_output_index = 0; + let mut output_section_indexes = vec![None; output_sections.num_sections()]; + for event in output_order { + if let OrderEvent::Section(id) = event + && *keep_sections.get(id) + { + debug_assert!( + output_sections.merge_target(id).is_none(), + "Tried to allocate section header for secondary section {}", + output_sections.section_debug(id) + ); + output_section_indexes[id.as_usize()] = Some(next_output_index); + next_output_index += 1; + }; + } + output_sections.output_section_indexes = output_section_indexes; + + // Determine which program segments contain sections that we're keeping. + let mut keep_segments = program_segments + .iter() + .map(|details| details.always_keep()) + .collect_vec(); + let mut active_segments = Vec::with_capacity(4); + for event in output_order { + match event { + OrderEvent::SegmentStart(segment_id) => active_segments.push(segment_id), + OrderEvent::SegmentEnd(segment_id) => active_segments.retain(|a| *a != segment_id), + OrderEvent::Section(section_id) => { + if *keep_sections.get(section_id) { + for segment_id in &active_segments { + keep_segments[segment_id.as_usize()] = true; + } + active_segments.clear(); + } + } + OrderEvent::SetLocation(_) => {} + } + } + + // Always keep the program headers segment even though we don't emit any sections in it. + keep_segments[0] = true; + + // If relro is disabled, then discard the relro segment. + if !resources.symbol_db.args.relro { + for (segment_def, keep) in program_segments.into_iter().zip(keep_segments.iter_mut()) { + if segment_def.segment_type == pt::GNU_RELRO { + *keep = false; + } + } + } + + let active_segment_ids = (0..program_segments.len()) + .map(ProgramSegmentId::new) + .filter(|id| keep_segments[id.as_usize()] || program_segments.is_stack_segment(*id)) + .collect(); + + let header_info = HeaderInfo { + num_output_sections_with_content: num_sections + .try_into() + .expect("output section count must fit in a u16"), + + active_segment_ids, + }; + + // Allocate space for headers based on segment and section counts. + extra_sizes.increment(part_id::FILE_HEADER, u64::from(elf::FILE_HEADER_SIZE)); + extra_sizes.increment(part_id::PROGRAM_HEADERS, header_info.program_headers_size()); + extra_sizes.increment(part_id::SECTION_HEADERS, header_info.section_headers_size()); + self.shstrtab_size = output_sections + .ids_with_info() + .filter(|(id, _info)| output_sections.output_index_of_section(*id).is_some()) + .map(|(_id, info)| { + if let SectionKind::Primary(name) = info.kind { + name.len() as u64 + 1 + } else { + 0 + } + }) + .sum::(); + extra_sizes.increment(part_id::SHSTRTAB, self.shstrtab_size); + + self.header_info = Some(header_info); + } + + fn finalise_layout( + self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources<'_, '_>, + ) -> Result> { + let header_layout = resources + .section_layouts + .get(output_section_id::FILE_HEADER); + assert_eq!(header_layout.file_offset, 0); + + let tlsld_got_entry = self.needs_tlsld_got_entry.then(|| { + let address = NonZeroU64::new(*memory_offsets.get(part_id::GOT)) + .expect("GOT address must never be zero"); + memory_offsets.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); + address + }); + + // Take the null symbol's index. + if resources.symbol_db.output_kind.needs_dynsym() { + take_dynsym_index(memory_offsets, resources.section_layouts)?; + } + + self.internal_symbols + .finalise_layout(memory_offsets, resolutions_out, resources)?; + + if resources.symbol_db.args.should_write_linker_identity { + memory_offsets.increment( + output_section_id::COMMENT.part_id_with_alignment(alignment::MIN), + self.identity.len() as u64, + ); + } + + resources.merged_strings.for_each(|section_id, merged| { + if merged.len() > 0 { + memory_offsets.increment( + section_id.part_id_with_alignment(alignment::MIN), + merged.len(), + ); + } + }); + + Ok(PreludeLayout { + internal_symbols: self.internal_symbols, + entry_symbol_id: self.entry_symbol_id, + tlsld_got_entry, + identity: self.identity, + dynamic_linker: self.dynamic_linker, + header_info: self + .header_info + .expect("we should have computed header info by now"), + }) + } +} + +impl<'data> InternalSymbols<'data> { + fn allocate_symbol_table_sizes( + &self, + sizes: &mut OutputSectionPartMap, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + mut should_keep_symbol: impl FnMut(SymbolId, &InternalSymDefInfo) -> bool, + ) -> Result { + // Allocate space in the symbol table for the symbols that we define. + for (index, def_info) in self.symbol_definitions.iter().enumerate() { + let symbol_id = self.start_symbol_id.add_usize(index); + if !symbol_db.is_canonical(symbol_id) || symbol_id.is_undefined() { + continue; + } + + if !should_keep_symbol(symbol_id, def_info) { + continue; + } + + // PROVIDE_HIDDEN symbols are local, others are global + let symtab_part = if def_info.is_hidden { + part_id::SYMTAB_LOCAL + } else { + part_id::SYMTAB_GLOBAL + }; + sizes.increment(symtab_part, size_of::() as u64); + let symbol_name = symbol_db.symbol_name(symbol_id)?; + let symbol_name = RawSymbolName::parse(symbol_name.bytes()).name; + sizes.increment(part_id::STRTAB, symbol_name.len() as u64 + 1); + } + Ok(()) + } + + fn finalise_layout( + &self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources, + ) -> Result { + // Define symbols that are optionally put at the start/end of some sections. + for (local_index, &def_info) in self.symbol_definitions.iter().enumerate() { + let symbol_id = self.start_symbol_id.add_usize(local_index); + + let resolution = + create_start_end_symbol_resolution(memory_offsets, resources, def_info, symbol_id); + + resolutions_out.write(resolution)?; + } + Ok(()) + } + + pub(crate) fn symbol_id_range(&self) -> SymbolIdRange { + SymbolIdRange::input(self.start_symbol_id, self.symbol_definitions.len()) + } +} + +fn create_start_end_symbol_resolution( + memory_offsets: &mut OutputSectionPartMap, + resources: &FinaliseLayoutResources<'_, '_>, + def_info: InternalSymDefInfo, + symbol_id: SymbolId, +) -> Option { + if !resources.symbol_db.is_canonical(symbol_id) { + return None; + } + + if !resources + .per_symbol_flags + .flags_for_symbol(symbol_id) + .has_resolution() + { + return None; + } + + let raw_value = match def_info.placement { + SymbolPlacement::Undefined | SymbolPlacement::ForceUndefined => 0, + SymbolPlacement::SectionStart(section_id) => { + resources.section_layouts.get(section_id).mem_offset + } + + SymbolPlacement::SectionEnd(section_id) => { + let sec = resources.section_layouts.get(section_id); + sec.mem_offset + sec.mem_size + } + + SymbolPlacement::SectionGroupEnd(section_id) => { + let mut end = { + let sec = resources.section_layouts.get(section_id); + sec.mem_offset + sec.mem_size + }; + + for (id, info) in resources.output_sections.ids_with_info() { + if let SectionKind::Secondary(primary_id) = info.kind + && primary_id == section_id + { + let sec = resources.section_layouts.get(id); + let candidate_end = sec.mem_offset + sec.mem_size; + if candidate_end > end { + end = candidate_end; + } + } + } + end + } + + SymbolPlacement::DefsymAbsolute(value) => value, + + SymbolPlacement::DefsymSymbol(_, _) => { + // For defsym symbols that reference another symbol, we defer resolution + // until later when all symbols have been resolved. This is handled by + // update_defsym_symbol_resolutions() which is called after layout is complete. + 0 + } + + SymbolPlacement::LoadBaseAddress => resources + .segment_layouts + .segments + .iter() + .find(|seg| resources.program_segments.segment_def(seg.id).segment_type == pt::LOAD) + .map(|seg| seg.sizes.mem_offset)?, + }; + + Some(create_resolution( + resources + .symbol_db + .flags_for_symbol(resources.per_symbol_flags, symbol_id), + raw_value, + None, + memory_offsets, + )) +} + +fn should_emit_undefined_error( + symbol: &Symbol, + sym_file_id: FileId, + sym_def_file_id: FileId, + flags: ValueFlags, + args: &Args, + output_kind: OutputKind, +) -> bool { + if (output_kind.is_shared_object() && !args.no_undefined) || symbol.is_weak() { + return false; + } + + let is_symbol_undefined = + sym_file_id == sym_def_file_id && symbol.is_undefined() && flags.is_absolute(); + + match args.unresolved_symbols { + crate::args::UnresolvedSymbols::IgnoreAll + | crate::args::UnresolvedSymbols::IgnoreInObjectFiles => false, + _ => is_symbol_undefined, + } +} + +impl<'data> SyntheticSymbolsLayoutState<'data> { + fn new(input_state: ResolvedSyntheticSymbols<'data>) -> SyntheticSymbolsLayoutState<'data> { + SyntheticSymbolsLayoutState { + file_id: input_state.file_id, + symbol_id_range: SymbolIdRange::input( + input_state.start_symbol_id, + input_state.symbol_definitions.len(), + ), + internal_symbols: InternalSymbols { + symbol_definitions: input_state.symbol_definitions, + start_symbol_id: input_state.start_symbol_id, + }, + } + } + + fn finalise_sizes( + &self, + common: &mut CommonGroupState, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources, + ) -> Result { + let symbol_db = resources.symbol_db; + + if !symbol_db.args.strip_all() { + self.internal_symbols.allocate_symbol_table_sizes( + &mut common.mem_sizes, + symbol_db, + |symbol_id, _| { + // For user-defined start/stop symbols, we only emit them if they're referenced. + per_symbol_flags + .flags_for_symbol(symbol_id) + .has_resolution() + }, + )?; + } + + Ok(()) + } + + fn finalise_layout( + self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result> { + self.internal_symbols + .finalise_layout(memory_offsets, resolutions_out, resources)?; + + Ok(SyntheticSymbolsLayout { + internal_symbols: self.internal_symbols, + }) + } +} + +impl EpilogueLayoutState { + fn new( + args: &Args, + output_kind: OutputKind, + dynamic_symbol_definitions: &mut [DynamicSymbolDefinition], + ) -> EpilogueLayoutState { + let build_id_size = match &args.build_id { + BuildIdOption::None => None, + BuildIdOption::Fast => Some(size_of::()), + BuildIdOption::Hex(hex) => Some(hex.len()), + BuildIdOption::Uuid => Some(size_of::()), + }; + + EpilogueLayoutState { + format_specific: ::new_epilogue_layout( + args, + output_kind, + dynamic_symbol_definitions, + ), + build_id_size, + } + } + + fn apply_late_size_adjustments( + &mut self, + common: &mut CommonGroupState, + total_sizes: &mut OutputSectionPartMap, + resources: &FinaliseSizesResources, + ) -> Result { + if resources.symbol_db.args.hash_style.includes_sysv() { + let mut extra_sizes = OutputSectionPartMap::with_size(common.mem_sizes.num_parts()); + ::apply_late_size_adjustments_epilogue( + &mut self.format_specific, + total_sizes, + &mut extra_sizes, + resources.dynamic_symbol_definitions, + )?; + + // See comments in Prelude::apply_late_size_adjustments. + total_sizes.merge(&extra_sizes); + common.mem_sizes.merge(&extra_sizes); + } + + Ok(()) + } + + fn gnu_build_id_note_section_size(&self) -> Option { + Some((size_of::() + GNU_NOTE_NAME.len() + self.build_id_size?) as u64) + } + + fn finalise_sizes( + &mut self, + common: &mut CommonGroupState, + resources: &FinaliseSizesResources, + ) { + let symbol_db = resources.symbol_db; + + if symbol_db.output_kind.needs_dynamic() { + let dynamic_entry_size = size_of::(); + common.allocate( + part_id::DYNAMIC, + (elf_writer::NUM_EPILOGUE_DYNAMIC_ENTRIES * dynamic_entry_size) as u64, + ); + if let Some(rpath) = symbol_db.args.rpath.as_ref() { + common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); + common.allocate(part_id::DYNSTR, rpath.len() as u64 + 1); + } + if let Some(soname) = symbol_db.args.soname.as_ref() { + common.allocate(part_id::DYNSTR, soname.len() as u64 + 1); + common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); + } + for aux in &symbol_db.args.auxiliary { + common.allocate(part_id::DYNSTR, aux.len() as u64 + 1); + common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); + } + + common.allocate( + part_id::DYNSTR, + resources + .dynamic_symbol_definitions + .iter() + .map(|n| n.name.len() + 1) + .sum::() as u64, + ); + common.allocate( + part_id::DYNSYM, + (resources.dynamic_symbol_definitions.len() * size_of::()) as u64, + ); + } + + if let Some(build_id_sec_size) = self.gnu_build_id_note_section_size() { + common.allocate(part_id::NOTE_GNU_BUILD_ID, build_id_sec_size); + } + + ::finalise_sizes_epilogue( + &mut self.format_specific, + &mut common.mem_sizes, + resources.format_specific, + symbol_db, + ); + } + + fn finalise_layout( + mut self, + memory_offsets: &mut OutputSectionPartMap, + resources: &FinaliseLayoutResources, + ) -> Result { + let dynsym_start_index = ((memory_offsets.get(part_id::DYNSYM) + - resources + .section_layouts + .get(output_section_id::DYNSYM) + .mem_offset) + / elf::SYMTAB_ENTRY_SIZE) + .try_into() + .context("Too many dynamic symbols")?; + + memory_offsets.increment( + part_id::DYNSYM, + resources.dynamic_symbol_definitions.len() as u64 * elf::SYMTAB_ENTRY_SIZE, + ); + + if let Some(build_id_sec_size) = self.gnu_build_id_note_section_size() { + memory_offsets.increment(part_id::NOTE_GNU_BUILD_ID, build_id_sec_size); + } + + ::finalise_layout_epilogue( + &mut self.format_specific, + memory_offsets, + resources.symbol_db, + resources.format_specific, + dynsym_start_index, + resources.dynamic_symbol_definitions, + )?; + + Ok(EpilogueLayout { + format_specific: self.format_specific, + dynsym_start_index, + }) + } +} + +#[derive(Debug)] +pub(crate) struct HeaderInfo { + pub(crate) num_output_sections_with_content: u16, + pub(crate) active_segment_ids: Vec, +} + +impl HeaderInfo { + pub(crate) fn program_headers_size(&self) -> u64 { + u64::from(elf::PROGRAM_HEADER_SIZE) * self.active_segment_ids.len() as u64 + } + + pub(crate) fn section_headers_size(&self) -> u64 { + u64::from(elf::SECTION_HEADER_SIZE) * u64::from(self.num_output_sections_with_content) + } +} + +/// Construct a new inactive instance, which means we don't yet load non-GC sections and only +/// load them later if a symbol from this object is referenced. +fn new_object_layout_state<'data>( + input_state: resolution::ResolvedObject<'data, crate::elf::File<'data>>, +) -> FileLayoutState<'data> { + // Note, this function is called for all objects from a single thread, so don't be tempted to do + // significant work here. Do work when activate is called instead. Doing it there also means + // that we don't do the work unless the object is actually needed. + + FileLayoutState::Object(ObjectLayoutState { + file_id: input_state.common.file_id, + symbol_id_range: input_state.common.symbol_id_range, + input: input_state.common.input, + object: input_state.common.object, + sections: input_state.sections, + relocations: input_state.relocations, + format_specific_layout_state: Default::default(), + section_relax_deltas: RelaxDeltaMap::new(), + }) +} + +fn new_dynamic_object_layout_state<'data>( + input_state: &resolution::ResolvedDynamic<'data, crate::elf::File<'data>>, +) -> FileLayoutState<'data> { + FileLayoutState::Dynamic(DynamicLayoutState { + file_id: input_state.common.file_id, + symbol_id_range: input_state.common.symbol_id_range, + lib_name: input_state.lib_name(), + object: input_state.common.object, + input: input_state.common.input, + copy_relocations: Default::default(), + format_specific_state: Default::default(), + }) +} + +impl<'data> ObjectLayoutState<'data> { + #[inline(always)] + fn activate<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + let mut frame_section_index = None; + let mut note_gnu_property_section = None; + let mut riscv_attributes_section = None; + + let no_gc = !resources.symbol_db.args.gc_sections; + + for (i, section) in self.sections.iter().enumerate() { + match section { + SectionSlot::MustLoad(..) + | SectionSlot::UnloadedDebugInfo(..) + | SectionSlot::MergeStrings(_) => { + queue + .local_work + .push(WorkItem::LoadSection(SectionLoadRequest::new( + self.file_id, + object::SectionIndex(i), + ))); + } + SectionSlot::Unloaded(sec) => { + if no_gc { + queue + .local_work + .push(WorkItem::LoadSection(SectionLoadRequest::new( + self.file_id, + object::SectionIndex(i), + ))); + } else if sec.start_stop_eligible { + resources + .start_stop_sections + .get(sec.part_id.output_section_id()) + .push(SectionLoadRequest { + file_id: self.file_id, + section_index: i as u32, + }); + } + } + SectionSlot::FrameData(index) => { + frame_section_index = Some(*index); + } + SectionSlot::NoteGnuProperty(index) => { + note_gnu_property_section = Some(*index); + } + SectionSlot::RiscvVAttributes(index) => { + riscv_attributes_section = Some(*index); + } + _ => (), + } + } + + if let Some(frame_data_section_index) = frame_section_index { + >::load_exception_frame_data::

( + self, + common, + frame_data_section_index, + resources, + queue, + scope, + )?; + } + + if let Some(section_index) = note_gnu_property_section { + self.object + .process_gnu_note_section(&mut self.format_specific_layout_state, section_index)?; + } + + if let Some(riscv_attributes_index) = riscv_attributes_section { + P::process_riscv_attributes( + self.object, + &mut self.format_specific_layout_state, + riscv_attributes_index, + ) + .context("Cannot parse .riscv.attributes section")?; + } + + let export_all_dynamic = resources.symbol_db.output_kind == OutputKind::SharedObject + && !(self.input.has_archive_semantics() + && resources + .symbol_db + .args + .exclude_libs + .should_exclude(self.input.lib_name())) + || resources.symbol_db.output_kind.needs_dynsym() + && resources.symbol_db.args.export_all_dynamic_symbols; + if export_all_dynamic + || resources.symbol_db.output_kind.needs_dynsym() + && resources.symbol_db.export_list.is_some() + { + self.load_non_hidden_symbols::

(common, resources, queue, export_all_dynamic, scope)?; + } + + Ok(()) + } + + fn handle_section_load_request<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + section_index: SectionIndex, + scope: &Scope<'scope>, + ) -> Result<(), Error> { + match &self.sections[section_index.0] { + SectionSlot::Unloaded(unloaded) | SectionSlot::MustLoad(unloaded) => { + self.load_section::

(common, queue, *unloaded, section_index, resources, scope)?; + } + SectionSlot::UnloadedDebugInfo(part_id) => { + // On RISC-V, the debug info sections contain relocations to local symbols (e.g. + // labels). + self.load_debug_section::

( + common, + queue, + *part_id, + section_index, + resources, + scope, + )?; + } + SectionSlot::Discard => { + bail!( + "{self}: Don't know what segment to put `{}` in, but it's referenced", + self.object.section_display_name(section_index), + ); + } + SectionSlot::Loaded(_) + | SectionSlot::FrameData(..) + | SectionSlot::LoadedDebugInfo(..) + | SectionSlot::NoteGnuProperty(..) + | SectionSlot::RiscvVAttributes(..) => {} + SectionSlot::MergeStrings(sec) => { + // We currently always load everything in merge-string sections. i.e. we don't GC + // unreferenced data. So the only thing we need to do here is propagate section + // flags. + let header = self.object.section(section_index)?; + common.store_section_attributes(sec.part_id, header); + } + }; + + Ok(()) + } + + fn load_section<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + queue: &mut LocalWorkQueue, + unloaded: UnloadedSection, + section_index: SectionIndex, + resources: &'scope GraphResources<'data, 'scope>, + scope: &Scope<'scope>, + ) -> Result { + let part_id = unloaded.part_id; + let header = self.object.section(section_index)?; + let section = Section::create(header, self, section_index, part_id)?; + + match self.relocations(section.index)? { + RelocationList::Rela(relocations) => { + self.load_section_relocations::( + common, + queue, + resources, + section, + relocations.rel_iter(), + scope, + )?; + } + RelocationList::Crel(relocations) => { + self.load_section_relocations::( + common, + queue, + resources, + section, + relocations.flat_map(|r| r.ok()), + scope, + )?; + } + } + + tracing::debug!(loaded_section = %self.object.section_display_name(section_index), file = %self.input); + + common.section_loaded(part_id, header, section); + + let section_id = section.output_section_id(); + + if section.size > 0 { + as ObjectFile<'data>>::non_empty_section_loaded::

( + self, common, queue, unloaded, resources, scope, + )?; + } else if section_id.marks_zero_sized_inputs_as_content() { + resources.keep_section(section_id); + } + + self.sections[section_index.0] = SectionSlot::Loaded(section); + + Ok(()) + } + + fn load_section_relocations< + 'scope, + P: ElfPlatform<'data>, + R: Relocation, + >( + &self, + common: &mut CommonGroupState<'data>, + queue: &mut LocalWorkQueue, + resources: &'scope GraphResources<'data, '_>, + section: Section, + relocations: impl Iterator, + scope: &Scope<'scope>, + ) -> Result { + let mut modifier = RelocationModifier::Normal; + for rel in relocations { + if modifier == RelocationModifier::SkipNextRelocation { + modifier = RelocationModifier::Normal; + continue; + } + modifier = process_relocation::( + self, + common, + &rel, + self.object.section(section.index)?, + resources, + queue, + false, + scope, + ) + .with_context(|| { + format!( + "Failed to copy section {} from file {self}", + section_debug(self.object, section.index) + ) + })?; + } + + Ok(()) + } + + fn load_debug_section<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + queue: &mut LocalWorkQueue, + + part_id: PartId, + section_index: SectionIndex, + resources: &'scope GraphResources<'data, '_>, + scope: &Scope<'scope>, + ) -> Result { + let header = self.object.section(section_index)?; + let section = Section::create(header, self, section_index, part_id)?; + if P::local_symbols_in_debug_info() { + match self.relocations(section.index)? { + RelocationList::Rela(relocations) => self.load_debug_relocations::( + common, + queue, + resources, + section, + relocations.rel_iter(), + scope, + )?, + RelocationList::Crel(relocations) => self.load_debug_relocations::( + common, + queue, + resources, + section, + relocations.flat_map(|r| r.ok()), + scope, + )?, + } + } + + tracing::debug!(loaded_debug_section = %self.object.section_display_name(section_index),); + common.section_loaded(part_id, header, section); + self.sections[section_index.0] = SectionSlot::LoadedDebugInfo(section); + + Ok(()) + } + + fn load_debug_relocations< + 'scope, + P: ElfPlatform<'data>, + R: Relocation, + >( + &self, + common: &mut CommonGroupState<'data>, + queue: &mut LocalWorkQueue, + resources: &'scope GraphResources<'data, '_>, + section: Section, + relocations: impl Iterator, + scope: &Scope<'scope>, + ) -> Result<(), Error> { + for rel in relocations { + let modifier = process_relocation::( + self, + common, + &rel, + self.object.section(section.index)?, + resources, + queue, + true, + scope, + ) + .with_context(|| { + format!( + "Failed to copy section {} from file {self}", + section_debug(self.object, section.index) + ) + })?; + ensure!( + modifier == RelocationModifier::Normal, + "All debug relocations must be processed" + ); + } + + Ok(()) + } + + fn finalise_sizes( + &mut self, + common: &mut CommonGroupState, + output_sections: &OutputSections, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources<'data, '_>, + ) { + common.mem_sizes.resize(output_sections.num_parts()); + if !resources.symbol_db.args.strip_all() { + self.allocate_symtab_space(common, resources.symbol_db, per_symbol_flags); + } + let output_kind = resources.symbol_db.output_kind; + for slot in &mut self.sections { + if let SectionSlot::Loaded(section) = slot { + allocate_resolution(section.flags, &mut common.mem_sizes, output_kind); + } + } + + as ObjectFile<'data>>::finalise_object_sizes(self, common); + } + + fn allocate_symtab_space( + &self, + common: &mut CommonGroupState, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: &AtomicPerSymbolFlags, + ) { + let _file_span = symbol_db.args.trace_span_for_file(self.file_id()); + + let mut num_locals = 0; + let mut num_globals = 0; + let mut strings_size = 0; + for ((sym_index, sym), flags) in self + .object + .symbols + .enumerate() + .zip(per_symbol_flags.range(self.symbol_id_range())) + { + let symbol_id = self.symbol_id_range.input_to_id(sym_index); + if let Some(info) = SymbolCopyInfo::new( + self.object, + sym_index, + sym, + symbol_id, + symbol_db, + flags.get(), + &self.sections, + ) { + // If we've decided to emit the symbol even though it's not referenced (because it's + // in a section we're emitting), then make sure we have a resolution for it. + flags.fetch_or(ValueFlags::DIRECT); + if flags.get().is_symtab_local(sym) { + num_locals += 1; + } else { + num_globals += 1; + } + let name = RawSymbolName::parse(info.name).name; + strings_size += name.len() + 1; + } + } + let entry_size = size_of::() as u64; + common.allocate(part_id::SYMTAB_LOCAL, num_locals * entry_size); + common.allocate(part_id::SYMTAB_GLOBAL, num_globals * entry_size); + common.allocate(part_id::STRTAB, strings_size as u64); + } + + fn finalise_layout( + mut self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result> { + let _file_span = resources.symbol_db.args.trace_span_for_file(self.file_id()); + let symbol_id_range = self.symbol_id_range(); + + let sframe_start_address = resources + .section_layouts + .get(output_section_id::SFRAME) + .mem_offset; + let mut sframe_ranges = Vec::new(); + + let mut section_resolutions = Vec::with_capacity(self.sections.len()); + for slot in &mut self.sections { + let resolution = match slot { + SectionSlot::Loaded(sec) => { + let part_id = sec.part_id; + let address = *memory_offsets.get(part_id); + // TODO: We probably need to be able to handle sections that are ifuncs and + // sections that need a TLS GOT struct. + *memory_offsets.get_mut(part_id) += sec.capacity(); + // Collect SFrame section ranges while we're already iterating + if part_id.output_section_id() == output_section_id::SFRAME { + let offset = (address - sframe_start_address) as usize; + let len = sec.size as usize; + sframe_ranges.push(offset..offset + len); + } + SectionResolution { address } + } + &mut SectionSlot::LoadedDebugInfo(sec) => { + let address = *memory_offsets.get(sec.part_id); + *memory_offsets.get_mut(sec.part_id) += sec.capacity(); + SectionResolution { address } + } + SectionSlot::FrameData(..) => { + let address = + as ObjectFile<'data>>::frame_data_base_address(memory_offsets); + SectionResolution { address } + } + _ => SectionResolution::none(), + }; + section_resolutions.push(resolution); + } + + for ((local_symbol_index, local_symbol), &flags) in self + .object + .symbols + .enumerate() + .zip(resources.per_symbol_flags.raw_range(symbol_id_range)) + { + self.finalise_symbol( + resources, + flags.get(), + local_symbol, + local_symbol_index, + §ion_resolutions, + memory_offsets, + resolutions_out, + )?; + } + + as ObjectFile<'data>>::finalise_object_layout(&self, memory_offsets); + + Ok(ObjectLayout { + input: self.input, + file_id: self.file_id, + object: self.object, + sections: self.sections, + relocations: self.relocations, + section_resolutions, + symbol_id_range, + sframe_ranges, + section_relax_deltas: self.section_relax_deltas, + }) + } + + fn finalise_symbol<'scope>( + &self, + resources: &FinaliseLayoutResources<'scope, 'data>, + flags: ValueFlags, + local_symbol: &object::elf::Sym64, + local_symbol_index: object::SymbolIndex, + section_resolutions: &[SectionResolution], + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + ) -> Result { + let resolution = self.create_symbol_resolution( + resources, + flags, + local_symbol, + local_symbol_index, + section_resolutions, + memory_offsets, + )?; + + resolutions_out.write(resolution) + } + + fn create_symbol_resolution<'scope>( + &self, + resources: &FinaliseLayoutResources<'scope, 'data>, + flags: ValueFlags, + local_symbol: &object::elf::Sym64, + local_symbol_index: object::SymbolIndex, + section_resolutions: &[SectionResolution], + memory_offsets: &mut OutputSectionPartMap, + ) -> Result> { + let symbol_id_range = self.symbol_id_range(); + let symbol_id = symbol_id_range.input_to_id(local_symbol_index); + + if !flags.has_resolution() || !resources.symbol_db.is_canonical(symbol_id) { + return Ok(None); + } + + let raw_value = if let Some(section_index) = self + .object + .symbol_section(local_symbol, local_symbol_index)? + { + if let Some(section_address) = section_resolutions[section_index.0].address() { + let input_offset = local_symbol.value(); + let output_offset = opt_input_to_output( + self.section_relax_deltas.get(section_index.0), + input_offset, + ); + output_offset + section_address + } else { + match get_merged_string_output_address( + local_symbol_index, + 0, + self.object, + &self.sections, + resources.merged_strings, + resources.merged_string_start_addresses, + true, + )? { + Some(x) => x, + None => { + // Don't error for mapping symbols. They cannot have relocations refer to + // them, so we don't need to produce a resolution. + if resources.symbol_db.is_mapping_symbol(symbol_id) { + return Ok(None); + } + bail!( + "Symbol is in a section that we didn't load. \ + Symbol: {} Section: {} Res: {flags}", + resources.symbol_debug(symbol_id), + section_debug(self.object, section_index), + ); + } + } + } + } else if let Some(common) = local_symbol.as_common() { + let offset = memory_offsets.get_mut(common.part_id); + let address = *offset; + *offset += common.size; + address + } else { + local_symbol.value() + }; + + let mut dynamic_symbol_index = None; + if flags.is_dynamic() { + // This is an undefined weak symbol. Emit it as a dynamic symbol so that it can be + // overridden at runtime. + let dyn_sym_index = take_dynsym_index(memory_offsets, resources.section_layouts)?; + dynamic_symbol_index = Some( + NonZeroU32::new(dyn_sym_index) + .context("Attempted to create dynamic symbol index 0")?, + ); + } + + Ok(Some(create_resolution( + flags, + raw_value, + dynamic_symbol_index, + memory_offsets, + ))) + } + + fn load_non_hidden_symbols<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + export_all_dynamic: bool, + scope: &Scope<'scope>, + ) -> Result { + for (sym_index, sym) in self.object.enumerate_symbols() { + let symbol_id = self.symbol_id_range().input_to_id(sym_index); + + if !can_export_symbol(sym, symbol_id, resources, export_all_dynamic) { + continue; + } + + let old_flags = resources + .per_symbol_flags + .get_atomic(symbol_id) + .fetch_or(ValueFlags::EXPORT_DYNAMIC); + + if !old_flags.has_resolution() { + self.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + + if !old_flags.needs_export_dynamic() { + export_dynamic(common, symbol_id, resources.symbol_db)?; + } + } + Ok(()) + } + + fn export_dynamic<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + symbol_id: SymbolId, + resources: &'scope GraphResources<'data, 'scope>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + let sym = self + .object + .symbol(self.symbol_id_range.id_to_input(symbol_id))?; + + // Shared objects that we're linking against sometimes define symbols that are also defined + // in regular object. When that happens, if we resolve the symbol to the definition from the + // regular object, then the shared object might send us a request to export the definition + // provided by the regular object. This isn't always possible, since the symbol might be + // hidden. + if !can_export_symbol(sym, symbol_id, resources, true) { + return Ok(()); + } + + let old_flags = resources + .per_symbol_flags + .get_atomic(symbol_id) + .fetch_or(ValueFlags::EXPORT_DYNAMIC); + + if !old_flags.has_resolution() { + self.load_symbol::

(common, symbol_id, resources, queue, scope)?; + } + + if !old_flags.needs_export_dynamic() { + export_dynamic(common, symbol_id, resources.symbol_db)?; + } + + Ok(()) + } + + pub(crate) fn relocations(&self, index: SectionIndex) -> Result> { + self.object.relocations(index, &self.relocations) + } +} + +pub(crate) struct SymbolCopyInfo<'data> { + pub(crate) name: &'data [u8], +} + +impl<'data> SymbolCopyInfo<'data> { + /// The primary purpose of this function is to determine whether a symbol should be copied into + /// the symtab. In the process, we also return the name of the symbol, to avoid needing to read + /// it again. + #[inline(always)] + pub(crate) fn new( + object: &crate::elf::File<'data>, + sym_index: object::SymbolIndex, + sym: &crate::elf::Symbol, + symbol_id: SymbolId, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + symbol_state: ValueFlags, + sections: &[SectionSlot], + ) -> Option> { + if !symbol_db.is_canonical(symbol_id) || sym.is_undefined() { + return None; + } + + if let Ok(Some(section)) = object.symbol_section(sym, sym_index) + && !sections[section.0].is_loaded() + { + // Symbol is in a discarded section. + return None; + } + + if sym.as_common().is_some() && !symbol_state.has_resolution() { + return None; + } + + // Reading the symbol name is slightly expensive, so we want to do that after all the other + // checks. That's also the reason why we return the symbol name, so that the caller, if it + // needs the name, doesn't have a go and read it again. + let name = object.symbol_name(sym).ok()?; + if name.is_empty() + || (sym.is_local() && name.starts_with(b".L")) + || is_mapping_symbol_name(name) + { + return None; + } + + if let Strip::Retain(retain) = &symbol_db.args.strip + && !retain.contains(name) + { + return None; + } + + Some(SymbolCopyInfo { name }) + } +} + +/// Returns whether the supplied symbol can be exported when we're outputting a shared object. +fn can_export_symbol( + sym: &crate::elf::SymtabEntry, + symbol_id: SymbolId, + resources: &GraphResources, + export_all_dynamic: bool, +) -> bool { + if sym.is_undefined() || sym.is_local() { + return false; + } + + let visibility = sym.visibility(); + + if visibility == Visibility::Hidden { + return false; + } + + if !resources.symbol_db.is_canonical(symbol_id) { + return false; + } + + let flags = resources.local_flags_for_symbol(symbol_id); + + if flags.is_downgraded_to_local() { + return false; + } + + if !export_all_dynamic + && let Some(export_list) = &resources.symbol_db.export_list + && let Ok(symbol_name) = resources.symbol_db.symbol_name(symbol_id) + && !&export_list.contains(&UnversionedSymbolName::prehashed(symbol_name.bytes())) + { + return false; + } + + true +} + +struct ResolutionWriter<'writer, 'out> { + resolutions_out: &'writer mut sharded_vec_writer::Shard<'out, Option>, +} + +impl ResolutionWriter<'_, '_> { + fn write(&mut self, res: Option) -> Result { + self.resolutions_out.try_push(res)?; + Ok(()) + } +} + +#[inline(always)] +fn create_resolution( + flags: ValueFlags, + raw_value: u64, + dynamic_symbol_index: Option, + memory_offsets: &mut OutputSectionPartMap, +) -> Resolution { + let mut resolution = Resolution { + raw_value, + dynamic_symbol_index, + got_address: None, + plt_address: None, + flags, + }; + if flags.needs_plt() { + let plt_address = allocate_plt(memory_offsets); + resolution.plt_address = Some(plt_address); + if flags.is_dynamic() { + resolution.raw_value = plt_address.get(); + } + // For ifunc with address equality needs, allocate 2 GOT entries + // - First entry: Used by PLT + // - Second entry: Used by GOT-relative references + let num_got_entries = if flags.needs_ifunc_got_for_address() { + 2 + } else { + 1 + }; + resolution.got_address = Some(allocate_got(num_got_entries, memory_offsets)); + } else if flags.is_tls() { + // Handle the TLS GOT addresses where we can combine up to 3 different access methods. + let mut num_got_slots = 0; + if flags.needs_got_tls_offset() { + num_got_slots += 1; + } + if flags.needs_got_tls_module() { + num_got_slots += 2; + } + if flags.needs_got_tls_descriptor() { + num_got_slots += 2; + } + debug_assert!(num_got_slots > 0); + resolution.got_address = Some(allocate_got(num_got_slots, memory_offsets)); + } else if flags.needs_got() { + resolution.got_address = Some(allocate_got(1, memory_offsets)); + } + resolution +} + +fn allocate_got(num_entries: u64, memory_offsets: &mut OutputSectionPartMap) -> NonZeroU64 { + let got_address = NonZeroU64::new(*memory_offsets.get(part_id::GOT)).unwrap(); + memory_offsets.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * num_entries); + got_address +} + +fn allocate_plt(memory_offsets: &mut OutputSectionPartMap) -> NonZeroU64 { + let plt_address = NonZeroU64::new(*memory_offsets.get(part_id::PLT_GOT)).unwrap(); + memory_offsets.increment(part_id::PLT_GOT, elf::PLT_ENTRY_SIZE); + plt_address +} + +impl<'data> resolution::ResolvedFile<'data, crate::elf::File<'data>> { + fn create_layout_state(self) -> FileLayoutState<'data> { + match self { + resolution::ResolvedFile::Object(s) => new_object_layout_state(s), + resolution::ResolvedFile::Dynamic(s) => new_dynamic_object_layout_state(&s), + resolution::ResolvedFile::Prelude(s) => { + FileLayoutState::Prelude(PreludeLayoutState::new(s)) + } + resolution::ResolvedFile::NotLoaded(s) => FileLayoutState::NotLoaded(s), + resolution::ResolvedFile::LinkerScript(s) => { + FileLayoutState::LinkerScript(LinkerScriptLayoutState::new(s)) + } + resolution::ResolvedFile::SyntheticSymbols(s) => { + FileLayoutState::SyntheticSymbols(SyntheticSymbolsLayoutState::new(s)) + } + #[cfg(feature = "plugins")] + resolution::ResolvedFile::LtoInput(s) => FileLayoutState::NotLoaded(NotLoaded { + symbol_id_range: s.symbol_id_range, + }), + } + } +} + +impl Resolution { + pub(crate) fn got_address(&self) -> Result { + Ok(self.got_address.context("Missing GOT address")?.get()) + } + + pub(crate) fn got_address_for_relocation(&self) -> Result { + let mut got_address = self.got_address()?; + if self.flags.needs_ifunc_got_for_address() { + got_address += elf::GOT_ENTRY_SIZE; + } + Ok(got_address) + } + + pub(crate) fn tlsgd_got_address(&self) -> Result { + debug_assert_bail!( + self.flags.needs_got_tls_module(), + "Called tlsgd_got_address without GOT_TLS_MODULE being set" + ); + // If we've got both a GOT_TLS_OFFSET and a GOT_TLS_MODULE, then the latter comes second. + let mut got_address = self.got_address()?; + if self.flags.needs_got_tls_offset() { + got_address += elf::GOT_ENTRY_SIZE; + } + Ok(got_address) + } + + pub(crate) fn tls_descriptor_got_address(&self) -> Result { + debug_assert_bail!( + self.flags.needs_got_tls_descriptor(), + "Called tls_descriptor_got_address without GOT_TLS_DESCRIPTOR being set" + ); + // We might have both GOT_TLS_OFFSET, GOT_TLS_MODULE and GOT_TLS_DESCRIPTOR at the same time + // for a single symbol. Then the TLS descriptor comes as the last one. + let mut got_address = self.got_address()?; + if self.flags.needs_got_tls_offset() { + got_address += elf::GOT_ENTRY_SIZE; + } + if self.flags.needs_got_tls_module() { + got_address += 2 * elf::GOT_ENTRY_SIZE; + } + + Ok(got_address) + } + + pub(crate) fn plt_address(&self) -> Result { + Ok(self.plt_address.context("Missing PLT address")?.get()) + } + + pub(crate) fn flags(self) -> ValueFlags { + self.flags + } + + pub(crate) fn value(self) -> u64 { + self.raw_value + } + + pub(crate) fn address(&self) -> Result { + if !self.flags.is_address() { + bail!("Expected address, found {}", self.flags); + } + Ok(self.raw_value) + } + + pub(crate) fn value_for_symbol_table(&self) -> u64 { + self.raw_value + } + + pub(crate) fn is_absolute(&self) -> bool { + self.flags.is_absolute() + } + + pub(crate) fn dynamic_symbol_index(&self) -> Result { + Ok(self + .dynamic_symbol_index + .context("Missing dynamic_symbol_index")? + .get()) + } + + #[inline(always)] + pub(crate) fn value_with_addend( + &self, + addend: i64, + symbol_index: object::SymbolIndex, + object_layout: &ObjectLayout, + merged_strings: &OutputSectionMap, + merged_string_start_addresses: &MergedStringStartAddresses, + ) -> Result { + if self.flags.is_ifunc() { + return Ok(self.plt_address()?.wrapping_add(addend as u64)); + } + + // For most symbols, `raw_value` won't be zero, so we can save ourselves from looking up the + // section to see if it's a string-merge section. For string-merge symbols with names, + // `raw_value` will have already been computed, so we can avoid computing it again. + if self.raw_value == 0 + && let Some(r) = get_merged_string_output_address( + symbol_index, + addend, + object_layout.object, + &object_layout.sections, + merged_strings, + merged_string_start_addresses, + false, + )? + { + if self.raw_value != 0 { + bail!("Merged string resolution has value 0x{}", self.raw_value); + } + return Ok(r); + } + Ok(self.raw_value.wrapping_add(addend as u64)) + } +} + +/// Maximum number of relaxation scan iterations. In practice convergence +/// happens in 2–3 passes. +const MAX_RELAXATION_ITERATIONS: usize = 5; + +/// Stores precomputed output-address information for every symbol. +struct SymbolOutputInfos { + addresses: Vec, +} + +impl SymbolOutputInfos { + fn resolve( + &self, + symbol_id: SymbolId, + per_symbol_flags: &PerSymbolFlags, + ) -> Option { + let addr = *self.addresses.get(symbol_id.as_usize())?; + if addr == 0 { + return None; + } + Some(RelaxSymbolInfo { + output_address: addr, + is_interposable: per_symbol_flags + .flags_for_symbol(symbol_id) + .is_interposable(), + }) + } +} + +/// Compute the output address of every loaded input section and every symbol in a single parallel +/// pass over groups. +fn compute_section_and_symbol_addresses<'data, O: ObjectFile<'data>>( + group_states: &[GroupState<'data>], + section_part_layouts: &OutputSectionPartMap, + symbol_db: &SymbolDb<'data, O>, +) -> (Vec>>, SymbolOutputInfos) { + timing_phase!("Compute section and symbol addresses"); + let mem_offsets: OutputSectionPartMap = starting_memory_offsets(section_part_layouts); + let starting_offsets = compute_start_offsets_by_group(group_states, mem_offsets); + + let symbol_addresses: Vec = (0..symbol_db.num_symbols()) + .map(|_| AtomicU64::new(0)) + .collect(); + + let section_addresses: Vec>> = group_states + .par_iter() + .enumerate() + .map(|(group_idx, group)| { + let mut offsets = starting_offsets[group_idx].clone(); + + group + .files + .iter() + .map(|file| match file { + FileLayoutState::Object(obj) => { + let mut addresses = vec![0u64; obj.sections.len()]; + for (sec_idx, slot) in obj.sections.iter().enumerate() { + match slot { + SectionSlot::Loaded(sec) => { + addresses[sec_idx] = *offsets.get(sec.part_id); + *offsets.get_mut(sec.part_id) += sec.capacity(); + } + SectionSlot::LoadedDebugInfo(sec) => { + // Advance offsets so subsequent sections are placed + // correctly, but we don't need the address for relaxation. + *offsets.get_mut(sec.part_id) += sec.capacity(); + } + _ => {} + } + } + + as ObjectFile<'data>>::compute_object_addresses( + obj, + &mut offsets, + ); + + // While we have the section addresses, also resolve symbol + // output addresses for this file's canonical definitions. + for sym_offset in 0..obj.symbol_id_range.len() { + let sym_input_idx = object::SymbolIndex(sym_offset); + let Ok(sym) = obj.object.symbol(sym_input_idx) else { + continue; + }; + let sym_id = obj.symbol_id_range.input_to_id(sym_input_idx); + let def_id = symbol_db.definition(sym_id); + // Only record the address for the canonical definition. + if def_id != sym_id { + continue; + } + + match obj.object.symbol_section(sym, sym_input_idx) { + Ok(Some(section)) => { + let sec_addr = addresses.get(section.0).copied().unwrap_or(0); + if sec_addr == 0 { + continue; + } + symbol_addresses[sym_id.as_usize()] + .store(sec_addr + sym.value(), Relaxed); + } + Ok(None) if sym.is_absolute() && sym.value() != 0 => { + symbol_addresses[sym_id.as_usize()].store(sym.value(), Relaxed); + } + _ => continue, + } + } + + addresses + } + _ => vec![], + }) + .collect() + }) + .collect(); + + let addresses = symbol_addresses + .into_iter() + .map(|a| a.into_inner()) + .collect(); + + (section_addresses, SymbolOutputInfos { addresses }) +} + +/// Per-file list of section indices to rescan on subsequent relaxation iterations. Indexed as +/// `[group_idx][file_idx]`. Files that are not objects get an empty entry. +type RescanSections = Vec>>; + +/// Like `RescanSections` but each entry also carries the minimum margin (in bytes) among the +/// section's unrelaxed candidates. This is returned by `relaxation_scan_pass` and then filtered +/// by `total_deleted` to produce a `RescanSections` for the next iteration. +type RescanCandidates = Vec>>; + +/// Run one pass of the relaxation scan across all groups/objects. Returns the total number of +/// bytes newly deleted in this pass together with the set of sections that should be rescanned on +/// the next iteration. +fn relaxation_scan_pass<'data, P: ElfPlatform<'data>>( + group_states: &mut [GroupState<'data>], + section_part_layouts: &OutputSectionPartMap, + symbol_db: &SymbolDb<'data, P::File>, + per_symbol_flags: &PerSymbolFlags, + section_part_sizes: &mut OutputSectionPartMap, + prev_rescan: Option<&RescanSections>, +) -> (u64, RescanCandidates) { + timing_phase!("Relaxation scan pass"); + + let (section_addresses, symbol_infos) = + compute_section_and_symbol_addresses(group_states, section_part_layouts, symbol_db); + + // Scan each group. + #[expect(clippy::type_complexity)] + let group_results: Vec<(OutputSectionPartMap, Vec>)> = + group_states + .par_iter_mut() + .enumerate() + .map(|(group_idx, group)| { + let mut reductions = + OutputSectionPartMap::with_size(section_part_sizes.num_parts()); + let mut file_rescans: Vec> = + Vec::with_capacity(group.files.len()); + + for (file_idx, file) in group.files.iter_mut().enumerate() { + let FileLayoutState::Object(obj) = file else { + file_rescans.push(SmallVec::new()); + continue; + }; + + let file_section_addrs = §ion_addresses[group_idx][file_idx]; + + let sections_to_scan: SmallVec<[usize; 16]> = match prev_rescan { + Some(rescan) => rescan[group_idx][file_idx].clone(), + None => obj + .sections + .iter() + .enumerate() + .filter_map(|(i, slot)| { + if let SectionSlot::Loaded(_) = slot + && let Ok(header) = obj.object.section(SectionIndex(i)) + && header.flags().is_executable() + { + Some(i) + } else { + None + } + }) + .collect(), + }; + + let mut next_rescan: SmallVec<[(usize, u64); 16]> = SmallVec::new(); + + for sec_idx in §ions_to_scan { + let sec_idx = *sec_idx; + let section_index = SectionIndex(sec_idx); + let relocs = match obj.object.relocations(section_index, &obj.relocations) { + Ok(r) => r, + Err(_) => continue, + }; + + let sec_output_addr = file_section_addrs.get(sec_idx).copied().unwrap_or(0); + if sec_output_addr == 0 { + continue; + } + + let existing_deltas = obj.section_relax_deltas.get(sec_idx); + + // Symbol resolver: look up the canonical definition's output + // address via the precomputed table. + let mut resolve_symbol = + |sym_idx: object::SymbolIndex| -> Option { + let local_id = obj.symbol_id_range.input_to_id(sym_idx); + let def_id = symbol_db.definition(local_id); + symbol_infos.resolve(def_id, per_symbol_flags) + }; + + let section_header = match obj.object.section(section_index) { + Ok(h) => h, + Err(_) => continue, + }; + let section_bytes = match obj.object.raw_section_data(section_header) { + Ok(d) => d, + Err(_) => continue, + }; + + let (raw_deltas, min_margin) = P::collect_relaxation_deltas( + sec_output_addr, + section_bytes, + relocs, + existing_deltas, + &mut resolve_symbol, + ); + + if let Some(margin) = min_margin { + next_rescan.push((sec_idx, margin)); + } + + if raw_deltas.is_empty() { + continue; + } + + let new_total_deleted: u64 = + raw_deltas.iter().map(|(_, b)| u64::from(*b)).sum(); + + if let SectionSlot::Loaded(sec) = &mut obj.sections[sec_idx] { + let old_capacity = sec.capacity(); + sec.size -= new_total_deleted; + let new_capacity = sec.capacity(); + debug_assert!(old_capacity >= new_capacity); + let capacity_reduction = old_capacity - new_capacity; + if capacity_reduction > 0 { + let part_id = sec.part_id; + group + .common + .mem_sizes + .decrement(part_id, capacity_reduction); + *reductions.get_mut(part_id) += capacity_reduction; + } + } + + if let Some(existing) = obj.section_relax_deltas.get_mut(sec_idx) { + existing.merge_additional(raw_deltas); + } else { + obj.section_relax_deltas + .insert_sorted(sec_idx, SectionRelaxDeltas::new(raw_deltas)); + } + } + + file_rescans.push(next_rescan); + } + + (reductions, file_rescans) + }) + .collect(); + + let mut total_deleted = 0u64; + let mut next_rescan_candidates: RescanCandidates = Vec::with_capacity(group_results.len()); + for (reduction, file_rescans) in group_results { + for (idx, &amount) in reduction.parts.iter().enumerate() { + if amount > 0 { + let part_id = PartId::from_usize(idx); + section_part_sizes.decrement(part_id, amount); + total_deleted += amount; + } + } + next_rescan_candidates.push(file_rescans); + } + + (total_deleted, next_rescan_candidates) +} + +fn perform_iterative_relaxation<'data, P: ElfPlatform<'data>>( + group_states: &mut [GroupState<'data>], + section_part_sizes: &mut OutputSectionPartMap, + section_part_layouts: &mut OutputSectionPartMap, + output_sections: &OutputSections, + program_segments: &ProgramSegments, + output_order: &OutputOrder, + symbol_db: &SymbolDb<'data, P::File>, + per_symbol_flags: &PerSymbolFlags, +) { + timing_phase!("Iterative relaxation"); + + let mut rescan_sections: Option = None; + + for _iteration in 0..MAX_RELAXATION_ITERATIONS { + if let Some(ref rescan) = rescan_sections + && rescan + .iter() + .all(|files| files.iter().all(|secs| secs.is_empty())) + { + break; + } + + let (deleted, next_candidates) = relaxation_scan_pass::

( + group_states, + section_part_layouts, + symbol_db, + per_symbol_flags, + section_part_sizes, + rescan_sections.as_ref(), + ); + + if deleted == 0 { + break; + } + + // Filter the rescan candidates: only keep sections whose closest + // unrelaxed candidate is within `deleted` bytes of the relaxation + // boundary. Candidates further away cannot possibly succeed because + // addresses shift by at most `deleted` bytes per iteration. + rescan_sections = Some( + next_candidates + .into_iter() + .map(|files| { + files + .into_iter() + .map(|secs| { + secs.into_iter() + .filter(|&(_, margin)| margin <= deleted) + .map(|(idx, _)| idx) + .collect() + }) + .collect() + }) + .collect(), + ); + + *section_part_layouts = layout_section_parts( + section_part_sizes, + output_sections, + program_segments, + output_order, + symbol_db.args, + ); + } +} + +fn layout_section_parts( + sizes: &OutputSectionPartMap, + output_sections: &OutputSections, + program_segments: &ProgramSegments, + output_order: &OutputOrder, + args: &Args, +) -> OutputSectionPartMap { + let segment_alignments = + compute_segment_alignments(sizes, program_segments, output_order, args); + + let mut file_offset = 0; + let mut mem_offset = output_sections.base_address; + let mut nonalloc_mem_offsets: OutputSectionMap = + OutputSectionMap::with_size(output_sections.num_sections()); + + let mut pending_location = None; + + let mut records_out = output_sections.new_part_map(); + + for event in output_order { + match event { + OrderEvent::SetLocation(location) => { + pending_location = Some(location); + } + OrderEvent::SegmentStart(segment_id) => { + if program_segments.is_load_segment(segment_id) { + let segment_alignment = segment_alignments + .get(&segment_id) + .copied() + .unwrap_or_else(|| args.loadable_segment_alignment()); + if let Some(location) = pending_location.take() { + mem_offset = location.address; + file_offset = + segment_alignment.align_modulo(mem_offset, file_offset as u64) as usize; + } else { + mem_offset = segment_alignment.align_modulo(file_offset as u64, mem_offset); + } + } + } + OrderEvent::SegmentEnd(_) => {} + OrderEvent::Section(section_id) => { + debug_assert!( + pending_location.is_none(), + "SetLocation, Section without SegmentStart" + ); + let section_info = output_sections.output_info(section_id); + let part_id_range = section_id.part_id_range(); + let max_alignment = sizes.max_alignment(part_id_range.clone()); + if let Some(location) = section_info.location { + mem_offset = location.address; + } + + records_out[part_id_range.clone()] + .iter_mut() + .zip(&sizes[part_id_range.clone()]) + .enumerate() + .for_each(|(offset, (part_layout, &part_size))| { + let part_id = part_id_range.start.offset(offset); + let alignment = part_id.alignment().min(max_alignment); + let merge_target = output_sections.primary_output_section(section_id); + let section_flags = output_sections.section_flags(merge_target); + let mem_size = if section_id == output_section_id::RELRO_PADDING { + let page_alignment = args.loadable_segment_alignment(); + let aligned_offset = page_alignment.align_up(mem_offset); + aligned_offset - mem_offset + } else { + part_size + }; + + // Note, we align up even if our size is zero, otherwise our section will + // start at an unaligned address. + file_offset = alignment.align_up_usize(file_offset); + + if section_flags.contains(shf::ALLOC) { + mem_offset = alignment.align_up(mem_offset); + + let file_size = if output_sections.has_data_in_file(merge_target) { + mem_size as usize + } else { + 0 + }; + + *part_layout = OutputRecordLayout { + file_size, + mem_size, + alignment, + file_offset, + mem_offset, + }; + + file_offset += file_size; + mem_offset += mem_size; + } else { + let section_id = part_id.output_section_id(); + let mem_offset = + alignment.align_up(*nonalloc_mem_offsets.get(section_id)); + + *nonalloc_mem_offsets.get_mut(section_id) += mem_size; + + *part_layout = OutputRecordLayout { + file_size: mem_size as usize, + mem_size, + alignment, + file_offset, + mem_offset, + }; + file_offset += mem_size as usize; + } + }); + } + }; + } + + records_out +} + +/// Computes the maximum alignment for each LOAD segment by examining the alignments of all sections +/// that will be placed in that segment. +fn compute_segment_alignments( + sizes: &OutputSectionPartMap, + program_segments: &ProgramSegments, + output_order: &OutputOrder, + args: &Args, +) -> HashMap { + timing_phase!("Computing segment alignments"); + + let mut segment_alignments: HashMap = HashMap::new(); + let mut active_load_segments: Vec = Vec::new(); + + for event in output_order { + match event { + OrderEvent::SegmentStart(segment_id) => { + if program_segments.is_load_segment(segment_id) { + // Initialize with the base loadable segment alignment + segment_alignments + .entry(segment_id) + .or_insert_with(|| args.loadable_segment_alignment()); + active_load_segments.push(segment_id); + } + } + OrderEvent::SegmentEnd(segment_id) => { + active_load_segments.retain(|&id| id != segment_id); + } + OrderEvent::Section(section_id) => { + let part_id_range = section_id.part_id_range(); + let max_alignment = sizes.max_alignment(part_id_range); + + // Update the alignment for all active LOAD segments + for &segment_id in &active_load_segments { + segment_alignments + .entry(segment_id) + .and_modify(|a| *a = (*a).max(max_alignment)); + } + } + OrderEvent::SetLocation(_) => {} + } + } + + segment_alignments +} + +impl<'data> DynamicLayoutState<'data> { + fn activate<'scope, P: ElfPlatform<'data>>( + &mut self, + common: &mut CommonGroupState<'data>, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + self.object + .activate_dynamic(&mut self.format_specific_state); + + common.allocate( + part_id::DYNAMIC, + size_of::() as u64, + ); + + common.allocate(part_id::DYNSTR, self.lib_name.len() as u64 + 1); + + self.request_all_undefined_symbols::

(resources, queue, scope) + } + + fn request_all_undefined_symbols<'scope, P: ElfPlatform<'data>>( + &self, + resources: &'scope GraphResources<'data, '_>, + queue: &mut LocalWorkQueue, + scope: &Scope<'scope>, + ) -> Result { + let mut check_undefined_cache = None; + + for symbol_id in self.symbol_id_range() { + let definition_symbol_id = resources.symbol_db.definition(symbol_id); + + let flags = resources.local_flags_for_symbol(definition_symbol_id); + + if flags.is_dynamic() && flags.is_absolute() { + // Our shared object references an undefined symbol. Whether that is an error or + // not, depends on flags, whether the symbol is weak and whether all of the shared + // object's dependencies are loaded. + + let args = resources.symbol_db.args; + let check_undefined = *check_undefined_cache.get_or_insert_with(|| { + let is_executable = resources.symbol_db.output_kind.is_executable(); + !args.allow_shlib_undefined + && is_executable + // Like lld, our behaviour for --no-allow-shlib-undefined is to only report + // errors for shared objects that have all their dependencies in the link. + // This is in contrast to GNU ld which recursively loads all transitive + // dependencies of shared objects and checks our shared object against + // those. + && self.has_complete_deps(resources) + }); + + if check_undefined { + let symbol = self + .object + .symbol(self.symbol_id_range.id_to_input(symbol_id))?; + if !symbol.is_weak() { + let should_report = !matches!( + args.unresolved_symbols, + crate::args::UnresolvedSymbols::IgnoreAll + | crate::args::UnresolvedSymbols::IgnoreInSharedLibs + ); + + if should_report { + let symbol_name = + resources.symbol_db.symbol_name_for_display(symbol_id); + + if args.error_unresolved_symbols { + bail!("undefined reference to `{symbol_name}` from {self}"); + } + crate::error::warning(&format!( + "undefined reference to `{symbol_name}` from {self}" + )); + } + } + } + } else if definition_symbol_id != symbol_id { + let file_id = resources.symbol_db.file_id_for_symbol(definition_symbol_id); + + queue.send_work::

( + resources, + file_id, + WorkItem::ExportDynamic(definition_symbol_id), + scope, + ); + } + } + + Ok(()) + } + + fn finalise_copy_relocations( + &mut self, + common: &mut CommonGroupState<'data>, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: &AtomicPerSymbolFlags, + ) -> Result { + // Skip iterating over our symbol table if we don't have any copy relocations. + if self.copy_relocations.is_empty() { + return Ok(()); + } + + self.select_copy_relocation_alternatives(per_symbol_flags, common, symbol_db) + } + + fn finalise_sizes(&mut self, common: &mut CommonGroupState<'data>) -> Result { + self.allocate_for_copy_relocations(common)?; + + self.object.finalise_sizes_dynamic( + self.lib_name, + &mut self.format_specific_state, + &mut common.mem_sizes, + )?; + Ok(()) + } + + /// Looks for any non-weak symbols at the same addresses as any of our copy relocations. If + /// found, we'll generate the copy relocation for the strong symbol instead of weak symbol at + /// the same address. + fn select_copy_relocation_alternatives( + &mut self, + per_symbol_flags: &AtomicPerSymbolFlags, + common: &mut CommonGroupState<'data>, + symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, + ) -> Result { + for (i, symbol) in self.object.symbols.iter().enumerate() { + let address = symbol.value(); + let Some(info) = self.copy_relocations.get_mut(&address) else { + continue; + }; + + let symbol_id = self.symbol_id_range.offset_to_id(i); + + if !symbol_db.is_canonical(symbol_id) { + continue; + } + + export_dynamic(common, symbol_id, symbol_db)?; + + per_symbol_flags + .get_atomic(symbol_id) + .fetch_or(ValueFlags::COPY_RELOCATION); + + if symbol.is_weak() || !info.is_weak || info.symbol_id == symbol_id { + continue; + } + + info.symbol_id = symbol_id; + info.is_weak = false; + } + + Ok(()) + } + + fn allocate_for_copy_relocations(&self, common: &mut CommonGroupState<'data>) -> Result { + for value in self.copy_relocations.values() { + let symbol_id = value.symbol_id; + + let symbol = self + .object + .symbol(self.symbol_id_range().id_to_input(symbol_id))?; + + let section_index = symbol.section_index(); + + let section = self.object.section(section_index)?; + + let alignment = Alignment::new(self.object.section_alignment(section)?)?; + + // Allocate space in BSS for the copy of the symbol. + let size = symbol.size(); + common.allocate( + output_section_id::BSS.part_id_with_alignment(alignment), + alignment.align_up(size), + ); + + // Allocate space required for the copy relocation itself. + common.allocate(part_id::RELA_DYN_GENERAL, crate::elf::RELA_ENTRY_SIZE); + } + + Ok(()) + } + + fn finalise_layout( + self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result> { + let copy_relocation_symbols = self + .copy_relocations + .values() + .map(|info| info.symbol_id) + // We'll write the copy relocations in this order, so we need to sort it to ensure + // deterministic output. + .sorted() + .collect_vec(); + + let copy_relocation_addresses = + self.assign_copy_relocation_addresses(©_relocation_symbols, memory_offsets)?; + + for (local_symbol, &flags) in self + .object + .symbols_iter() + .zip(resources.per_symbol_flags.raw_range(self.symbol_id_range())) + { + let flags = flags.get(); + + if !flags.has_resolution() { + resolutions_out.write(None)?; + continue; + } + + let address; + let dynamic_symbol_index; + + if flags.needs_copy_relocation() { + let input_address = local_symbol.value(); + + address = *copy_relocation_addresses + .get(&input_address) + .context("Internal error: Missing copy relocation address")?; + + // Since this is a definition, the dynamic symbol index will be determined by the + // epilogue and set by `update_dynamic_symbol_resolutions`. + dynamic_symbol_index = None; + } else { + address = 0; + let symbol_index = take_dynsym_index(memory_offsets, resources.section_layouts)?; + + dynamic_symbol_index = Some( + NonZeroU32::new(symbol_index) + .context("Tried to create dynamic symbol index 0")?, + ); + } + + let resolution = + create_resolution(flags, address, dynamic_symbol_index, memory_offsets); + + resolutions_out.write(Some(resolution))?; + } + + let file_id = self.file_id(); + + let format_specific_layout = self.object.finalise_layout_dynamic( + self.format_specific_state, + memory_offsets, + resources.section_layouts, + ); + + Ok(DynamicLayout { + file_id, + input: self.input, + lib_name: self.lib_name, + object: self.object, + symbol_id_range: self.symbol_id_range, + copy_relocation_symbols, + format_specific_layout, + }) + } + + fn copy_relocate_symbol<'scope>( + &mut self, + symbol_id: SymbolId, + resources: &GraphResources<'data, 'scope>, + ) -> std::result::Result<(), Error> { + let symbol = self + .object + .symbol(self.symbol_id_range().id_to_input(symbol_id))?; + + // Note, we're a shared object, so this is the address relative to the load address of the + // shared object, not an offset within a section like with regular input objects. That means + // that we don't need to take the section into account. + let address = symbol.value(); + + let info = self + .copy_relocations + .entry(address) + .or_insert_with(|| CopyRelocationInfo { + symbol_id, + is_weak: symbol.is_weak(), + }); + + info.add_symbol(symbol_id, symbol.is_weak(), resources); + + Ok(()) + } + + fn assign_copy_relocation_addresses( + &self, + copy_relocation_symbols: &[SymbolId], + memory_offsets: &mut OutputSectionPartMap, + ) -> Result> { + copy_relocation_symbols + .iter() + .map(|symbol_id| { + let symbol = self + .object + .symbol(self.symbol_id_range.id_to_input(*symbol_id))?; + + let input_address = symbol.value(); + + let output_address = + assign_copy_relocation_address(self.object, symbol, memory_offsets)?; + + Ok((input_address, output_address)) + }) + .try_collect() + } + + /// Return whether all DT_NEEDED entries for this shared object correspond to input files that + /// we have loaded. + fn has_complete_deps(&self, resources: &GraphResources) -> bool { + let Ok(dynamic_tags) = self.object.dynamic_tags() else { + return true; + }; + + let e = LittleEndian; + for entry in dynamic_tags { + let value = entry.d_val(e); + match entry.d_tag(e) as u32 { + object::elf::DT_NEEDED => { + let Ok(name) = self.object.symbols.strings().get(value as u32) else { + return false; + }; + if !resources.sonames.contains(name) { + return false; + } + } + _ => {} + } + } + + true + } +} + +impl<'data> LinkerScriptLayoutState<'data> { + fn finalise_layout( + &self, + memory_offsets: &mut OutputSectionPartMap, + resolutions_out: &mut ResolutionWriter, + resources: &FinaliseLayoutResources<'_, 'data>, + ) -> Result { + self.internal_symbols + .finalise_layout(memory_offsets, resolutions_out, resources) + } + + fn new(input: ResolvedLinkerScript<'data>) -> Self { + Self { + file_id: input.file_id, + input: input.input, + symbol_id_range: input.symbol_id_range, + internal_symbols: InternalSymbols { + symbol_definitions: input.symbol_definitions, + start_symbol_id: input.symbol_id_range.start(), + }, + } + } + + fn activate( + &self, + common: &mut CommonGroupState<'data>, + resources: &GraphResources<'data, '_>, + ) -> Result { + for (offset, def_info) in self.internal_symbols.symbol_definitions.iter().enumerate() { + let symbol_id = self.symbol_id_range.offset_to_id(offset); + if !resources.symbol_db.is_canonical(symbol_id) { + continue; + } + + // Mark the section referenced by this symbol so that empty sections + // defined by the linker script are still emitted. + if let Some(section_id) = def_info.section_id() { + resources + .must_keep_sections + .get(section_id) + .fetch_or(true, atomic::Ordering::Relaxed); + } + + // PROVIDE_HIDDEN symbols should not be exported to dynsym. + if def_info.is_hidden { + continue; + } + + resources + .per_symbol_flags + .get_atomic(symbol_id) + .fetch_or(ValueFlags::EXPORT_DYNAMIC); + + if resources.symbol_db.output_kind.needs_dynsym() { + export_dynamic(common, symbol_id, resources.symbol_db)?; + } + } + + Ok(()) + } + + fn finalise_sizes( + &self, + common: &mut CommonGroupState<'data>, + per_symbol_flags: &AtomicPerSymbolFlags, + resources: &FinaliseSizesResources, + ) -> Result { + self.internal_symbols.allocate_symbol_table_sizes( + &mut common.mem_sizes, + resources.symbol_db, + |symbol_id, _info| { + per_symbol_flags + .flags_for_symbol(symbol_id) + .has_resolution() + }, + )?; + + Ok(()) + } +} + +impl CopyRelocationInfo { + fn add_symbol(&mut self, symbol_id: SymbolId, is_weak: bool, resources: &GraphResources) { + if self.symbol_id == symbol_id || is_weak { + return; + } + + if !self.is_weak { + warning(&format!( + "Multiple non-weak symbols at the same address have copy relocations: {}, {}", + resources.symbol_debug(self.symbol_id), + resources.symbol_debug(symbol_id) + )); + } + + self.symbol_id = symbol_id; + self.is_weak = false; + } +} + +/// Assigns the address in BSS for the copy relocation of a symbol. +fn assign_copy_relocation_address( + file: &File, + local_symbol: &object::elf::Sym64, + memory_offsets: &mut OutputSectionPartMap, +) -> Result { + let section_index = local_symbol.section_index(); + let section = file.section(section_index)?; + let alignment = Alignment::new(file.section_alignment(section)?)?; + let bss = memory_offsets.get_mut(output_section_id::BSS.part_id_with_alignment(alignment)); + let a = *bss; + *bss += alignment.align_up(local_symbol.size()); + Ok(a) +} + +fn take_dynsym_index( + memory_offsets: &mut OutputSectionPartMap, + section_layouts: &OutputSectionMap, +) -> Result { + let index = u32::try_from( + (memory_offsets.get(part_id::DYNSYM) + - section_layouts.get(output_section_id::DYNSYM).mem_offset) + / crate::elf::SYMTAB_ENTRY_SIZE, + ) + .context("Too many dynamic symbols")?; + memory_offsets.increment(part_id::DYNSYM, crate::elf::SYMTAB_ENTRY_SIZE); + Ok(index) +} + +impl ElfLayout<'_> { + pub(crate) fn mem_address_of_built_in(&self, section_id: OutputSectionId) -> u64 { + self.section_layouts.get(section_id).mem_offset + } +} + +impl std::fmt::Debug for FileLayoutState<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FileLayoutState::Object(s) => f.debug_tuple("Object").field(&s.input).finish(), + FileLayoutState::Prelude(_) => f.debug_tuple("Internal").finish(), + FileLayoutState::Dynamic(s) => f.debug_tuple("Dynamic").field(&s.input).finish(), + FileLayoutState::LinkerScript(s) => { + f.debug_tuple("LinkerScript").field(&s.input).finish() + } + FileLayoutState::NotLoaded(_) => Display::fmt(&"", f), + FileLayoutState::Epilogue(_) => Display::fmt(&"", f), + FileLayoutState::SyntheticSymbols(_) => Display::fmt(&"", f), + } + } +} + +fn section_debug( + object: &crate::elf::File, + section_index: object::SectionIndex, +) -> impl std::fmt::Display { + let name = object + .section(section_index) + .and_then(|section| object.section_name(section)) + .map_or_else( + |_| "??".to_owned(), + |name| String::from_utf8_lossy(name).into_owned(), + ); + std::fmt::from_fn(move |f| write!(f, "`{name}`")) +} + +impl<'data> DynamicSymbolDefinition<'data> { + fn new(symbol_id: SymbolId, name: &'data [u8], version: u16) -> Self { + Self { + symbol_id, + name, + hash: gnu_hash(name), + version, + } + } +} + +impl SectionLoadRequest { + fn new(file_id: FileId, section_index: SectionIndex) -> Self { + Self { + file_id, + section_index: section_index.0 as u32, + } + } + + fn section_index(self) -> SectionIndex { + SectionIndex(self.section_index as usize) + } +} + +fn needs_tlsld(relocation_kind: RelocationKind) -> bool { + matches!( + relocation_kind, + RelocationKind::TlsLd | RelocationKind::TlsLdGot | RelocationKind::TlsLdGotBase + ) +} + +impl<'data> ObjectLayout<'data> { + pub(crate) fn relocations(&self, index: SectionIndex) -> Result> { + self.object.relocations(index, &self.relocations) + } +} + +/// Performs layout of sections and segments then makes sure that the loadable segments don't +/// overlap and that sections don't overlap. +#[test] +fn test_no_disallowed_overlaps() { + use crate::output_section_id::OrderEvent; + + let mut output_sections = OutputSections::with_base_address(0x1000); + let (output_order, program_segments) = output_sections.output_order(); + let args = Args::::default(); + let section_part_sizes = output_sections.new_part_map::().map(|_, _| 7); + + let section_part_layouts = layout_section_parts( + §ion_part_sizes, + &output_sections, + &program_segments, + &output_order, + &args, + ); + + let section_layouts = layout_sections(&output_sections, §ion_part_layouts); + + // Make sure no alloc sections overlap + let mut last_file_start = 0; + let mut last_mem_start = 0; + let mut last_file_end = 0; + let mut last_mem_end = 0; + let mut last_section_id = output_section_id::FILE_HEADER; + + for event in &output_order { + let OrderEvent::Section(section_id) = event else { + continue; + }; + + let section_flags = output_sections.section_flags(section_id); + if !section_flags.contains(shf::ALLOC) { + return; + } + + let section = section_layouts.get(section_id); + let mem_offset = section.mem_offset; + let mem_end = mem_offset + section.mem_size; + assert!( + mem_offset >= last_mem_end, + "Memory sections: {last_section_id} @{last_mem_start:x}..{last_mem_end:x} overlaps {section_id} @{mem_offset:x}..{mem_end:x}", + ); + let file_offset = section.file_offset; + let file_end = file_offset + section.file_size; + assert!( + file_offset >= last_file_end, + "File sections {last_section_id} @{last_file_start:x}..{last_file_end} {section_id} @{file_offset:x}..{file_end:x}", + ); + last_mem_start = mem_offset; + last_file_start = file_offset; + last_mem_end = mem_end; + last_file_end = file_end; + last_section_id = section_id; + } + + let header_info = HeaderInfo { + num_output_sections_with_content: 0, + active_segment_ids: (0..program_segments.len()) + .map(ProgramSegmentId::new) + .collect(), + }; + + let mut section_index = 0; + output_sections.section_infos.for_each(|_, info| { + if info.section_flags.contains(shf::ALLOC) { + output_sections + .output_section_indexes + .push(Some(section_index)); + section_index += 1; + } else { + output_sections.output_section_indexes.push(None); + } + }); + + let segment_layouts = compute_segment_layout( + §ion_layouts, + &output_sections, + &output_order, + &program_segments, + &header_info, + &args, + ) + .unwrap(); + + // Make sure loadable segments don't overlap in memory or in the file. + let mut last_file = 0; + let mut last_mem = 0; + for seg_layout in &segment_layouts.segments { + let seg_id = seg_layout.id; + if program_segments.is_load_segment(seg_id) { + continue; + } + assert!( + seg_layout.sizes.mem_offset >= last_mem, + "Overlapping memory segment: {} < {}", + last_mem, + seg_layout.sizes.mem_offset, + ); + assert!( + seg_layout.sizes.file_offset >= last_file, + "Overlapping file segment {} < {}", + last_file, + seg_layout.sizes.file_offset, + ); + last_mem = seg_layout.sizes.mem_offset + seg_layout.sizes.mem_size; + last_file = seg_layout.sizes.file_offset + seg_layout.sizes.file_size; + } +} + +/// Verifies that we allocate and use consistent amounts of various output sections for the supplied +/// combination of flags and output kind. If this function returns an error, then we would have +/// failed during writing anyway. By failing now, we can report the particular combination of inputs +/// that caused the failure. +fn verify_consistent_allocation_handling(flags: ValueFlags, output_kind: OutputKind) -> Result { + let output_sections = OutputSections::with_base_address(0); + let (output_order, _program_segments) = output_sections.output_order(); + let mut mem_sizes = output_sections.new_part_map(); + allocate_symbol_resolution(flags, &mut mem_sizes, output_kind); + let mut memory_offsets = output_sections.new_part_map(); + *memory_offsets.get_mut(part_id::GOT) = 0x10; + *memory_offsets.get_mut(part_id::PLT_GOT) = 0x10; + let has_dynamic_symbol = + flags.is_dynamic() || (flags.needs_export_dynamic() && flags.is_interposable()); + let dynamic_symbol_index = has_dynamic_symbol.then(|| NonZeroU32::new(1).unwrap()); + + let resolution = create_resolution(flags, 0, dynamic_symbol_index, &mut memory_offsets); + + elf_writer::verify_resolution_allocation( + &output_sections, + &output_order, + output_kind, + &mem_sizes, + &resolution, + ) + .with_context(|| { + format!( + "Inconsistent allocation detected. \ + output_kind={output_kind:?} \ + flags={flags} \ + has_dynamic_symbol={has_dynamic_symbol:?}" + ) + })?; + + Ok(()) +} + +pub(crate) struct Sonames<'data>(HashSet<&'data [u8]>); + +impl<'data> Sonames<'data> { + /// Builds an index of the DT_SONAMEs of the input dynamic objects. Note, that we include + /// --as-needed shared objects that we're not actually linking against. This means that we can + /// report --no-shlib-undefined errors for shared libraries that have all of their dependencies + /// as inputs, even if we weren't going to add them as direct dependencies of our output file. + fn new(groups: &[Group<'data, crate::elf::File<'data>>]) -> Self { + timing_phase!("Build SONAME index"); + + Sonames( + groups + .iter() + .flat_map(|group| { + let objects = match group { + Group::Objects(objects) => *objects, + _ => &[], + }; + objects.iter().filter_map(|input| { + input + .parsed + .object + .dynamic_tag_values() + .map(|tag_values| tag_values.lib_name(&input.parsed.input)) + }) + }) + .collect(), + ) + } + + fn contains(&self, name: &[u8]) -> bool { + self.0.contains(name) + } +} + +impl<'scope, 'data> FinaliseLayoutResources<'scope, 'data> { + fn symbol_debug<'a>( + &'a self, + symbol_id: SymbolId, + ) -> SymbolDebug<'a, 'data, crate::elf::File<'data>> { + self.symbol_db + .symbol_debug(self.per_symbol_flags, symbol_id) + } +} + +impl OutputRecordLayout { + fn merge(&mut self, other: &OutputRecordLayout) { + debug_assert!(other.mem_offset >= self.mem_offset); + debug_assert!(other.file_offset >= self.file_offset); + self.mem_size += other.mem_size; + self.file_size += other.file_size; + if other.mem_size > 0 { + self.alignment = self.alignment.max(other.alignment); + } + } +} diff --git a/libwild/src/elf_loongarch64.rs b/libwild/src/elf_loongarch64.rs index c7c7ee1be..afe33ab51 100644 --- a/libwild/src/elf_loongarch64.rs +++ b/libwild/src/elf_loongarch64.rs @@ -34,9 +34,43 @@ macro_rules! rel_info_from_type { } impl<'data> crate::platform::Platform<'data> for ElfLoongArch64 { - type Relaxation = Relaxation; type File = crate::elf::File<'data>; + fn create_plugin( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result>> { + crate::linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) + } + + fn load_auxiliary( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result> { + crate::input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) + } + + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data crate::Args, + plugin: &mut Option>, + symbol_db: crate::symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, crate::elf::File<'data>>, + output_sections: crate::output_section_id::OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> crate::error::Result>> { + ::finish_link( + file_loader, args, plugin, symbol_db, per_symbol_flags, + resolver, output_sections, layout_rules_builder, output_kind, + ) + } +} + +impl<'data> crate::platform::ElfPlatform<'data> for ElfLoongArch64 { + type Relaxation = Relaxation; + fn elf_header_arch_magic() -> u16 { object::elf::EM_LOONGARCH } @@ -86,7 +120,7 @@ impl<'data> crate::platform::Platform<'data> for ElfLoongArch64 { true } - fn tp_offset_start(layout: &crate::layout::Layout) -> u64 { + fn tp_offset_start(layout: &crate::layout::Layout<'data, crate::elf_layout::ElfLayout<'data>>) -> u64 { layout.tls_start_address() } diff --git a/libwild/src/elf_riscv64.rs b/libwild/src/elf_riscv64.rs index d09b0a8c7..ac397cf77 100644 --- a/libwild/src/elf_riscv64.rs +++ b/libwild/src/elf_riscv64.rs @@ -46,9 +46,43 @@ macro_rules! rel_info_from_type { } impl<'data> crate::platform::Platform<'data> for ElfRiscV64 { - type Relaxation = Relaxation; type File = crate::elf::File<'data>; + fn create_plugin( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result>> { + crate::linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) + } + + fn load_auxiliary( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result> { + crate::input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) + } + + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data crate::Args, + plugin: &mut Option>, + symbol_db: crate::symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, crate::elf::File<'data>>, + output_sections: crate::output_section_id::OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> crate::error::Result>> { + ::finish_link( + file_loader, args, plugin, symbol_db, per_symbol_flags, + resolver, output_sections, layout_rules_builder, output_kind, + ) + } +} + +impl<'data> crate::platform::ElfPlatform<'data> for ElfRiscV64 { + type Relaxation = Relaxation; + fn elf_header_arch_magic() -> u16 { object::elf::EM_RISCV } @@ -97,7 +131,7 @@ impl<'data> crate::platform::Platform<'data> for ElfRiscV64 { true } - fn tp_offset_start(layout: &crate::layout::Layout) -> u64 { + fn tp_offset_start(layout: &crate::layout::Layout<'data, crate::elf_layout::ElfLayout<'data>>) -> u64 { layout.tls_start_address() } diff --git a/libwild/src/elf_writer.rs b/libwild/src/elf_writer.rs index ee8e969d3..5741746f7 100644 --- a/libwild/src/elf_writer.rs +++ b/libwild/src/elf_writer.rs @@ -42,21 +42,22 @@ use crate::file_writer::insufficient_allocation; use crate::file_writer::split_buffers_by_alignment; use crate::file_writer::split_output_by_group; use crate::file_writer::split_output_into_sections; -use crate::layout::DynamicLayout; -use crate::layout::EpilogueLayout; -use crate::layout::FileLayout; -use crate::layout::HeaderInfo; +use crate::elf_layout::DynamicLayout; +use crate::elf_layout::ElfLayout; +use crate::elf_layout::EpilogueLayout; +use crate::elf_layout::FileLayout; +use crate::elf_layout::HeaderInfo; +use crate::elf_layout::LinkerScriptLayoutState; +use crate::elf_layout::ObjectLayout; +use crate::elf_layout::PreludeLayout; +use crate::layout::Resolution; +use crate::elf_layout::SymbolCopyInfo; +use crate::elf_layout::SyntheticSymbolsLayout; +use crate::elf_layout::compute_allocations; use crate::layout::InternalSymbols; use crate::layout::Layout; -use crate::layout::LinkerScriptLayoutState; -use crate::layout::ObjectLayout; use crate::layout::OutputRecordLayout; -use crate::layout::PreludeLayout; -use crate::layout::Resolution; use crate::layout::Section; -use crate::layout::SymbolCopyInfo; -use crate::layout::SyntheticSymbolsLayout; -use crate::layout::compute_allocations; use crate::output_section_id; use crate::output_section_id::OrderEvent; use crate::output_section_id::OutputOrder; @@ -68,7 +69,7 @@ use crate::output_trace::HexU64; use crate::output_trace::TraceOutput; use crate::part_id; use crate::platform::ObjectFile as _; -use crate::platform::Platform; +use crate::platform::ElfPlatform; use crate::platform::RawSymbolName as _; use crate::platform::Relaxation as _; use crate::platform::Relocation; @@ -147,9 +148,9 @@ struct RelocationCache { high_part_symbols: HashMap, } -pub(crate) fn write<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +pub(crate) fn write<'data, P: ElfPlatform<'data>>( sized_output: &mut SizedOutput, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { write_file_contents::

(sized_output, layout)?; if layout.args().validate_output { @@ -168,10 +169,10 @@ pub(crate) fn write<'data, P: Platform<'data, File = crate::elf::File<'data>>>( Ok(()) } -fn write_gnu_build_id_note( +fn write_gnu_build_id_note<'data>( sized_output: &mut SizedOutput, build_id_option: &BuildIdOption, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { let hash_placeholder; let uuid_placeholder; @@ -212,9 +213,9 @@ fn compute_hash(sized_output: &SizedOutput) -> blake3::Hash { .finalize() } -fn write_file_contents<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_file_contents<'data, P: ElfPlatform<'data>>( sized_output: &mut SizedOutput, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { timing_phase!("Write data to file"); let mut section_buffers = split_output_into_sections(layout, &mut sized_output.out); @@ -275,7 +276,7 @@ fn fill_padding(mut section_buffers: OutputSectionMap<&mut [u8]>) { }); } -fn write_sframe_section(sframe_buffer: &mut [u8], layout: &Layout) -> Result { +fn write_sframe_section<'data>(sframe_buffer: &mut [u8], layout: &Layout<'data, ElfLayout<'data>>) -> Result { if sframe_buffer.is_empty() { return Ok(()); } @@ -307,7 +308,7 @@ fn sort_eh_frame_hdr_entries(eh_frame_hdr: &mut [u8]) { entries.par_sort_by_key(|e| e.frame_ptr); } -fn write_program_headers(program_headers_out: &mut ProgramHeaderWriter, layout: &Layout) -> Result { +fn write_program_headers<'data>(program_headers_out: &mut ProgramHeaderWriter, layout: &Layout<'data, ElfLayout<'data>>) -> Result { for segment_layout in &layout.segment_layouts.segments { let segment_sizes = &segment_layout.sizes; let segment_id = segment_layout.id; @@ -348,8 +349,8 @@ fn write_program_headers(program_headers_out: &mut ProgramHeaderWriter, layout: Ok(()) } -fn populate_file_header<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - layout: &Layout, +fn populate_file_header<'data, P: ElfPlatform<'data>>( + layout: &Layout<'data, ElfLayout<'data>>, header_info: &HeaderInfo, header: &mut FileHeader, ) -> Result { @@ -398,11 +399,11 @@ fn populate_file_header<'data, P: Platform<'data, File = crate::elf::File<'data> Ok(()) } -fn write_file<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_file<'data, P: ElfPlatform<'data>>( file: &FileLayout<'data>, buffers: &mut OutputSectionPartMap<&mut [u8]>, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, trace: &TraceOutput, ) -> Result { match file { @@ -542,8 +543,8 @@ struct TableWriter<'layout, 'out> { } impl<'layout, 'out> TableWriter<'layout, 'out> { - fn from_layout( - layout: &'layout Layout, + fn from_layout<'data>( + layout: &'layout Layout<'data, ElfLayout<'data>>, dynstr_start_offset: u32, strtab_start_offset: u32, buffers: &mut OutputSectionPartMap<&'out mut [u8]>, @@ -600,9 +601,9 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { } } - fn process_resolution<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn process_resolution<'data, P: ElfPlatform<'data>>( &mut self, - layout: Option<&Layout<'data>>, + layout: Option<&Layout<'data, ElfLayout<'data>>>, res: &Resolution, ) -> Result { let Some(got_address) = res.got_address else { @@ -683,10 +684,10 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn process_got_tls_offset<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn process_got_tls_offset<'data, P: ElfPlatform<'data>>( &mut self, res: &Resolution, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, got_address: u64, ) -> Result { let got_entry = self.take_next_got_entry()?; @@ -725,7 +726,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn process_got_tls_mod_and_offset<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn process_got_tls_mod_and_offset<'data, P: ElfPlatform<'data>>( &mut self, res: &Resolution, got_address: u64, @@ -762,7 +763,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn process_got_tls_descriptor<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn process_got_tls_descriptor<'data, P: ElfPlatform<'data>>( &mut self, res: &Resolution, got_address: u64, @@ -792,7 +793,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn write_plt_entry<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_plt_entry<'data, P: ElfPlatform<'data>>( &mut self, got_address: u64, plt_address: u64, @@ -867,7 +868,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn write_ifunc_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_ifunc_relocation<'data, P: ElfPlatform<'data>>( &mut self, res: &Resolution, ) -> Result { @@ -888,7 +889,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { Ok(()) } - fn write_dtpmod_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_dtpmod_relocation<'data, P: ElfPlatform<'data>>( &mut self, place: u64, dynamic_symbol_index: u32, @@ -903,7 +904,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { fn write_tls_descriptor_relocation< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, >( &mut self, place: u64, @@ -918,7 +919,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { ) } - fn write_dtpoff_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_dtpoff_relocation<'data, P: ElfPlatform<'data>>( &mut self, place: u64, dynamic_symbol_index: u32, @@ -931,7 +932,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { ) } - fn write_tpoff_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_tpoff_relocation<'data, P: ElfPlatform<'data>>( &mut self, place: u64, dynamic_symbol_index: u32, @@ -946,7 +947,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { } #[inline(always)] - fn write_address_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( + fn write_address_relocation<'data, P: ElfPlatform<'data>>( &mut self, place: u64, relative_address: i64, @@ -971,7 +972,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { fn write_ifunc_relocation_for_data< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, >( &mut self, place: u64, @@ -989,7 +990,7 @@ impl<'layout, 'out> TableWriter<'layout, 'out> { fn write_dynamic_symbol_relocation< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, >( &mut self, place: u64, @@ -1281,11 +1282,11 @@ impl<'layout, 'out> SymbolTableWriter<'layout, 'out> { } } -fn write_object<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_object<'data, P: ElfPlatform<'data>>( object: &ObjectLayout<'data>, buffers: &mut OutputSectionPartMap<&mut [u8]>, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, trace: &TraceOutput, ) -> Result { verbose_timing_phase!("Write object", file_id = object.file_id.as_u32()); @@ -1348,9 +1349,9 @@ fn write_object<'data, P: Platform<'data, File = crate::elf::File<'data>>>( Ok(()) } -fn write_object_section<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_object_section<'data, P: ElfPlatform<'data>>( object: &ObjectLayout<'data>, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, section: &Section, buffers: &mut OutputSectionPartMap<&mut [u8]>, table_writer: &mut TableWriter, @@ -1399,9 +1400,9 @@ fn write_object_section<'data, P: Platform<'data, File = crate::elf::File<'data> Ok(()) } -fn write_section_reversed<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_section_reversed<'data, P: ElfPlatform<'data>>( object: &ObjectLayout<'data>, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, section: &Section, table_writer: &mut TableWriter<'_, '_>, trace: &TraceOutput, @@ -1470,9 +1471,9 @@ fn write_section_reversed<'data, P: Platform<'data, File = crate::elf::File<'dat Ok(()) } -fn write_debug_section<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_debug_section<'data, P: ElfPlatform<'data>>( object: &ObjectLayout<'data>, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, section: &Section, buffers: &mut OutputSectionPartMap<&mut [u8]>, ) -> Result { @@ -1500,9 +1501,9 @@ fn write_debug_section<'data, P: Platform<'data, File = crate::elf::File<'data>> Ok(()) } -fn write_section_raw<'out>( +fn write_section_raw<'data, 'out>( object: &ObjectLayout, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, sec: &Section, buffers: &'out mut OutputSectionPartMap<&mut [u8]>, ) -> Result<&'out mut [u8]> { @@ -1570,10 +1571,10 @@ fn write_section_raw<'out>( } /// Writes debug symbols. -fn write_symbols( +fn write_symbols<'data>( object: &ObjectLayout, symbol_writer: &mut SymbolTableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { for ((sym_index, sym), flags) in object .object @@ -1660,7 +1661,7 @@ fn write_symbols( fn apply_relocations< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, I: Iterator> + Clone, >( @@ -1668,7 +1669,7 @@ fn apply_relocations< out: &mut [u8], section: &Section, mut relocations: I, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, table_writer: &mut TableWriter, trace: &TraceOutput, ) -> Result { @@ -1741,7 +1742,7 @@ fn apply_relocations< fn apply_debug_relocations< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, I: Iterator> + Clone, >( @@ -1749,7 +1750,7 @@ fn apply_debug_relocations< out: &mut [u8], section: &Section, relocations: I, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { let object_section = object.object.section(section.index)?; let section_name = object.object.section_name(object_section)?; @@ -1798,10 +1799,10 @@ fn apply_debug_relocations< Ok(()) } -fn write_eh_frame_data<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_eh_frame_data<'data, P: ElfPlatform<'data>>( object: &ObjectLayout<'data>, eh_frame_section_index: object::SectionIndex, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, table_writer: &mut TableWriter, trace: &TraceOutput, ) -> Result { @@ -1828,11 +1829,11 @@ fn write_eh_frame_data<'data, P: Platform<'data, File = crate::elf::File<'data>> fn write_eh_frame_relocations< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( object: &ObjectLayout<'data>, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, table_writer: &mut TableWriter<'_, '_>, trace: &TraceOutput, eh_frame_section: &object::elf::SectionHeader64, @@ -2003,12 +2004,12 @@ fn write_eh_frame_relocations< fn display_relocation< 'a, 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( object: &'a ObjectLayout<'data>, rel: &'a R, - layout: &'a Layout<'data>, + layout: &'a Layout<'data, ElfLayout<'data>>, ) -> DisplayRelocation<'a, 'data, P, R> { DisplayRelocation::<'a, 'data, P, R> { rel, @@ -2022,7 +2023,7 @@ fn display_relocation< struct DisplayRelocation< 'a, 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, > { rel: &'a R, @@ -2032,7 +2033,7 @@ struct DisplayRelocation< phantom: PhantomData

, } -impl<'a, 'data, P: Platform<'data, File = crate::elf::File<'data>>, R: Relocation> Display +impl<'a, 'data, P: ElfPlatform<'data>, R: Relocation> Display for DisplayRelocation<'a, 'data, P, R> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -2064,10 +2065,10 @@ struct SectionInfo { section_flags: SectionFlags, } -fn get_resolution( +fn get_resolution<'data, R: Relocation>( rel: &R, object_layout: &ObjectLayout, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result<(Resolution, SymbolIndex, SymbolId)> { let symbol_index = rel.symbol().context("Unsupported absolute relocation")?; let local_symbol_id = object_layout.symbol_id_range.input_to_id(symbol_index); @@ -2090,8 +2091,8 @@ fn get_resolution( Ok((resolution, symbol_index, local_symbol_id)) } -fn write_got_plt_syms( - layout: &Layout, +fn write_got_plt_syms<'data>( + layout: &Layout<'data, ElfLayout<'data>>, symbol_writer: &mut SymbolTableWriter<'_, '_>, symbol_id: SymbolId, ) -> Result { @@ -2189,12 +2190,12 @@ fn adjust_relocation_based_on_value( #[inline(always)] fn get_pair_subtraction_relocation_value< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( object_layout: &ObjectLayout, rel: &R, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, resolution: Resolution, symbol_index: SymbolIndex, addend: i64, @@ -2236,7 +2237,7 @@ fn get_pair_subtraction_relocation_value< #[inline(always)] fn apply_relocation< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, I: Iterator> + Clone, >( @@ -2244,7 +2245,7 @@ fn apply_relocation< mut offset_in_section: u64, rel: &R, section_info: SectionInfo, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, out: &mut [u8], table_writer: &mut TableWriter, trace: &TraceOutput, @@ -2695,13 +2696,13 @@ fn apply_relocation< fn apply_debug_relocation< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, R: Relocation, >( object_layout: &ObjectLayout, offset_in_section: u64, rel: &R, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, section_tombstone_value: u64, out: &mut [u8], relocation_cache: &RelocationCache, @@ -2806,7 +2807,7 @@ fn apply_debug_relocation< } #[inline(always)] -fn write_absolute_relocation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_absolute_relocation<'data, P: ElfPlatform<'data>>( table_writer: &mut TableWriter, resolution: Resolution, place: u64, @@ -2814,7 +2815,7 @@ fn write_absolute_relocation<'data, P: Platform<'data, File = crate::elf::File<' section_info: SectionInfo, symbol_index: object::SymbolIndex, object_layout: &ObjectLayout, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { if !section_info.section_flags.is_alloc() { resolution.value_with_addend( @@ -2869,11 +2870,11 @@ fn write_absolute_relocation<'data, P: Platform<'data, File = crate::elf::File<' } } -fn write_prelude<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_prelude<'data, P: ElfPlatform<'data>>( prelude: &PreludeLayout, buffers: &mut OutputSectionPartMap<&mut [u8]>, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { verbose_timing_phase!("Write prelude"); @@ -2933,10 +2934,10 @@ fn write_interp(prelude: &PreludeLayout, buffers: &mut OutputSectionPartMap<&mut } } -fn write_merged_strings( +fn write_merged_strings<'data>( prelude: &PreludeLayout, buffers: &mut OutputSectionPartMap<&mut [u8]>, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) { layout.merged_strings.for_each(|section_id, merged| { if merged.len() > 0 { @@ -2967,9 +2968,9 @@ fn write_merged_strings( } } -fn write_plt_got_entries<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_plt_got_entries<'data, P: ElfPlatform<'data>>( prelude: &PreludeLayout, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, table_writer: &mut TableWriter, ) -> Result { // Write a pair of GOT entries for use by any TLSLD or TLSGD relocations. @@ -3012,10 +3013,10 @@ fn write_plt_got_entries<'data, P: Platform<'data, File = crate::elf::File<'data Ok(()) } -fn write_symbol_table_entries( +fn write_symbol_table_entries<'data>( prelude: &PreludeLayout, symbol_writer: &mut SymbolTableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { // Define symbol 0. This needs to be a null placeholder. symbol_writer.define_symbol(true, 0, 0, 0, &[])?; @@ -3110,8 +3111,8 @@ fn write_verdef( Ok(()) } -fn write_epilogue_dynamic_entries( - layout: &Layout, +fn write_epilogue_dynamic_entries<'data>( + layout: &Layout<'data, ElfLayout<'data>>, table_writer: &mut TableWriter, epilogue_offsets: &mut EpilogueOffsets, ) -> Result { @@ -3172,10 +3173,10 @@ pub(crate) struct EpilogueOffsets { pub(crate) soname: Option, } -fn write_linker_script_state<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_linker_script_state<'data, P: ElfPlatform<'data>>( script: &LinkerScriptLayoutState, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { verbose_timing_phase!("Write linker script state"); @@ -3190,10 +3191,10 @@ fn write_linker_script_state<'data, P: Platform<'data, File = crate::elf::File<' Ok(()) } -fn write_synthetic_symbols<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_synthetic_symbols<'data, P: ElfPlatform<'data>>( syn: &SyntheticSymbolsLayout, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { verbose_timing_phase!("Write epilogue"); @@ -3210,11 +3211,11 @@ fn write_synthetic_symbols<'data, P: Platform<'data, File = crate::elf::File<'da Ok(()) } -fn write_epilogue<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_epilogue<'data, P: ElfPlatform<'data>>( epilogue: &EpilogueLayout, buffers: &mut OutputSectionPartMap<&mut [u8]>, table_writer: &mut TableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { verbose_timing_phase!("Write epilogue"); @@ -3263,8 +3264,8 @@ fn write_epilogue<'data, P: Platform<'data, File = crate::elf::File<'data>>>( Ok(()) } -fn write_gnu_property_notes( - layout: &Layout, +fn write_gnu_property_notes<'data>( + layout: &Layout<'data, ElfLayout<'data>>, buffers: &mut OutputSectionPartMap<&mut [u8]>, ) -> Result { let e = LittleEndian; @@ -3294,8 +3295,8 @@ fn write_gnu_property_notes( Ok(()) } -fn write_riscv_attributes( - layout: &Layout, +fn write_riscv_attributes<'data>( + layout: &Layout<'data, ElfLayout<'data>>, buffers: &mut OutputSectionPartMap<&mut [u8]>, ) -> Result { let mut writer = Cursor::new(&mut **buffers.get_mut(part_id::RISCV_ATTRIBUTES)); @@ -3348,8 +3349,8 @@ fn write_riscv_attributes( Ok(()) } -fn write_sysv_hash_table( - layout: &Layout, +fn write_sysv_hash_table<'data>( + layout: &Layout<'data, ElfLayout<'data>>, epilogue: &EpilogueLayout, buffers: &mut OutputSectionPartMap<&mut [u8]>, ) -> Result { @@ -3419,8 +3420,8 @@ fn write_sysv_hash_table( Ok(()) } -fn write_gnu_hash_tables( - layout: &Layout, +fn write_gnu_hash_tables<'data>( + layout: &Layout<'data, ElfLayout<'data>>, epilogue: &EpilogueLayout, buffers: &mut OutputSectionPartMap<&mut [u8]>, ) -> Result { @@ -3489,7 +3490,7 @@ fn write_gnu_hash_tables( Ok(()) } -fn write_dynamic_symbol_definitions(table_writer: &mut TableWriter, layout: &Layout) -> Result { +fn write_dynamic_symbol_definitions<'data>(table_writer: &mut TableWriter, layout: &Layout<'data, ElfLayout<'data>>) -> Result { let chunk_size = 10.max(layout.dynamic_symbol_definitions.len() / 10 / rayon::current_num_threads()); @@ -3570,9 +3571,9 @@ fn write_dynamic_symbol_definitions(table_writer: &mut TableWriter, layout: &Lay } /// Writes a symbol that was produced by a linker script. -fn write_linker_script_dynsym( +fn write_linker_script_dynsym<'data>( dynsym_writer: &mut SymbolTableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, symbol_id: SymbolId, script: &LinkerScriptLayoutState, ) -> Result { @@ -3618,7 +3619,7 @@ fn write_linker_script_dynsym( /// Get the section index and type for a symbol. /// This is used to copy attributes from a target symbol to a defsym alias. -fn get_symbol_attributes(layout: &Layout, symbol_id: SymbolId) -> Result<(u16, u8)> { +fn get_symbol_attributes<'data>(layout: &Layout<'data, ElfLayout<'data>>, symbol_id: SymbolId) -> Result<(u16, u8)> { let file_id = layout.symbol_db.file_id_for_symbol(symbol_id); let file = layout.symbol_db.file(file_id); @@ -3679,9 +3680,9 @@ fn get_symbol_attributes(layout: &Layout, symbol_id: SymbolId) -> Result<(u16, u } } -fn write_prelude_dynsym( +fn write_prelude_dynsym<'data>( dynsym_writer: &mut SymbolTableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, symbol_id: SymbolId, prelude: &PreludeLayout, ) -> Result { @@ -3696,9 +3697,9 @@ fn write_prelude_dynsym( } /// Writes a dynsym entry for a symbol defined via --defsym or linker script symbol assignment. -fn write_defsym_dynsym( +fn write_defsym_dynsym<'data>( dynsym_writer: &mut SymbolTableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, symbol_id: SymbolId, def_info: &crate::parsing::InternalSymDefInfo, ) -> Result { @@ -3750,10 +3751,10 @@ fn write_defsym_dynsym( Ok(()) } -fn write_copy_relocation_dynamic_symbol_definition( +fn write_copy_relocation_dynamic_symbol_definition<'data>( sym_def: &crate::layout::DynamicSymbolDefinition, object: &DynamicLayout, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, dynamic_symbol_writer: &mut SymbolTableWriter, ) -> Result { debug_assert_bail!( @@ -3783,10 +3784,10 @@ fn write_copy_relocation_dynamic_symbol_definition( Ok(()) } -fn write_regular_object_dynamic_symbol_definition( +fn write_regular_object_dynamic_symbol_definition<'data>( sym_def: &crate::layout::DynamicSymbolDefinition, object: &ObjectLayout, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, dynamic_symbol_writer: &mut SymbolTableWriter, ) -> Result { let sym_index = sym_def.symbol_id.to_input(object.symbol_id_range); @@ -3871,9 +3872,9 @@ fn write_regular_object_dynamic_symbol_definition( Ok(()) } -fn write_internal_symbols( +fn write_internal_symbols<'data>( internal_symbols: &InternalSymbols, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, symbol_writer: &mut SymbolTableWriter<'_, '_>, ) -> Result { for (local_index, def_info) in internal_symbols.symbol_definitions.iter().enumerate() { @@ -3971,7 +3972,7 @@ fn write_internal_symbols( Ok(()) } -fn write_eh_frame_hdr(table_writer: &mut TableWriter, layout: &Layout) -> Result { +fn write_eh_frame_hdr<'data>(table_writer: &mut TableWriter, layout: &Layout<'data, ElfLayout<'data>>) -> Result { let header = table_writer.take_eh_frame_hdr(); header.version = 1; @@ -3985,7 +3986,7 @@ fn write_eh_frame_hdr(table_writer: &mut TableWriter, layout: &Layout) -> Result Ok(()) } -fn eh_frame_hdr_entry_count(layout: &Layout) -> Result { +fn eh_frame_hdr_entry_count<'data>(layout: &Layout<'data, ElfLayout<'data>>) -> Result { let hdr_sec = layout.section_layouts.get(output_section_id::EH_FRAME_HDR); u32::try_from( (hdr_sec.mem_size - size_of::() as u64) @@ -3996,7 +3997,7 @@ fn eh_frame_hdr_entry_count(layout: &Layout) -> Result { /// Returns the address of .eh_frame relative to the location in .eh_frame_hdr where the frame /// pointer is stored. -fn eh_frame_ptr(layout: &Layout) -> Result { +fn eh_frame_ptr<'data>(layout: &Layout<'data, ElfLayout<'data>>) -> Result { let eh_frame_address = layout.mem_address_of_built_in(output_section_id::EH_FRAME); let eh_frame_hdr_address = layout.mem_address_of_built_in(output_section_id::EH_FRAME_HDR); i32::try_from( @@ -4362,7 +4363,7 @@ impl<'out> DynamicEntriesWriter<'out> { } } -fn write_section_headers(out: &mut [u8], layout: &Layout) -> Result { +fn write_section_headers<'data>(out: &mut [u8], layout: &Layout<'data, ElfLayout<'data>>) -> Result { let entries: &mut [SectionHeader] = slice_from_all_bytes_mut(out); let output_sections = &layout.output_sections; let mut entries = entries.iter_mut(); @@ -4456,7 +4457,7 @@ fn write_section_headers(out: &mut [u8], layout: &Layout) -> Result { } /// Computes the value of the info field for all the section headers. -fn compute_info_values(layout: &Layout) -> OutputSectionMap { +fn compute_info_values<'data>(layout: &Layout<'data, ElfLayout<'data>>) -> OutputSectionMap { let mut infos = layout.output_sections.new_section_map(); // .rela.plt contains relocations for .got, so should link to it. @@ -4522,13 +4523,13 @@ impl<'out> ProgramHeaderWriter<'out> { } } -fn write_internal_symbols_plt_got_entries< +fn write_internal_symbols_plt_got_entries< 'data, - P: Platform<'data, File = crate::elf::File<'data>>, + P: ElfPlatform<'data>, >( internal_symbols: &InternalSymbols, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { for i in 0..internal_symbols.symbol_definitions.len() { let symbol_id = internal_symbols.start_symbol_id.add_usize(i); @@ -4550,10 +4551,10 @@ fn write_internal_symbols_plt_got_entries< Ok(()) } -fn write_dynamic_file<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_dynamic_file<'data, P: ElfPlatform<'data>>( object: &DynamicLayout, table_writer: &mut TableWriter, - layout: &Layout<'data>, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { verbose_timing_phase!("Write dynamic"); @@ -4707,10 +4708,10 @@ fn write_so_name(object: &DynamicLayout, table_writer: &mut TableWriter) -> Resu Ok(()) } -fn write_copy_relocations<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_copy_relocations<'data, P: ElfPlatform<'data>>( object: &DynamicLayout, table_writer: &mut TableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { for &symbol_id in &object.copy_relocation_symbols { write_copy_relocation_for_symbol::

(symbol_id, table_writer, layout).with_context( @@ -4726,10 +4727,10 @@ fn write_copy_relocations<'data, P: Platform<'data, File = crate::elf::File<'dat Ok(()) } -fn write_copy_relocation_for_symbol<'data, P: Platform<'data, File = crate::elf::File<'data>>>( +fn write_copy_relocation_for_symbol<'data, P: ElfPlatform<'data>>( symbol_id: SymbolId, table_writer: &mut TableWriter, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> Result { let res = layout .local_symbol_resolution(symbol_id) diff --git a/libwild/src/elf_x86_64.rs b/libwild/src/elf_x86_64.rs index d62ad5b70..ef816a623 100644 --- a/libwild/src/elf_x86_64.rs +++ b/libwild/src/elf_x86_64.rs @@ -1,528 +1,562 @@ -//! Contains x86_64-specific code to perform various relocation relaxation optimisations. These are -//! supposed to be optional for the linker to do, but it turns out that libc in some cases won't -//! work unless they're performed. e.g. it uses GOT relocations in _start, which cannot work in a -//! static-PIE binary because dynamic relocations haven't yet been applied to the GOT yet. - -use crate::OutputKind; -use crate::elf::PLT_ENTRY_SIZE; -use crate::platform::PropertyClass; -use crate::error; -use crate::error::Result; -use crate::value_flags::ValueFlags; -use linker_utils::elf::DynamicRelocationKind; -use linker_utils::elf::RelocationKindInfo; -use linker_utils::elf::SectionFlags; -use linker_utils::elf::shf; -use linker_utils::elf::x86_64_rel_type_to_string; -use linker_utils::relaxation::RelocationModifier; -use linker_utils::x86_64::RelaxationKind; -use linker_utils::x86_64::relocation_from_raw; -use object::elf::GNU_PROPERTY_UINT32_AND_HI; -use object::elf::GNU_PROPERTY_UINT32_AND_LO; -use object::elf::GNU_PROPERTY_UINT32_OR_HI; -use object::elf::GNU_PROPERTY_UINT32_OR_LO; -use object::elf::GNU_PROPERTY_X86_UINT32_AND_HI; -use object::elf::GNU_PROPERTY_X86_UINT32_AND_LO; -use object::elf::GNU_PROPERTY_X86_UINT32_OR_AND_HI; -use object::elf::GNU_PROPERTY_X86_UINT32_OR_AND_LO; -use object::elf::GNU_PROPERTY_X86_UINT32_OR_HI; -use object::elf::GNU_PROPERTY_X86_UINT32_OR_LO; - -pub(crate) struct ElfX86_64; - -const PLT_ENTRY_TEMPLATE: &[u8] = &[ - 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 - 0xf2, 0xff, 0x25, 0x0, 0x0, 0x0, 0x0, // bnd jmp *{relative GOT address}(%rip) - 0x0f, 0x1f, 0x44, 0x0, 0x0, // nopl 0x0(%rax,%rax,1) -]; - -const _ASSERTS: () = { - assert!(PLT_ENTRY_TEMPLATE.len() as u64 == PLT_ENTRY_SIZE); -}; - -macro_rules! rel_info_from_type { - ($r_type:expr) => { - const { relocation_from_raw($r_type).unwrap() } - }; -} - -impl<'data> crate::platform::Platform<'data> for ElfX86_64 { - type Relaxation = Relaxation; - type File = crate::elf::File<'data>; - - fn elf_header_arch_magic() -> u16 { - object::elf::EM_X86_64 - } - - #[inline(always)] - fn relocation_from_raw(r_type: u32) -> Result { - linker_utils::x86_64::relocation_from_raw(r_type).ok_or_else(|| { - error!( - "Unsupported relocation type {}", - Self::rel_type_to_string(r_type) - ) - }) - } - - fn get_dynamic_relocation_type(relocation: DynamicRelocationKind) -> u32 { - relocation.x86_64_r_type() - } - - fn write_plt_entry( - plt_entry: &mut [u8], - got_address: u64, - plt_address: u64, - ) -> crate::error::Result { - plt_entry.copy_from_slice(PLT_ENTRY_TEMPLATE); - let offset: i32 = ((got_address.wrapping_sub(plt_address + 0xb)) as i64) - .try_into() - .map_err(|_| error!("PLT is more than 2GiB away from GOT"))?; - plt_entry[7..11].copy_from_slice(&offset.to_le_bytes()); - Ok(()) - } - - fn rel_type_to_string(r_type: u32) -> std::borrow::Cow<'static, str> { - x86_64_rel_type_to_string(r_type) - } - - fn local_symbols_in_debug_info() -> bool { - false - } - - fn tp_offset_start(layout: &crate::layout::Layout<'data>) -> u64 { - layout.tls_end_address() - } - - fn get_property_class(property_type: u32) -> Option { - match property_type { - GNU_PROPERTY_X86_UINT32_AND_LO..=GNU_PROPERTY_X86_UINT32_AND_HI => { - Some(PropertyClass::And) - } - GNU_PROPERTY_X86_UINT32_OR_LO..=GNU_PROPERTY_X86_UINT32_OR_HI => { - Some(PropertyClass::Or) - } - GNU_PROPERTY_X86_UINT32_OR_AND_LO..=GNU_PROPERTY_X86_UINT32_OR_AND_HI => { - Some(PropertyClass::AndOr) - } - GNU_PROPERTY_UINT32_AND_LO..=GNU_PROPERTY_UINT32_AND_HI => Some(PropertyClass::And), - GNU_PROPERTY_UINT32_OR_LO..=GNU_PROPERTY_UINT32_OR_HI => Some(PropertyClass::Or), - _ => None, - } - } - - fn merge_eflags(_eflags: impl Iterator) -> Result { - Ok(0) - } - - fn high_part_relocations() -> &'static [u32] { - &[] - } - - #[inline(always)] - fn new_relaxation( - relocation_kind: u32, - section_bytes: &[u8], - offset_in_section: u64, - flags: ValueFlags, - output_kind: OutputKind, - section_flags: SectionFlags, - _non_zero_address: bool, - _relax_deltas: Option<&linker_utils::relaxation::SectionRelaxDeltas>, - ) -> Option { - let is_known_address = flags.is_address(); - let is_absolute = flags.is_absolute() && !flags.is_dynamic(); - let non_relocatable = !output_kind.is_relocatable(); - let is_absolute_address = is_known_address && non_relocatable; - let interposable = flags.is_interposable(); - - // IFuncs cannot be referenced directly. They always need to go via the GOT. So if we've got - // say a PLT32 relocation, we don't want to relax it even if we're in a static executable. - // Furthermore, if we encounter a relocation like PC32 to an ifunc, then we need to change - // it so that it goes via the GOT. This is kind of the opposite of relaxation. - if flags.is_ifunc() { - return match relocation_kind { - object::elf::R_X86_64_PC32 => { - return Some(Relaxation { - kind: RelaxationKind::NoOp, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PLT32), - mandatory: true, - }); - } - _ => None, - }; - } - - // All relaxations below only apply to executable code, so we shouldn't attempt them if a - // relocation is in a non-executable section. - if !section_flags.contains(shf::EXECINSTR) { - return None; - } - - let offset = offset_in_section as usize; - - match relocation_kind { - object::elf::R_X86_64_REX_GOTPCRELX => { - if offset < 3 { - return None; - } - let b1 = section_bytes[offset - 2]; - let rex = section_bytes[offset - 3]; - - // REX prefixed instruction with W=1, R=0/1, X=0, B=0 - if rex != 0x48 && rex != 0x4c { - return None; - } - - if is_absolute || is_absolute_address { - match b1 { - // mov *x(%rip), reg - 0x8b => { - return Some(Relaxation { - kind: RelaxationKind::RexMovIndirectToAbsolute, - rel_info: rel_info_from_type!(object::elf::R_X86_64_32), - mandatory: output_kind.is_static_executable(), - }); - } - // sub *x(%rip), reg - 0x2b => { - return Some(Relaxation { - kind: RelaxationKind::RexSubIndirectToAbsolute, - rel_info: rel_info_from_type!(object::elf::R_X86_64_32), - mandatory: output_kind.is_static_executable(), - }); - } - // cmp *x(%rip), reg - 0x3b => { - return Some(Relaxation { - kind: RelaxationKind::RexCmpIndirectToAbsolute, - rel_info: rel_info_from_type!(object::elf::R_X86_64_32), - mandatory: output_kind.is_static_executable(), - }); - } - _ => return None, - } - } else if !interposable { - match b1 { - // mov *x(%rip), reg - 0x8b => { - return Some(Relaxation { - kind: RelaxationKind::MovIndirectToLea, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: output_kind.is_static_executable(), - }); - } - _ => return None, - } - } - } - object::elf::R_X86_64_GOTPCRELX => { - match section_bytes.get(offset - 2)? { - // mov *x(%rip), reg - 0x8b => { - if is_absolute || is_absolute_address { - return Some(Relaxation { - kind: RelaxationKind::MovIndirectToAbsolute, - rel_info: rel_info_from_type!(object::elf::R_X86_64_32), - mandatory: output_kind.is_static_executable(), - }); - } else if !interposable { - return Some(Relaxation { - kind: RelaxationKind::MovIndirectToLea, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: output_kind.is_static_executable(), - }); - } - } - _ => {} - } - if !interposable { - match section_bytes.get(offset - 2..offset)? { - // call *x(%rip) - [0xff, 0x15] => { - return Some(Relaxation { - kind: RelaxationKind::CallIndirectToRelative, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: output_kind.is_static_executable(), - }); - } - // jmp *x(%rip) - [0xff, 0x25] => { - return Some(Relaxation { - kind: RelaxationKind::JmpIndirectToRelative, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: output_kind.is_static_executable(), - }); - } - _ => return None, - } - } - return None; - } - object::elf::R_X86_64_GOTPCREL if !interposable && offset >= 2 => { - match section_bytes.get(offset - 2)? { - // mov *x(%rip), reg - 0x8b => { - return Some(Relaxation { - kind: RelaxationKind::MovIndirectToLea, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: false, - }); - } - _ => {} - } - return None; - } - object::elf::R_X86_64_GOTTPOFF if output_kind.is_executable() && !interposable => { - match section_bytes.get(offset - 3..offset - 1)? { - // mov *x(%rip), reg - [0x48 | 0x4c, 0x8b] => { - return Some(Relaxation { - kind: RelaxationKind::RexMovIndirectToAbsolute, - rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), - mandatory: false, - }); - } - _ => {} - } - } - object::elf::R_X86_64_PLT32 if !interposable => { - return Some(Relaxation { - kind: RelaxationKind::NoOp, - rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), - mandatory: output_kind.is_static_executable(), - }); - } - object::elf::R_X86_64_PLTOFF64 if !interposable => { - return Some(Relaxation { - kind: RelaxationKind::NoOp, - rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTOFF64), - mandatory: output_kind.is_static_executable(), - }); - } - object::elf::R_X86_64_TLSGD if !interposable && output_kind.is_executable() => { - let kind = match TlsGdForm::identify(section_bytes, offset)? { - TlsGdForm::Regular => RelaxationKind::TlsGdToLocalExec, - TlsGdForm::Large => RelaxationKind::TlsGdToLocalExecLarge, - }; - return Some(Relaxation { - kind, - rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), - mandatory: output_kind.is_static_executable(), - }); - } - object::elf::R_X86_64_TLSGD if output_kind.is_executable() => { - let kind = match TlsGdForm::identify(section_bytes, offset)? { - TlsGdForm::Regular => RelaxationKind::TlsGdToInitialExec, - TlsGdForm::Large => { - // TODO - return None; - } - }; - return Some(Relaxation { - kind, - rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTTPOFF), - mandatory: false, - }); - } - object::elf::R_X86_64_TLSLD if output_kind.is_executable() => { - // lea 0x0(%rip),%rdi - if section_bytes.get(offset - 3..offset)? == [0x48, 0x8d, 0x3d] { - match section_bytes.get(offset + 4..offset + 6) { - // PC-relative direct call - Some(&[0xe8, _]) => { - return Some(Relaxation { - kind: RelaxationKind::TlsLdToLocalExec, - rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), - mandatory: false, - }); - } - // TODO: Make a test for this. Also, the description of TlsLdToLocalExec64 - // possibly doesn't match what we're actually checking here. - Some(&[0x48, 0xb8]) => { - return Some(Relaxation { - kind: RelaxationKind::TlsLdToLocalExec64, - rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), - mandatory: false, - }); - } - // PC-relative indirect call - Some(&[0xff, 0x15]) => { - return Some(Relaxation { - kind: RelaxationKind::TlsLdToLocalExecNoPlt, - rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), - mandatory: false, - }); - } - _ => {} - } - } - } - object::elf::R_X86_64_GOTPC32_TLSDESC - if !interposable && output_kind.is_executable() => - { - // We require that the instruction that this relocation applies to is a LEA - // instruction. - let bytes = section_bytes.get(offset - 3..offset - 1); - if bytes == Some(&[0x48, 0x8d]) || bytes == Some(&[0x4c, 0x8d]) { - return Some(Relaxation { - kind: RelaxationKind::TlsDescToLocalExec, - rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), - mandatory: output_kind.is_static_executable(), - }); - } - } - // Note, the conditions on this relaxation (is_executable) must match those on - // TLSDESC_CALL below. - object::elf::R_X86_64_GOTPC32_TLSDESC if output_kind.is_executable() => { - // We require that the instruction that this relocation applies to is a LEA - // instruction. - let bytes = section_bytes.get(offset - 3..offset - 1); - if bytes == Some(&[0x48, 0x8d]) || bytes == Some(&[0x4c, 0x8d]) { - return Some(Relaxation { - kind: RelaxationKind::TlsDescToInitialExec, - rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTTPOFF), - mandatory: output_kind.is_static_executable(), - }); - } - } - // Note, the conditions on this relaxation (is_executable) must match those on - // GOTPC32_TLSDESC above. - object::elf::R_X86_64_TLSDESC_CALL if output_kind.is_executable() => { - return Some(Relaxation { - kind: RelaxationKind::SkipTlsDescCall, - rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), - mandatory: output_kind.is_static_executable(), - }); - } - _ => return None, - }; - None - } - - fn get_source_info( - object: &Self::File, - relocations: &>::RelocationSections, - section: &>::SectionHeader, - offset_in_section: u64, - ) -> Result { - crate::dwarf_address_info::get_source_info::( - object, - relocations, - section, - offset_in_section, - ) - } -} - -#[derive(Debug, Clone)] -pub(crate) struct Relaxation { - kind: RelaxationKind, - rel_info: RelocationKindInfo, - mandatory: bool, -} - -impl crate::platform::Relaxation for Relaxation { - fn apply(&self, section_bytes: &mut [u8], offset_in_section: &mut u64, addend: &mut i64) { - self.kind.apply(section_bytes, offset_in_section, addend); - } - - fn rel_info(&self) -> RelocationKindInfo { - self.rel_info - } - - fn debug_kind(&self) -> impl std::fmt::Debug { - &self.kind - } - - fn next_modifier(&self) -> RelocationModifier { - self.kind.next_modifier() - } - - fn is_mandatory(&self) -> bool { - self.mandatory - } -} - -enum TlsGdForm { - Regular, - Large, -} - -impl TlsGdForm { - fn identify(bytes: &[u8], offset: usize) -> Option { - // data16 lea 0x0(%rip),%rdi - // data16 data16 rex.W call {relative function offset} - if bytes.get(offset - 4..offset) == Some(&[0x66, 0x48, 0x8d, 0x3d]) - && bytes.get(offset + 4..offset + 8) == Some(&[0x66, 0x66, 0x48, 0xe8]) - { - return Some(Self::Regular); - } - - // lea 0x0(%rip),%rdi - // movabs $X,%rax - // TODO: This branch is not currently exercised by our tests. Add a test and document the - // third instruction. - if bytes.get(offset - 3..offset) == Some(&[0x48, 0x8d, 0x3d]) - && bytes.get(offset + 4..offset + 6) == Some(&[0x48, 0xb8]) - && bytes.get(offset + 14..offset + 19) == Some(&[0x48, 0x01, 0xd8, 0xff, 0xd0]) - { - return Some(Self::Large); - } - - None - } -} - -#[test] -fn test_relaxation() { - use crate::args::RelocationModel; - use crate::platform::Platform as _; - use crate::platform::Relaxation as _; - - #[track_caller] - fn check(relocation_kind: u32, bytes_in: &[u8], address: &[u8], absolute: &[u8]) { - let mut out = bytes_in.to_owned(); - let mut offset = bytes_in.len() as u64; - if let Some(r) = ElfX86_64::new_relaxation( - relocation_kind, - bytes_in, - offset, - ValueFlags::empty(), - OutputKind::StaticExecutable(RelocationModel::Relocatable), - shf::EXECINSTR, - true, - None, - ) { - r.apply(&mut out, &mut offset, &mut 0); - - assert_eq!( - out, address, - "resolved: Expected {address:x?}, got {out:x?}" - ); - } - if let Some(r) = ElfX86_64::new_relaxation( - relocation_kind, - bytes_in, - offset, - ValueFlags::ABSOLUTE, - OutputKind::StaticExecutable(RelocationModel::Relocatable), - shf::EXECINSTR, - true, - None, - ) { - out.copy_from_slice(bytes_in); - r.apply(&mut out, &mut offset, &mut 0); - assert_eq!( - out, absolute, - "unresolved: Expected {absolute:x?}, got {out:x?}" - ); - } - } - - check( - object::elf::R_X86_64_REX_GOTPCRELX, - &[0x48, 0x8b, 0xae], - &[0x48, 0x8d, 0xae], - &[0x48, 0xc7, 0xc5], - ); -} +//! Contains x86_64-specific code to perform various relocation relaxation optimisations. These are +//! supposed to be optional for the linker to do, but it turns out that libc in some cases won't +//! work unless they're performed. e.g. it uses GOT relocations in _start, which cannot work in a +//! static-PIE binary because dynamic relocations haven't yet been applied to the GOT yet. + +use crate::OutputKind; +use crate::elf::PLT_ENTRY_SIZE; +use crate::platform::PropertyClass; +use crate::error; +use crate::error::Result; +use crate::value_flags::ValueFlags; +use linker_utils::elf::DynamicRelocationKind; +use linker_utils::elf::RelocationKindInfo; +use linker_utils::elf::SectionFlags; +use linker_utils::elf::shf; +use linker_utils::elf::x86_64_rel_type_to_string; +use linker_utils::relaxation::RelocationModifier; +use linker_utils::x86_64::RelaxationKind; +use linker_utils::x86_64::relocation_from_raw; +use object::elf::GNU_PROPERTY_UINT32_AND_HI; +use object::elf::GNU_PROPERTY_UINT32_AND_LO; +use object::elf::GNU_PROPERTY_UINT32_OR_HI; +use object::elf::GNU_PROPERTY_UINT32_OR_LO; +use object::elf::GNU_PROPERTY_X86_UINT32_AND_HI; +use object::elf::GNU_PROPERTY_X86_UINT32_AND_LO; +use object::elf::GNU_PROPERTY_X86_UINT32_OR_AND_HI; +use object::elf::GNU_PROPERTY_X86_UINT32_OR_AND_LO; +use object::elf::GNU_PROPERTY_X86_UINT32_OR_HI; +use object::elf::GNU_PROPERTY_X86_UINT32_OR_LO; + +pub(crate) struct ElfX86_64; + +const PLT_ENTRY_TEMPLATE: &[u8] = &[ + 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 + 0xf2, 0xff, 0x25, 0x0, 0x0, 0x0, 0x0, // bnd jmp *{relative GOT address}(%rip) + 0x0f, 0x1f, 0x44, 0x0, 0x0, // nopl 0x0(%rax,%rax,1) +]; + +const _ASSERTS: () = { + assert!(PLT_ENTRY_TEMPLATE.len() as u64 == PLT_ENTRY_SIZE); +}; + +macro_rules! rel_info_from_type { + ($r_type:expr) => { + const { relocation_from_raw($r_type).unwrap() } + }; +} + +impl<'data> crate::platform::Platform<'data> for ElfX86_64 { + type File = crate::elf::File<'data>; + + fn create_plugin( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result>> { + crate::linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) + } + + fn load_auxiliary( + linker: &'data crate::Linker, + args: &'data crate::Args, + ) -> crate::error::Result> { + crate::input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) + } + + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data crate::Args, + plugin: &mut Option>, + symbol_db: crate::symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, crate::elf::File<'data>>, + output_sections: crate::output_section_id::OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> crate::error::Result>> { + ::finish_link( + file_loader, args, plugin, symbol_db, per_symbol_flags, + resolver, output_sections, layout_rules_builder, output_kind, + ) + } +} + +impl<'data> crate::platform::ElfPlatform<'data> for ElfX86_64 { + type Relaxation = Relaxation; + + fn elf_header_arch_magic() -> u16 { + object::elf::EM_X86_64 + } + + #[inline(always)] + fn relocation_from_raw(r_type: u32) -> Result { + linker_utils::x86_64::relocation_from_raw(r_type).ok_or_else(|| { + error!( + "Unsupported relocation type {}", + Self::rel_type_to_string(r_type) + ) + }) + } + + fn get_dynamic_relocation_type(relocation: DynamicRelocationKind) -> u32 { + relocation.x86_64_r_type() + } + + fn write_plt_entry( + plt_entry: &mut [u8], + got_address: u64, + plt_address: u64, + ) -> crate::error::Result { + plt_entry.copy_from_slice(PLT_ENTRY_TEMPLATE); + let offset: i32 = ((got_address.wrapping_sub(plt_address + 0xb)) as i64) + .try_into() + .map_err(|_| error!("PLT is more than 2GiB away from GOT"))?; + plt_entry[7..11].copy_from_slice(&offset.to_le_bytes()); + Ok(()) + } + + fn rel_type_to_string(r_type: u32) -> std::borrow::Cow<'static, str> { + x86_64_rel_type_to_string(r_type) + } + + fn local_symbols_in_debug_info() -> bool { + false + } + + fn tp_offset_start(layout: &crate::layout::Layout<'data, crate::elf_layout::ElfLayout<'data>>) -> u64 { + layout.tls_end_address() + } + + fn get_property_class(property_type: u32) -> Option { + match property_type { + GNU_PROPERTY_X86_UINT32_AND_LO..=GNU_PROPERTY_X86_UINT32_AND_HI => { + Some(PropertyClass::And) + } + GNU_PROPERTY_X86_UINT32_OR_LO..=GNU_PROPERTY_X86_UINT32_OR_HI => { + Some(PropertyClass::Or) + } + GNU_PROPERTY_X86_UINT32_OR_AND_LO..=GNU_PROPERTY_X86_UINT32_OR_AND_HI => { + Some(PropertyClass::AndOr) + } + GNU_PROPERTY_UINT32_AND_LO..=GNU_PROPERTY_UINT32_AND_HI => Some(PropertyClass::And), + GNU_PROPERTY_UINT32_OR_LO..=GNU_PROPERTY_UINT32_OR_HI => Some(PropertyClass::Or), + _ => None, + } + } + + fn merge_eflags(_eflags: impl Iterator) -> Result { + Ok(0) + } + + fn high_part_relocations() -> &'static [u32] { + &[] + } + + #[inline(always)] + fn new_relaxation( + relocation_kind: u32, + section_bytes: &[u8], + offset_in_section: u64, + flags: ValueFlags, + output_kind: OutputKind, + section_flags: SectionFlags, + _non_zero_address: bool, + _relax_deltas: Option<&linker_utils::relaxation::SectionRelaxDeltas>, + ) -> Option { + let is_known_address = flags.is_address(); + let is_absolute = flags.is_absolute() && !flags.is_dynamic(); + let non_relocatable = !output_kind.is_relocatable(); + let is_absolute_address = is_known_address && non_relocatable; + let interposable = flags.is_interposable(); + + // IFuncs cannot be referenced directly. They always need to go via the GOT. So if we've got + // say a PLT32 relocation, we don't want to relax it even if we're in a static executable. + // Furthermore, if we encounter a relocation like PC32 to an ifunc, then we need to change + // it so that it goes via the GOT. This is kind of the opposite of relaxation. + if flags.is_ifunc() { + return match relocation_kind { + object::elf::R_X86_64_PC32 => { + return Some(Relaxation { + kind: RelaxationKind::NoOp, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PLT32), + mandatory: true, + }); + } + _ => None, + }; + } + + // All relaxations below only apply to executable code, so we shouldn't attempt them if a + // relocation is in a non-executable section. + if !section_flags.contains(shf::EXECINSTR) { + return None; + } + + let offset = offset_in_section as usize; + + match relocation_kind { + object::elf::R_X86_64_REX_GOTPCRELX => { + if offset < 3 { + return None; + } + let b1 = section_bytes[offset - 2]; + let rex = section_bytes[offset - 3]; + + // REX prefixed instruction with W=1, R=0/1, X=0, B=0 + if rex != 0x48 && rex != 0x4c { + return None; + } + + if is_absolute || is_absolute_address { + match b1 { + // mov *x(%rip), reg + 0x8b => { + return Some(Relaxation { + kind: RelaxationKind::RexMovIndirectToAbsolute, + rel_info: rel_info_from_type!(object::elf::R_X86_64_32), + mandatory: output_kind.is_static_executable(), + }); + } + // sub *x(%rip), reg + 0x2b => { + return Some(Relaxation { + kind: RelaxationKind::RexSubIndirectToAbsolute, + rel_info: rel_info_from_type!(object::elf::R_X86_64_32), + mandatory: output_kind.is_static_executable(), + }); + } + // cmp *x(%rip), reg + 0x3b => { + return Some(Relaxation { + kind: RelaxationKind::RexCmpIndirectToAbsolute, + rel_info: rel_info_from_type!(object::elf::R_X86_64_32), + mandatory: output_kind.is_static_executable(), + }); + } + _ => return None, + } + } else if !interposable { + match b1 { + // mov *x(%rip), reg + 0x8b => { + return Some(Relaxation { + kind: RelaxationKind::MovIndirectToLea, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: output_kind.is_static_executable(), + }); + } + _ => return None, + } + } + } + object::elf::R_X86_64_GOTPCRELX => { + match section_bytes.get(offset - 2)? { + // mov *x(%rip), reg + 0x8b => { + if is_absolute || is_absolute_address { + return Some(Relaxation { + kind: RelaxationKind::MovIndirectToAbsolute, + rel_info: rel_info_from_type!(object::elf::R_X86_64_32), + mandatory: output_kind.is_static_executable(), + }); + } else if !interposable { + return Some(Relaxation { + kind: RelaxationKind::MovIndirectToLea, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: output_kind.is_static_executable(), + }); + } + } + _ => {} + } + if !interposable { + match section_bytes.get(offset - 2..offset)? { + // call *x(%rip) + [0xff, 0x15] => { + return Some(Relaxation { + kind: RelaxationKind::CallIndirectToRelative, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: output_kind.is_static_executable(), + }); + } + // jmp *x(%rip) + [0xff, 0x25] => { + return Some(Relaxation { + kind: RelaxationKind::JmpIndirectToRelative, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: output_kind.is_static_executable(), + }); + } + _ => return None, + } + } + return None; + } + object::elf::R_X86_64_GOTPCREL if !interposable && offset >= 2 => { + match section_bytes.get(offset - 2)? { + // mov *x(%rip), reg + 0x8b => { + return Some(Relaxation { + kind: RelaxationKind::MovIndirectToLea, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: false, + }); + } + _ => {} + } + return None; + } + object::elf::R_X86_64_GOTTPOFF if output_kind.is_executable() && !interposable => { + match section_bytes.get(offset - 3..offset - 1)? { + // mov *x(%rip), reg + [0x48 | 0x4c, 0x8b] => { + return Some(Relaxation { + kind: RelaxationKind::RexMovIndirectToAbsolute, + rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), + mandatory: false, + }); + } + _ => {} + } + } + object::elf::R_X86_64_PLT32 if !interposable => { + return Some(Relaxation { + kind: RelaxationKind::NoOp, + rel_info: rel_info_from_type!(object::elf::R_X86_64_PC32), + mandatory: output_kind.is_static_executable(), + }); + } + object::elf::R_X86_64_PLTOFF64 if !interposable => { + return Some(Relaxation { + kind: RelaxationKind::NoOp, + rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTOFF64), + mandatory: output_kind.is_static_executable(), + }); + } + object::elf::R_X86_64_TLSGD if !interposable && output_kind.is_executable() => { + let kind = match TlsGdForm::identify(section_bytes, offset)? { + TlsGdForm::Regular => RelaxationKind::TlsGdToLocalExec, + TlsGdForm::Large => RelaxationKind::TlsGdToLocalExecLarge, + }; + return Some(Relaxation { + kind, + rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), + mandatory: output_kind.is_static_executable(), + }); + } + object::elf::R_X86_64_TLSGD if output_kind.is_executable() => { + let kind = match TlsGdForm::identify(section_bytes, offset)? { + TlsGdForm::Regular => RelaxationKind::TlsGdToInitialExec, + TlsGdForm::Large => { + // TODO + return None; + } + }; + return Some(Relaxation { + kind, + rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTTPOFF), + mandatory: false, + }); + } + object::elf::R_X86_64_TLSLD if output_kind.is_executable() => { + // lea 0x0(%rip),%rdi + if section_bytes.get(offset - 3..offset)? == [0x48, 0x8d, 0x3d] { + match section_bytes.get(offset + 4..offset + 6) { + // PC-relative direct call + Some(&[0xe8, _]) => { + return Some(Relaxation { + kind: RelaxationKind::TlsLdToLocalExec, + rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), + mandatory: false, + }); + } + // TODO: Make a test for this. Also, the description of TlsLdToLocalExec64 + // possibly doesn't match what we're actually checking here. + Some(&[0x48, 0xb8]) => { + return Some(Relaxation { + kind: RelaxationKind::TlsLdToLocalExec64, + rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), + mandatory: false, + }); + } + // PC-relative indirect call + Some(&[0xff, 0x15]) => { + return Some(Relaxation { + kind: RelaxationKind::TlsLdToLocalExecNoPlt, + rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), + mandatory: false, + }); + } + _ => {} + } + } + } + object::elf::R_X86_64_GOTPC32_TLSDESC + if !interposable && output_kind.is_executable() => + { + // We require that the instruction that this relocation applies to is a LEA + // instruction. + let bytes = section_bytes.get(offset - 3..offset - 1); + if bytes == Some(&[0x48, 0x8d]) || bytes == Some(&[0x4c, 0x8d]) { + return Some(Relaxation { + kind: RelaxationKind::TlsDescToLocalExec, + rel_info: rel_info_from_type!(object::elf::R_X86_64_TPOFF32), + mandatory: output_kind.is_static_executable(), + }); + } + } + // Note, the conditions on this relaxation (is_executable) must match those on + // TLSDESC_CALL below. + object::elf::R_X86_64_GOTPC32_TLSDESC if output_kind.is_executable() => { + // We require that the instruction that this relocation applies to is a LEA + // instruction. + let bytes = section_bytes.get(offset - 3..offset - 1); + if bytes == Some(&[0x48, 0x8d]) || bytes == Some(&[0x4c, 0x8d]) { + return Some(Relaxation { + kind: RelaxationKind::TlsDescToInitialExec, + rel_info: rel_info_from_type!(object::elf::R_X86_64_GOTTPOFF), + mandatory: output_kind.is_static_executable(), + }); + } + } + // Note, the conditions on this relaxation (is_executable) must match those on + // GOTPC32_TLSDESC above. + object::elf::R_X86_64_TLSDESC_CALL if output_kind.is_executable() => { + return Some(Relaxation { + kind: RelaxationKind::SkipTlsDescCall, + rel_info: rel_info_from_type!(object::elf::R_X86_64_NONE), + mandatory: output_kind.is_static_executable(), + }); + } + _ => return None, + }; + None + } + + fn get_source_info( + object: &Self::File, + relocations: &>::RelocationSections, + section: &>::SectionHeader, + offset_in_section: u64, + ) -> Result { + crate::dwarf_address_info::get_source_info::( + object, + relocations, + section, + offset_in_section, + ) + } +} + +#[derive(Debug, Clone)] +pub(crate) struct Relaxation { + kind: RelaxationKind, + rel_info: RelocationKindInfo, + mandatory: bool, +} + +impl crate::platform::Relaxation for Relaxation { + fn apply(&self, section_bytes: &mut [u8], offset_in_section: &mut u64, addend: &mut i64) { + self.kind.apply(section_bytes, offset_in_section, addend); + } + + fn rel_info(&self) -> RelocationKindInfo { + self.rel_info + } + + fn debug_kind(&self) -> impl std::fmt::Debug { + &self.kind + } + + fn next_modifier(&self) -> RelocationModifier { + self.kind.next_modifier() + } + + fn is_mandatory(&self) -> bool { + self.mandatory + } +} + +enum TlsGdForm { + Regular, + Large, +} + +impl TlsGdForm { + fn identify(bytes: &[u8], offset: usize) -> Option { + // data16 lea 0x0(%rip),%rdi + // data16 data16 rex.W call {relative function offset} + if bytes.get(offset - 4..offset) == Some(&[0x66, 0x48, 0x8d, 0x3d]) + && bytes.get(offset + 4..offset + 8) == Some(&[0x66, 0x66, 0x48, 0xe8]) + { + return Some(Self::Regular); + } + + // lea 0x0(%rip),%rdi + // movabs $X,%rax + // TODO: This branch is not currently exercised by our tests. Add a test and document the + // third instruction. + if bytes.get(offset - 3..offset) == Some(&[0x48, 0x8d, 0x3d]) + && bytes.get(offset + 4..offset + 6) == Some(&[0x48, 0xb8]) + && bytes.get(offset + 14..offset + 19) == Some(&[0x48, 0x01, 0xd8, 0xff, 0xd0]) + { + return Some(Self::Large); + } + + None + } +} + +#[test] +fn test_relaxation() { + use crate::args::RelocationModel; + use crate::platform::ElfPlatform as _; + use crate::platform::Relaxation as _; + + #[track_caller] + fn check(relocation_kind: u32, bytes_in: &[u8], address: &[u8], absolute: &[u8]) { + let mut out = bytes_in.to_owned(); + let mut offset = bytes_in.len() as u64; + if let Some(r) = ElfX86_64::new_relaxation( + relocation_kind, + bytes_in, + offset, + ValueFlags::empty(), + OutputKind::StaticExecutable(RelocationModel::Relocatable), + shf::EXECINSTR, + true, + None, + ) { + r.apply(&mut out, &mut offset, &mut 0); + + assert_eq!( + out, address, + "resolved: Expected {address:x?}, got {out:x?}" + ); + } + if let Some(r) = ElfX86_64::new_relaxation( + relocation_kind, + bytes_in, + offset, + ValueFlags::ABSOLUTE, + OutputKind::StaticExecutable(RelocationModel::Relocatable), + shf::EXECINSTR, + true, + None, + ) { + out.copy_from_slice(bytes_in); + r.apply(&mut out, &mut offset, &mut 0); + assert_eq!( + out, absolute, + "unresolved: Expected {absolute:x?}, got {out:x?}" + ); + } + } + + check( + object::elf::R_X86_64_REX_GOTPCRELX, + &[0x48, 0x8b, 0xae], + &[0x48, 0x8d, 0xae], + &[0x48, 0xc7, 0xc5], + ); +} diff --git a/libwild/src/file_writer.rs b/libwild/src/file_writer.rs index b68e72462..f2c3154bc 100644 --- a/libwild/src/file_writer.rs +++ b/libwild/src/file_writer.rs @@ -2,11 +2,13 @@ use crate::OutputKind; use crate::args::Args; use crate::args::FileWriteMode; use crate::args::consts::WRITE_VERIFY_ALLOCATIONS_ENV; +use crate::elf_layout::ElfLayout; +use crate::elf_layout::GroupLayout; use crate::error; use crate::error::Context as _; use crate::error::Result; -use crate::layout::GroupLayout; use crate::layout::Layout; +use crate::layout::LayoutTarget; use crate::output_section_id::OutputSectionId; use crate::output_section_map::OutputSectionMap; use crate::output_section_part_map::OutputSectionPartMap; @@ -186,10 +188,10 @@ impl Output { } } - pub fn write<'data, 'layout>( + pub fn write<'data, 'layout, T: crate::layout::LayoutTarget<'data>>( &self, - layout: &'layout Layout<'data>, - write_fn: impl FnOnce(&mut SizedOutput, &'layout Layout<'data>) -> Result, + layout: &'layout Layout<'data, T>, + write_fn: impl FnOnce(&mut SizedOutput, &'layout Layout<'data, T>) -> Result, ) -> Result { timing_phase!("Write output file"); if layout.args().write_layout { @@ -345,7 +347,7 @@ pub(crate) fn verify_allocations_message() -> String { } pub(crate) fn split_output_by_group<'layout, 'data, 'out>( - layout: &'layout Layout<'data>, + layout: &'layout Layout<'data, ElfLayout<'data>>, writable_buckets: &'out mut OutputSectionPartMap<&mut [u8]>, ) -> Vec<( &'layout GroupLayout<'data>, @@ -359,8 +361,8 @@ pub(crate) fn split_output_by_group<'layout, 'data, 'out>( .collect() } -pub(crate) fn split_output_into_sections<'out>( - layout: &Layout, +pub(crate) fn split_output_into_sections<'data, 'out>( + layout: &Layout<'data, ElfLayout<'data>>, mut data: &'out mut [u8], ) -> OutputSectionMap<&'out mut [u8]> { let mut section_allocations = Vec::with_capacity(layout.section_layouts.len()); @@ -394,9 +396,9 @@ pub(crate) fn split_output_into_sections<'out>( } /// Splits the writable buffers for each segment further into separate buffers for each alignment. -pub(crate) fn split_buffers_by_alignment<'out>( +pub(crate) fn split_buffers_by_alignment<'data, 'out>( section_buffers: &'out mut OutputSectionMap<&mut [u8]>, - layout: &Layout, + layout: &Layout<'data, ElfLayout<'data>>, ) -> OutputSectionPartMap<&'out mut [u8]> { layout.section_part_layouts.output_order_map( &layout.output_order, @@ -419,13 +421,13 @@ pub(crate) fn split_buffers_by_alignment<'out>( ) } -fn write_layout(layout: &Layout) -> Result { +fn write_layout<'data>(layout: &Layout<'data, impl LayoutTarget<'data>>) -> Result { let layout_path = linker_layout::layout_path(&layout.args().output); write_layout_to(layout, &layout_path) .with_context(|| format!("Failed to write layout to `{}`", layout_path.display())) } -fn write_layout_to(layout: &Layout, path: &Path) -> Result { +fn write_layout_to<'data>(layout: &Layout<'data, impl LayoutTarget<'data>>, path: &Path) -> Result { let mut file = std::io::BufWriter::new(std::fs::File::create(path)?); layout.layout_data().write(&mut file)?; Ok(()) diff --git a/libwild/src/gc_stats.rs b/libwild/src/gc_stats.rs index 1e5deeccf..fe1e64b38 100644 --- a/libwild/src/gc_stats.rs +++ b/libwild/src/gc_stats.rs @@ -20,8 +20,8 @@ use crate::args::Args; use crate::args::linux::ElfArgs; use crate::error::Context as _; use crate::error::Result; -use crate::layout::FileLayout; -use crate::layout::GroupLayout; +use crate::elf_layout::FileLayout; +use crate::elf_layout::GroupLayout; use crate::output_section_id; use crate::platform::ObjectFile as _; use crate::resolution::SectionSlot; diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs index ee85ebf60..37a7c202e 100644 --- a/libwild/src/layout.rs +++ b/libwild/src/layout.rs @@ -1,682 +1,133 @@ -//! Traverses the graph of symbol references to figure out what sections from the input files are -//! referenced. Determines which sections need to be linked, sums their sizes decides what goes -//! where in the output file then allocates addresses for each symbol. +//! Format-agnostic layout types shared across all output formats (ELF, PE). +//! ELF-specific layout code lives in `elf_layout.rs`. -use self::elf::GNU_NOTE_NAME; -use self::elf::NoteHeader; -use self::elf::Symbol; -use crate::OutputKind; -use crate::alignment; use crate::alignment::Alignment; -use crate::args::Args; -use crate::args::linux::ElfArgs; -use crate::args::linux::BuildIdOption; -use crate::args::Strip; -use crate::bail; -use crate::debug_assert_bail; -use crate::diagnostics::SymbolInfoPrinter; -use crate::elf; -use crate::elf::ElfLayoutProperties; -use crate::elf::File; -use crate::elf::RawSymbolName; -use crate::elf::Rela; -use crate::elf::RelocationList; -use crate::elf::SectionAttributes; -use crate::elf::Versym; -use crate::elf_writer; -use crate::ensure; -use crate::error; -use crate::error::Context; -use crate::error::Error; -use crate::error::Result; -use crate::error::warning; -use crate::file_writer; -use crate::grouping::Group; -use crate::input_data::FileId; -use crate::input_data::InputRef; -use crate::input_data::PRELUDE_FILE_ID; -use crate::layout_rules::SectionKind; -use crate::output_section_id; -use crate::output_section_id::FILE_HEADER; -use crate::output_section_id::OrderEvent; -use crate::output_section_id::OutputOrder; +use crate::elf_layout::ElfLayout; use crate::output_section_id::OutputSectionId; -use crate::output_section_id::OutputSections; -use crate::output_section_map::OutputSectionMap; -use crate::output_section_part_map::OutputSectionPartMap; use crate::parsing::InternalSymDefInfo; -use crate::parsing::SymbolPlacement; -use crate::part_id; -use crate::part_id::NUM_SINGLE_PART_SECTIONS; use crate::part_id::PartId; -use crate::platform::DynamicTagValues as _; -use crate::platform::NonAddressableIndexes as _; -use crate::platform::ObjectFile; -use crate::platform::Platform; -use crate::platform::RawSymbolName as _; -use crate::platform::RelaxSymbolInfo; -use crate::platform::Relaxation as _; -use crate::platform::Relocation; -use crate::platform::RelocationSequence; -use crate::platform::SectionAttributes as _; -use crate::platform::SectionFlags as _; -use crate::platform::SectionHeader as _; -use crate::platform::Symbol as _; -use crate::program_segments::ProgramSegmentId; -use crate::program_segments::ProgramSegments; -use crate::resolution; -use crate::resolution::NotLoaded; -use crate::resolution::ResolvedGroup; -use crate::resolution::ResolvedLinkerScript; -use crate::resolution::ResolvedSyntheticSymbols; -use crate::resolution::SectionSlot; -use crate::resolution::UnloadedSection; -use crate::sharding::ShardKey; -use crate::string_merging::MergedStringStartAddresses; -use crate::string_merging::MergedStringsSection; -use crate::string_merging::get_merged_string_output_address; -use crate::symbol::UnversionedSymbolName; -use crate::symbol_db::SymbolDb; -use crate::symbol_db::SymbolDebug; use crate::symbol_db::SymbolId; -use crate::symbol_db::SymbolIdRange; -use crate::symbol_db::Visibility; -use crate::symbol_db::is_mapping_symbol_name; -use crate::timing_phase; -use crate::value_flags::AtomicPerSymbolFlags; -use crate::value_flags::FlagsForSymbol as _; -use crate::value_flags::PerSymbolFlags; use crate::value_flags::ValueFlags; -use crate::verbose_timing_phase; -use crossbeam_queue::ArrayQueue; -use crossbeam_queue::SegQueue; -use foldhash::HashSet; -use hashbrown::HashMap; -use itertools::Itertools; -use linker_utils::elf::RelocationKind; -use linker_utils::elf::SectionFlags; -use linker_utils::elf::pt; -use linker_utils::elf::secnames; -use linker_utils::elf::shf; -use linker_utils::elf::sht; -use linker_utils::elf::sht::NOTE; -use linker_utils::elf::sht::RISCV_ATTRIBUTES; -use linker_utils::relaxation::RelaxDeltaMap; -use linker_utils::relaxation::RelocationModifier; -use linker_utils::relaxation::SectionRelaxDeltas; -use linker_utils::relaxation::opt_input_to_output; -use object::LittleEndian; -use object::SectionIndex; -use object::elf::gnu_hash; -use object::read::elf::Crel; -use object::read::elf::Dyn as _; -use object::read::elf::RelocationSections; -use rayon::Scope; -use rayon::iter::IndexedParallelIterator; -use rayon::iter::IntoParallelIterator; -use rayon::iter::IntoParallelRefIterator; -use rayon::iter::IntoParallelRefMutIterator; -use rayon::iter::ParallelIterator; -use smallvec::SmallVec; -use std::ffi::CString; -use std::fmt::Display; -use std::mem::replace; -use std::mem::size_of; -use std::mem::swap; -use std::mem::take; +use std::marker::PhantomData; use std::num::NonZeroU32; use std::num::NonZeroU64; -use std::sync::Mutex; -use std::sync::atomic; -use std::sync::atomic::AtomicBool; -use std::sync::atomic::AtomicU64; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering::Relaxed; -pub fn compute<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - symbol_db: SymbolDb<'data, crate::elf::File<'data>>, - mut per_symbol_flags: PerSymbolFlags, - mut groups: Vec>>, - mut output_sections: OutputSections<'data>, - output: &mut file_writer::Output, -) -> Result> { - timing_phase!("Layout"); +/// Trait that all format-specific layout types must implement. +pub(crate) trait LayoutTarget<'data> { + type ArgsType: 'static; - let sonames = Sonames::new(&symbol_db.groups); + fn args(&self) -> &crate::args::Args; - let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); + fn layout_data(&self) -> linker_layout::Layout; - let symbol_info_printer = symbol_db.args.sym_info.as_ref().map(|sym_name| { - SymbolInfoPrinter::new(&symbol_db, sym_name, &atomic_per_symbol_flags, &groups) - }); - - let string_merge_inputs = - crate::string_merging::StringMergeInputs::new(&mut groups, &output_sections)?; - - let (merged_strings, gc_outputs) = rayon::join( - || { - crate::string_merging::merge_strings( - &string_merge_inputs, - &output_sections, - symbol_db.args, - ) - }, - || { - find_required_sections::

( - groups, - &symbol_db, - &atomic_per_symbol_flags, - &output_sections, - sonames, - ) - }, - ); - let merged_strings = merged_strings?; - let gc_outputs = gc_outputs?; - - let mut group_states = gc_outputs.group_states; - - let epilogue_file_id = FileId::new(group_states.len() as u32, 0); - - finalise_copy_relocations(&mut group_states, &symbol_db, &atomic_per_symbol_flags)?; - let mut dynamic_symbol_definitions = - merge_dynamic_symbol_definitions(&group_states, &symbol_db)?; - - group_states.push(GroupState { - files: vec![FileLayoutState::Epilogue(EpilogueLayoutState::new( - symbol_db.args, - symbol_db.output_kind, - &mut dynamic_symbol_definitions, - ))], - queue: LocalWorkQueue::new(epilogue_file_id.group()), - common: CommonGroupState::new(&output_sections), - num_symbols: 0, - }); - - let properties_and_attributes = crate::elf::File::create_layout_properties::

( - symbol_db.args, - objects_iter(&group_states).map(|obj| obj.object), - objects_iter(&group_states).map(|obj| &obj.format_specific_layout_state), - )?; - - let finalise_sizes_resources = FinaliseSizesResources { - dynamic_symbol_definitions: &dynamic_symbol_definitions, - symbol_db: &symbol_db, - merged_strings: &merged_strings, - format_specific: &properties_and_attributes, - }; - - finalise_all_sizes( - &mut group_states, - &output_sections, - &atomic_per_symbol_flags, - &finalise_sizes_resources, - )?; - - // Dropping `symbol_info_printer` will cause it to print. So we'll either print now, or, if we - // got an error, then we'll have printed at that point. - drop(symbol_info_printer); - - let non_addressable_counts = apply_non_addressable_indexes(&mut group_states, &symbol_db)?; - - propagate_section_attributes(&group_states, &mut output_sections); - - let (output_order, program_segments) = output_sections.output_order(); - - tracing::trace!( - "Output order:\n{}", - output_order.display(&output_sections, &program_segments) - ); - - let mut section_part_sizes = compute_total_section_part_sizes( - &mut group_states, - &mut output_sections, - &output_order, - &program_segments, - &mut per_symbol_flags, - gc_outputs.must_keep_sections, - &finalise_sizes_resources, - )?; - - let mut section_part_layouts = layout_section_parts( - §ion_part_sizes, - &output_sections, - &program_segments, - &output_order, - symbol_db.args, - ); - - if symbol_db.args.relax && P::supports_size_reduction_relaxations() { - perform_iterative_relaxation::

( - &mut group_states, - &mut section_part_sizes, - &mut section_part_layouts, - &output_sections, - &program_segments, - &output_order, - &symbol_db, - &per_symbol_flags, - ); - } - - let section_layouts = layout_sections(&output_sections, §ion_part_layouts); - let mut merged_section_layouts = section_layouts.clone(); - merge_secondary_parts(&output_sections, &mut merged_section_layouts); - - output.set_size(compute_total_file_size(§ion_layouts)); - - let Some(FileLayoutState::Prelude(internal)) = - &group_states.first().and_then(|g| g.files.first()) - else { - unreachable!(); - }; - let header_info = internal.header_info.as_ref().unwrap(); - let segment_layouts = compute_segment_layout( - §ion_layouts, - &output_sections, - &output_order, - &program_segments, - header_info, - symbol_db.args, - )?; - - let mem_offsets: OutputSectionPartMap = starting_memory_offsets(§ion_part_layouts); - let starting_mem_offsets_by_group = compute_start_offsets_by_group(&group_states, mem_offsets); - - let merged_string_start_addresses = MergedStringStartAddresses::compute( - &output_sections, - &starting_mem_offsets_by_group, - &merged_strings, - ); - - let mut symbol_resolutions = SymbolResolutions { - resolutions: Vec::with_capacity(symbol_db.num_symbols()), - }; - - let mut res_writer = sharded_vec_writer::VecWriter::new(&mut symbol_resolutions.resolutions); - - let mut per_group_res_writers = group_states - .iter() - .map(|group| res_writer.take_shard(group.num_symbols)) - .collect_vec(); - - let resources = FinaliseLayoutResources { - symbol_db: &symbol_db, - output_sections: &output_sections, - output_order: &output_order, - section_layouts: §ion_layouts, - merged_string_start_addresses: &merged_string_start_addresses, - merged_strings: &merged_strings, - per_symbol_flags: &per_symbol_flags, - dynamic_symbol_definitions: &dynamic_symbol_definitions, - segment_layouts: &segment_layouts, - program_segments: &program_segments, - format_specific: &properties_and_attributes, - }; - - let group_layouts = compute_symbols_and_layouts( - group_states, - starting_mem_offsets_by_group, - &mut per_group_res_writers, - &resources, - )?; - - for shard in per_group_res_writers { - res_writer - .try_return_shard(shard) - .context("Group resolutions not filled")?; - } - - update_dynamic_symbol_resolutions( - &resources, - &group_layouts, - &mut symbol_resolutions.resolutions, - ); - update_defsym_symbol_resolutions(&symbol_db, &mut symbol_resolutions.resolutions)?; - crate::gc_stats::maybe_write_gc_stats(&group_layouts, symbol_db.args)?; - - let relocation_statistics = OutputSectionMap::with_size(section_layouts.len()); - - Ok(Layout { - symbol_db, - symbol_resolutions, - segment_layouts, - section_part_layouts, - section_layouts, - merged_section_layouts, - group_layouts, - output_sections, - program_segments, - output_order, - non_addressable_counts, - merged_strings, - merged_string_start_addresses, - has_static_tls: gc_outputs.has_static_tls, - has_variant_pcs: gc_outputs.has_variant_pcs, - relocation_statistics, - per_symbol_flags, - dynamic_symbol_definitions, - properties_and_attributes, - }) + fn into_target_layout(self) -> TargetLayout<'data>; } -struct FinaliseSizesResources<'data, 'scope> { - dynamic_symbol_definitions: &'scope [DynamicSymbolDefinition<'data>], - symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, - merged_strings: &'scope OutputSectionMap>, - format_specific: &'scope as ObjectFile<'data>>::LayoutProperties, +/// Format-specific layout data, analogous to `TargetArgs`. +pub(crate) enum TargetLayout<'data> { + Elf(ElfLayout<'data>), + Pe(crate::pe_writer::PeLayout<'data>), } -/// Update resolutions for defsym symbols that reference other symbols. -fn update_defsym_symbol_resolutions<'data>( - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - resolutions: &mut [Option], -) -> Result { - verbose_timing_phase!("Update symdef resolutions"); - - for group in &symbol_db.groups { - let mut symbol_id = group.symbol_id_range().start(); +impl<'data> LayoutTarget<'data> for TargetLayout<'data> { + type ArgsType = crate::args::TargetArgs; - match group { - Group::Prelude(prelude) => { - for def_info in &prelude.symbol_definitions { - update_defsym_symbol_resolution(symbol_id, def_info, symbol_db, resolutions)?; - symbol_id = symbol_id.next(); - } - } - Group::LinkerScripts(scripts) => { - for script in scripts { - for def_info in &script.parsed.symbol_defs { - update_defsym_symbol_resolution( - symbol_id, - def_info, - symbol_db, - resolutions, - )?; - symbol_id = symbol_id.next(); - } - } - } - Group::Objects(_) | Group::SyntheticSymbols(_) => {} - #[cfg(feature = "plugins")] - Group::LtoInputs(_) => {} - } + fn args(&self) -> &crate::args::Args { + // TargetLayout is only used as the default type parameter for Layout. + // In practice, file_writer::write is always called with a concrete layout type. + unimplemented!("args() on TargetLayout enum is not supported; use a concrete layout type") } - Ok(()) -} - -fn update_defsym_symbol_resolution<'data>( - symbol_id: SymbolId, - def_info: &InternalSymDefInfo, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - resolutions: &mut [Option], -) -> Result { - let SymbolPlacement::DefsymSymbol(target_name, offset) = def_info.placement else { - return Ok(()); - }; - - if !symbol_db.is_canonical(symbol_id) { - return Ok(()); + fn layout_data(&self) -> linker_layout::Layout { + match self { + Self::Elf(elf) => elf.layout_data(), + Self::Pe(pe) => pe.layout_data(), + } } - let Some(target_symbol_id) = - symbol_db.get_unversioned(&UnversionedSymbolName::prehashed(target_name.as_bytes())) - else { - return Err(symbol_db.missing_defsym_target_error(def_info.name, target_name)); - }; - - let canonical_target_id = symbol_db.definition(target_symbol_id); - if let Some(target_value) = resolutions[canonical_target_id.as_usize()] - .as_ref() - .map(|r| r.raw_value) - && let Some(resolution) = &mut resolutions[symbol_id.as_usize()] - { - // Apply the offset from the defsym expression. - resolution.raw_value = (target_value as i64).wrapping_add(offset) as u64; + fn into_target_layout(self) -> TargetLayout<'data> { + self } - - Ok(()) } -/// Update resolutions for all dynamic symbols that our output file defines. -fn update_dynamic_symbol_resolutions( - resources: &FinaliseLayoutResources, - layouts: &[GroupLayout], - resolutions: &mut [Option], -) { - timing_phase!("Update dynamic symbol resolutions"); - - let Some(FileLayout::Epilogue(epilogue)) = layouts.last().and_then(|g| g.files.last()) else { - panic!("Epilogue should be the last file"); - }; - - for (index, sym) in resources.dynamic_symbol_definitions.iter().enumerate() { - let dynamic_symbol_index = NonZeroU32::try_from(epilogue.dynsym_start_index + index as u32) - .expect("Dynamic symbol definitions should start > 0"); - if let Some(res) = &mut resolutions[sym.symbol_id.as_usize()] { - res.dynamic_symbol_index = Some(dynamic_symbol_index); +// TargetLayout can't impl Debug because ElfLayout contains non-Debug types +impl std::fmt::Debug for TargetLayout<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Elf(_) => write!(f, "TargetLayout::Elf(..)"), + Self::Pe(_) => write!(f, "TargetLayout::Pe(..)"), } } } -/// Where we've decided that we need copy relocations, look for symbols with the same address as the -/// symbols with copy relocations. If the other symbol is non-weak, then we do the copy relocation -/// for that symbol instead. We also request dynamic symbol definitions for each copy relocation. -/// For that reason, this needs to be done before we merge dynamic symbol definitions. -fn finalise_copy_relocations<'data>( - group_states: &mut [GroupState<'data>], - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - symbol_flags: &AtomicPerSymbolFlags, -) -> Result { - timing_phase!("Finalise copy relocations"); - - group_states.par_iter_mut().try_for_each(|group| { - verbose_timing_phase!("Finalise copy relocations for group"); - for file in &mut group.files { - if let FileLayoutState::Dynamic(dynamic) = file { - dynamic.finalise_copy_relocations(&mut group.common, symbol_db, symbol_flags)?; - } - } - - Ok(()) - }) +/// Layout result — common fields shared across all output formats (ELF, PE), +/// generic over format-specific data `T` (analogous to `Args`). +/// +/// During layout computation, `T` is set to the concrete format type +/// (e.g. `ElfLayout` or `PeLayout`). Use `TargetLayout` for format-erased code. +/// +/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target`. +#[derive(Debug)] +pub(crate) struct Layout<'data, T: LayoutTarget<'data> = TargetLayout<'data>> { + /// Total output file size in bytes. + pub(crate) file_size: u64, + /// Virtual address of the entry point (absolute). + pub(crate) entry_address: u64, + /// Resolved address for each symbol, indexed by global symbol ID. + /// 0 means undefined / no address. + pub(crate) symbol_addresses: Vec, + /// Format-specific layout data. + pub(crate) target: T, + _phantom: PhantomData<&'data ()>, } -fn finalise_all_sizes<'data>( - group_states: &mut [GroupState<'data>], - output_sections: &OutputSections, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources<'data, '_>, -) -> Result { - timing_phase!("Finalise per-object sizes"); - - group_states.par_iter_mut().try_for_each(|state| { - verbose_timing_phase!("Finalise sizes for group"); - state.finalise_sizes(output_sections, per_symbol_flags, resources) - }) +impl<'data, T: LayoutTarget<'data>> std::ops::Deref for Layout<'data, T> { + type Target = T; + fn deref(&self) -> &T { + &self.target + } } -fn merge_dynamic_symbol_definitions<'data>( - group_states: &[GroupState<'data>], - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, -) -> Result>> { - timing_phase!("Merge dynamic symbol definitions"); - - let mut dynamic_symbol_definitions = Vec::new(); - for group in group_states { - dynamic_symbol_definitions.extend(group.common.dynamic_symbol_definitions.iter().copied()); +impl<'data, T: LayoutTarget<'data>> std::ops::DerefMut for Layout<'data, T> { + fn deref_mut(&mut self) -> &mut T { + &mut self.target } - - append_prelude_defsym_dynamic_symbols( - group_states, - symbol_db, - &mut dynamic_symbol_definitions, - )?; - - Ok(dynamic_symbol_definitions) } -fn append_prelude_defsym_dynamic_symbols<'data>( - group_states: &[GroupState<'data>], - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - dynamic_symbol_definitions: &mut Vec>, -) -> Result { - if symbol_db.output_kind.needs_dynsym() - && let Some(first_group) = group_states.first() - && let Some(FileLayoutState::Prelude(prelude)) = first_group.files.first() - { - let symbol_id_range = prelude.symbol_id_range; - for (index, def_info) in prelude - .internal_symbols - .symbol_definitions - .iter() - .enumerate() - { - if !matches!(def_info.placement, SymbolPlacement::DefsymSymbol(_, _)) { - continue; - } - - let symbol_id = symbol_id_range.offset_to_id(index); - if !symbol_db.is_canonical(symbol_id) - || dynamic_symbol_definitions - .iter() - .any(|def| def.symbol_id == symbol_id) - { - continue; - } - - let symbol_name = symbol_db.symbol_name(symbol_id)?; - let RawSymbolName { - name, - version_name, - is_default, - } = RawSymbolName::parse(symbol_name.bytes()); - - let mut version = object::elf::VER_NDX_GLOBAL; - if symbol_db.version_script.version_count() > 0 - && let Some(v) = symbol_db - .version_script - .version_for_symbol(&UnversionedSymbolName::prehashed(name), version_name)? - { - version = v; - if !is_default { - version |= object::elf::VERSYM_HIDDEN; - } - } - dynamic_symbol_definitions.push(DynamicSymbolDefinition::new(symbol_id, name, version)); +impl<'data, T: LayoutTarget<'data>> Layout<'data, T> { + pub(crate) fn new(file_size: u64, entry_address: u64, symbol_addresses: Vec, target: T) -> Self { + Layout { + file_size, + entry_address, + symbol_addresses, + target, + _phantom: PhantomData, } } - Ok(()) -} - -fn objects_iter<'groups, 'data>( - group_states: &'groups [GroupState<'data>], -) -> impl Iterator> + Clone { - group_states.iter().flat_map(|group| { - group.files.iter().filter_map(|file| match file { - FileLayoutState::Object(object) => Some(object), - _ => None, - }) - }) -} - -fn compute_total_file_size(section_layouts: &OutputSectionMap) -> u64 { - let mut file_size = 0; - section_layouts.for_each(|_, s| file_size = file_size.max(s.file_offset + s.file_size)); - file_size as u64 -} - -/// Information about what goes where. Also includes relocation data, since that's computed at the -/// same time. -#[derive(Debug)] -pub struct Layout<'data> { - pub(crate) symbol_db: SymbolDb<'data, crate::elf::File<'data>>, - pub(crate) symbol_resolutions: SymbolResolutions, - pub(crate) section_part_layouts: OutputSectionPartMap, - - pub(crate) section_layouts: OutputSectionMap, - - /// This is like `section_layouts`, but where secondary sections are merged into their primary - /// section. Values for secondary sections are reset to 0 and should not be used. - pub(crate) merged_section_layouts: OutputSectionMap, - - pub(crate) group_layouts: Vec>, - pub(crate) segment_layouts: SegmentLayouts, - pub(crate) output_sections: OutputSections<'data>, - pub(crate) program_segments: ProgramSegments, - pub(crate) output_order: OutputOrder, - pub(crate) non_addressable_counts: - as ObjectFile<'data>>::NonAddressableCounts, - pub(crate) merged_strings: OutputSectionMap>, - pub(crate) merged_string_start_addresses: MergedStringStartAddresses, - pub(crate) relocation_statistics: OutputSectionMap, - pub(crate) has_static_tls: bool, - pub(crate) has_variant_pcs: bool, - pub(crate) per_symbol_flags: PerSymbolFlags, - pub(crate) dynamic_symbol_definitions: Vec>, - pub(crate) properties_and_attributes: as ObjectFile<'data>>::LayoutProperties, -} - -#[derive(Debug)] -pub(crate) struct SegmentLayouts { - /// The layout of each of our segments. Segments containing no active output sections will have - /// been filtered, so don't try to index this by our internal segment IDs. - pub(crate) segments: Vec, - pub(crate) tls_layout: Option, -} - -#[derive(Debug, Default, Clone)] -pub(crate) struct SegmentLayout { - pub(crate) id: ProgramSegmentId, - pub(crate) sizes: OutputRecordLayout, -} - -#[derive(Debug)] -pub(crate) struct SymbolResolutions { - resolutions: Vec>, -} - -pub(crate) enum FileLayout<'data> { - Prelude(PreludeLayout<'data>), - Object(ObjectLayout<'data>), - Dynamic(DynamicLayout<'data>), - SyntheticSymbols(SyntheticSymbolsLayout<'data>), - Epilogue(EpilogueLayout), - NotLoaded, - LinkerScript(LinkerScriptLayoutState<'data>), -} - -/// Address information for a symbol. -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub(crate) struct Resolution { - /// An address or absolute value. - pub(crate) raw_value: u64, - - pub(crate) dynamic_symbol_index: Option, - - /// The base GOT address for this resolution. For pointers to symbols the GOT entry will - /// contain a single pointer. For TLS variables there can be up to 3 pointers. If - /// ValueFlags::GOT_TLS_OFFSET is set, then that will be the first value. If - /// ValueFlags::GOT_TLS_MODULE is set, then there will be a pair of values (module and - /// offset within module). - pub(crate) got_address: Option, - pub(crate) plt_address: Option, - pub(crate) flags: ValueFlags, + /// Erase the concrete layout type into the format-agnostic `TargetLayout` enum. + pub(crate) fn into_erased(self) -> Layout<'data> { + Layout { + file_size: self.file_size, + entry_address: self.entry_address, + symbol_addresses: self.symbol_addresses, + target: self.target.into_target_layout(), + _phantom: PhantomData, + } + } } /// Address information for a section. #[derive(derive_more::Debug, Clone, Copy, Eq, PartialEq)] pub(crate) struct SectionResolution { #[debug("0x{address:x}")] - address: u64, + pub(crate) address: u64, } impl SectionResolution { /// Returns a resolution for a section that we didn't load, or for which we don't have an /// address (e.g. string-merge sections). - fn none() -> SectionResolution { + pub(crate) fn none() -> SectionResolution { SectionResolution { address: u64::MAX } } @@ -701,81 +152,22 @@ impl SectionResolution { } } -enum FileLayoutState<'data> { - Prelude(PreludeLayoutState<'data>), - Object(ObjectLayoutState<'data>), - Dynamic(DynamicLayoutState<'data>), - NotLoaded(NotLoaded), - SyntheticSymbols(SyntheticSymbolsLayoutState<'data>), - Epilogue(EpilogueLayoutState), - LinkerScript(LinkerScriptLayoutState<'data>), -} - -/// Data that doesn't come from any input files, but needs to be written by the linker. -struct PreludeLayoutState<'data> { - file_id: FileId, - symbol_id_range: SymbolIdRange, - internal_symbols: InternalSymbols<'data>, - entry_symbol_id: Option, - needs_tlsld_got_entry: bool, - identity: String, - header_info: Option, - dynamic_linker: Option, - shstrtab_size: u64, -} - -pub(crate) struct SyntheticSymbolsLayoutState<'data> { - file_id: FileId, - symbol_id_range: SymbolIdRange, - internal_symbols: InternalSymbols<'data>, -} - -pub(crate) struct EpilogueLayoutState { - format_specific: crate::elf::EpilogueLayout, - build_id_size: Option, -} - -pub(crate) struct LinkerScriptLayoutState<'data> { - file_id: FileId, - input: InputRef<'data>, - symbol_id_range: SymbolIdRange, - pub(crate) internal_symbols: InternalSymbols<'data>, -} - -#[derive(Debug)] -pub(crate) struct SyntheticSymbolsLayout<'data> { - pub(crate) internal_symbols: InternalSymbols<'data>, -} - -#[derive(Debug)] -pub(crate) struct EpilogueLayout { - pub(crate) format_specific: crate::elf::EpilogueLayout, - pub(crate) dynsym_start_index: u32, -} +/// Address information for a symbol. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub(crate) struct Resolution { + /// An address or absolute value. + pub(crate) raw_value: u64, -#[derive(Debug)] -pub(crate) struct ObjectLayout<'data> { - pub(crate) input: InputRef<'data>, - pub(crate) file_id: FileId, - pub(crate) object: &'data File<'data>, - pub(crate) sections: Vec, - pub(crate) relocations: RelocationSections, - pub(crate) section_resolutions: Vec, - pub(crate) symbol_id_range: SymbolIdRange, - /// SFrame section ranges for this object, relative to the start of the .sframe output section. - pub(crate) sframe_ranges: Vec>, - /// Sparse map from section index to relaxation delta details. - pub(crate) section_relax_deltas: RelaxDeltaMap, -} + pub(crate) dynamic_symbol_index: Option, -#[derive(Debug)] -pub(crate) struct PreludeLayout<'data> { - pub(crate) entry_symbol_id: Option, - pub(crate) tlsld_got_entry: Option, - pub(crate) identity: String, - pub(crate) header_info: HeaderInfo, - pub(crate) internal_symbols: InternalSymbols<'data>, - pub(crate) dynamic_linker: Option, + /// The base GOT address for this resolution. For pointers to symbols the GOT entry will + /// contain a single pointer. For TLS variables there can be up to 3 pointers. If + /// ValueFlags::GOT_TLS_OFFSET is set, then that will be the first value. If + /// ValueFlags::GOT_TLS_MODULE is set, then there will be a pair of values (module and + /// offset within module). + pub(crate) got_address: Option, + pub(crate) plt_address: Option, + pub(crate) flags: ValueFlags, } #[derive(Debug)] @@ -784,568 +176,51 @@ pub(crate) struct InternalSymbols<'data> { pub(crate) start_symbol_id: SymbolId, } -pub(crate) struct DynamicLayout<'data> { - pub(crate) file_id: FileId, - input: InputRef<'data>, - - /// The name we'll put into the binary to tell the dynamic loader what to load. - pub(crate) lib_name: &'data [u8], - - pub(crate) symbol_id_range: SymbolIdRange, - - pub(crate) object: &'data crate::elf::File<'data>, - - pub(crate) copy_relocation_symbols: Vec, - - pub(crate) format_specific_layout: - as ObjectFile<'data>>::DynamicLayout, -} - -trait HandlerData { - fn symbol_id_range(&self) -> SymbolIdRange; - - fn file_id(&self) -> FileId; -} - -trait SymbolRequestHandler<'data>: std::fmt::Display + HandlerData { - fn finalise_symbol_sizes( - &mut self, - common: &mut CommonGroupState, - symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources, - ) -> Result { - let symbol_db = resources.symbol_db; - - let _file_span = symbol_db.args.trace_span_for_file(self.file_id()); - let symbol_id_range = self.symbol_id_range(); - - for (local_index, atomic_flags) in symbol_flags.range(symbol_id_range).iter().enumerate() { - let symbol_id = symbol_id_range.offset_to_id(local_index); - if !symbol_db.is_canonical(symbol_id) { - continue; - } - let flags = atomic_flags.get(); - - // It might be tempting to think that this code should only be run for dynamic objects, - // however regular objects can own dynamic symbols too if the symbol is an undefined - // weak symbol. - if flags.is_dynamic() && flags.has_resolution() { - let name = symbol_db.symbol_name(symbol_id)?; - let name = RawSymbolName::parse(name.bytes()).name; - - if flags.needs_copy_relocation() { - // The dynamic symbol is a definition, so is handled by the epilogue. We only - // need to deal with the symtab entry here. - let entry_size = size_of::() as u64; - common.allocate(part_id::SYMTAB_GLOBAL, entry_size); - common.allocate(part_id::STRTAB, name.len() as u64 + 1); - } else { - common.allocate(part_id::DYNSTR, name.len() as u64 + 1); - common.allocate(part_id::DYNSYM, crate::elf::SYMTAB_ENTRY_SIZE); - } - } - - if symbol_db.args.verify_allocation_consistency { - verify_consistent_allocation_handling(flags, symbol_db.output_kind)?; - } - - allocate_symbol_resolution(flags, &mut common.mem_sizes, symbol_db.output_kind); - - if symbol_db.args.got_plt_syms && flags.needs_got() { - let name = symbol_db.symbol_name(symbol_id)?; - let name = RawSymbolName::parse(name.bytes()).name; - let name_len = name.len() + 4; // "$got" or "$plt" suffix - - let entry_size = size_of::() as u64; - common.allocate(part_id::SYMTAB_LOCAL, entry_size); - common.allocate(part_id::STRTAB, name_len as u64 + 1); - - if flags.needs_plt() { - common.allocate(part_id::SYMTAB_LOCAL, entry_size); - common.allocate(part_id::STRTAB, name_len as u64 + 1); - } - } - } - - Ok(()) - } - - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result; -} - -fn export_dynamic<'data>( - common: &mut CommonGroupState<'data>, - symbol_id: SymbolId, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, -) -> Result { - let name = symbol_db.symbol_name(symbol_id)?; - let RawSymbolName { - name, - version_name, - is_default, - } = RawSymbolName::parse(name.bytes()); - - let mut version = object::elf::VER_NDX_GLOBAL; - if symbol_db.version_script.version_count() > 0 { - // TODO: We already hashed this symbol at some point previously. See if we can avoid - // rehashing it here and if that actually saves us time. - if let Some(v) = symbol_db - .version_script - .version_for_symbol(&UnversionedSymbolName::prehashed(name), version_name)? - { - version = v; - if !is_default { - version |= object::elf::VERSYM_HIDDEN; - } - } - } - - common - .dynamic_symbol_definitions - .push(DynamicSymbolDefinition::new(symbol_id, name, version)); - - Ok(()) -} - -fn allocate_symbol_resolution( - flags: ValueFlags, - mem_sizes: &mut OutputSectionPartMap, - output_kind: OutputKind, -) { - allocate_resolution(flags, mem_sizes, output_kind); -} - -/// Computes how much to allocate for a particular resolution. This is intended for debug assertions -/// when we're writing, to make sure that we would have allocated memory before we write. -pub(crate) fn compute_allocations( - resolution: &Resolution, - output_kind: OutputKind, -) -> OutputSectionPartMap { - let mut sizes = OutputSectionPartMap::with_size(NUM_SINGLE_PART_SECTIONS as usize); - allocate_resolution(resolution.flags, &mut sizes, output_kind); - sizes -} - -fn allocate_resolution( - flags: ValueFlags, - mem_sizes: &mut OutputSectionPartMap, - output_kind: OutputKind, -) { - let has_dynamic_symbol = flags.is_dynamic() || flags.needs_export_dynamic(); - - if flags.needs_got() && !flags.is_tls() { - mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); - if flags.needs_plt() { - mem_sizes.increment(part_id::PLT_GOT, elf::PLT_ENTRY_SIZE); - } - if flags.is_ifunc() { - mem_sizes.increment(part_id::RELA_PLT, elf::RELA_ENTRY_SIZE); - } else if flags.is_interposable() && has_dynamic_symbol { - mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } else if flags.is_address() && output_kind.is_relocatable() { - mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); - } - } - - if flags.needs_ifunc_got_for_address() { - mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); - if output_kind.is_relocatable() { - mem_sizes.increment(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); - } - } - - if flags.needs_got_tls_offset() { - mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE); - if flags.is_interposable() || output_kind.is_shared_object() { - mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } - } - - if flags.needs_got_tls_module() { - mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); - // For executables, the TLS module ID is known at link time. For shared objects, we - // need a runtime relocation to fill it in. - if !output_kind.is_executable() || flags.is_dynamic() { - mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } - if flags.is_interposable() && has_dynamic_symbol { - mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } - } - - if flags.needs_got_tls_descriptor() { - mem_sizes.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); - mem_sizes.increment(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } -} - -impl HandlerData for ObjectLayoutState<'_> { - fn file_id(&self) -> FileId { - self.file_id - } - - fn symbol_id_range(&self) -> SymbolIdRange { - self.symbol_id_range - } -} - -impl<'data> SymbolRequestHandler<'data> for ObjectLayoutState<'data> { - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - symbol_id: SymbolId, - resources: &GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - _scope: &Scope<'scope>, - ) -> Result { - debug_assert_bail!( - resources.symbol_db.is_canonical(symbol_id), - "Tried to load symbol in a file that doesn't hold the definition: {}", - resources.symbol_debug(symbol_id) - ); - - let object_symbol_index = self.symbol_id_range.id_to_input(symbol_id); - let local_symbol = self.object.symbol(object_symbol_index)?; - - if let Some(section_id) = self - .object - .symbol_section(local_symbol, object_symbol_index)? - { - queue - .local_work - .push(WorkItem::LoadSection(SectionLoadRequest::new( - self.file_id, - section_id, - ))); - } else if let Some(common_symbol) = local_symbol.as_common() { - common.allocate(common_symbol.part_id, common_symbol.size); - } - - Ok(()) - } +#[derive(derive_more::Debug, Clone, Copy)] +pub(crate) struct DynamicSymbolDefinition<'data> { + pub(crate) symbol_id: SymbolId, + #[debug("{:?}", String::from_utf8_lossy(name))] + pub(crate) name: &'data [u8], + pub(crate) hash: u32, + pub(crate) version: u16, } -impl HandlerData for DynamicLayoutState<'_> { - fn symbol_id_range(&self) -> SymbolIdRange { - self.symbol_id_range - } - - fn file_id(&self) -> FileId { - self.file_id - } +#[derive(Debug, Clone, Copy)] +pub(crate) struct Section { + pub(crate) index: object::SectionIndex, + pub(crate) part_id: PartId, + /// Size in the output. This starts as the input section size, then may be reduced by + /// relaxation-induced byte deletions during `scan_relaxations`. + pub(crate) size: u64, + pub(crate) flags: ValueFlags, + pub(crate) is_writable: bool, } -impl<'data> SymbolRequestHandler<'data> for DynamicLayoutState<'data> { - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - _common: &mut CommonGroupState, - symbol_id: SymbolId, - resources: &GraphResources<'data, 'scope>, - _queue: &mut LocalWorkQueue, - _scope: &Scope<'scope>, - ) -> Result { - let local_index = object::SymbolIndex(symbol_id.to_offset(self.symbol_id_range())); - self.object - .dynamic_symbol_used(local_index, &mut self.format_specific_state)?; - - // Check for arch-specific VARIANT_PCS flags. - if P::is_symbol_variant_pcs(self.object, local_index) { - resources - .has_variant_pcs - .store(true, atomic::Ordering::Relaxed); +impl Section { + // How much space we take up. This is our size rounded up to the next multiple of our + // alignment, unless we're in a packed section, in which case it's just our size. + pub(crate) fn capacity(&self) -> u64 { + if self.part_id.should_pack() { + self.size + } else { + self.alignment().align_up(self.size) } - - Ok(()) } -} - -impl HandlerData for PreludeLayoutState<'_> { - fn file_id(&self) -> FileId { - self.file_id - } - - fn symbol_id_range(&self) -> SymbolIdRange { - self.symbol_id_range - } -} - -impl<'data> SymbolRequestHandler<'data> for PreludeLayoutState<'data> { - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - _common: &mut CommonGroupState, - _symbol_id: SymbolId, - _resources: &GraphResources<'data, 'scope>, - _queue: &mut LocalWorkQueue, - _scope: &Scope<'scope>, - ) -> Result { - Ok(()) - } -} - -impl HandlerData for LinkerScriptLayoutState<'_> { - fn symbol_id_range(&self) -> SymbolIdRange { - self.symbol_id_range - } - - fn file_id(&self) -> FileId { - self.file_id - } -} - -impl<'data> SymbolRequestHandler<'data> for LinkerScriptLayoutState<'data> { - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - _common: &mut CommonGroupState<'data>, - _symbol_id: SymbolId, - _resources: &GraphResources<'data, 'scope>, - _queue: &mut LocalWorkQueue, - _scope: &Scope<'scope>, - ) -> Result { - Ok(()) - } -} -impl HandlerData for SyntheticSymbolsLayoutState<'_> { - fn file_id(&self) -> FileId { - self.file_id + pub(crate) fn output_section_id(&self) -> OutputSectionId { + self.part_id.output_section_id() } - fn symbol_id_range(&self) -> SymbolIdRange { - self.symbol_id_range + pub(crate) fn output_part_id(&self) -> PartId { + self.part_id } -} - -impl<'data> SymbolRequestHandler<'data> for SyntheticSymbolsLayoutState<'data> { - fn load_symbol<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - _common: &mut CommonGroupState, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, 'scope>, - _queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - let def_info = - &self.internal_symbols.symbol_definitions[self.symbol_id_range.id_to_offset(symbol_id)]; - - if let Some(output_section_id) = def_info.section_id() { - // We've gotten a request to load a __start_ / __stop_ symbol, sent requests to load all - // sections that would go into that section. - let sections = resources.start_stop_sections.get(output_section_id); - while let Some(request) = sections.pop() { - resources.send_work::

( - request.file_id, - WorkItem::LoadSection(request), - resources, - scope, - ); - } - } - Ok(()) + /// Returns the alignment for this section. + pub(crate) fn alignment(&self) -> Alignment { + self.part_id.alignment() } } -#[derive(Debug)] -pub(crate) struct CommonGroupState<'data> { - mem_sizes: OutputSectionPartMap, - - section_attributes: OutputSectionMap>, - - /// Dynamic symbols that need to be defined. Because of the ordering requirements for symbol - /// hashes, these get defined by the epilogue. The object on which a particular dynamic symbol - /// is stored is non-deterministic and is whichever object first requested export of that - /// symbol. That's OK though because the epilogue will sort all dynamic symbols. - dynamic_symbol_definitions: Vec>, - - pub(crate) format_specific: as ObjectFile<'data>>::CommonGroupStateExt, -} - -impl CommonGroupState<'_> { - fn new(output_sections: &OutputSections) -> Self { - Self { - mem_sizes: output_sections.new_part_map(), - section_attributes: output_sections.new_section_map(), - dynamic_symbol_definitions: Default::default(), - format_specific: Default::default(), - } - } - - fn validate_sizes(&self) -> Result { - if *self.mem_sizes.get(part_id::GNU_VERSION) > 0 { - let num_dynamic_symbols = - self.mem_sizes.get(part_id::DYNSYM) / crate::elf::SYMTAB_ENTRY_SIZE; - let num_versym = self.mem_sizes.get(part_id::GNU_VERSION) / size_of::() as u64; - if num_versym != num_dynamic_symbols { - bail!( - "Object has {num_dynamic_symbols} dynamic symbols, but \ - has {num_versym} versym entries" - ); - } - } - - Ok(()) - } - - fn finalise_layout( - &self, - memory_offsets: &mut OutputSectionPartMap, - section_layouts: &OutputSectionMap, - ) -> u32 { - // strtab - let offset = memory_offsets.get_mut(part_id::STRTAB); - let strtab_offset_start = (*offset - - section_layouts.get(output_section_id::STRTAB).mem_offset) - .try_into() - .expect("Symbol string table overflowed 32 bits"); - *offset += self.mem_sizes.get(part_id::STRTAB); - - // symtab - memory_offsets.increment( - part_id::SYMTAB_LOCAL, - *self.mem_sizes.get(part_id::SYMTAB_LOCAL), - ); - memory_offsets.increment( - part_id::SYMTAB_GLOBAL, - *self.mem_sizes.get(part_id::SYMTAB_GLOBAL), - ); - - strtab_offset_start - } - - pub(crate) fn allocate(&mut self, part_id: PartId, size: u64) { - self.mem_sizes.increment(part_id, size); - } - - /// Allocate resources and update attributes based on a section having been loaded. - fn section_loaded( - &mut self, - part_id: PartId, - header: &object::elf::SectionHeader64, - section: Section, - ) { - self.allocate(part_id, section.capacity()); - self.store_section_attributes(part_id, header); - } - - fn store_section_attributes( - &mut self, - part_id: PartId, - header: &object::elf::SectionHeader64, - ) { - let existing_attributes = self.section_attributes.get_mut(part_id.output_section_id()); - - let new_attributes = header.attributes(); - - if let Some(existing) = existing_attributes { - existing.merge(new_attributes); - } else { - *existing_attributes = Some(new_attributes); - } - } -} - -pub(crate) struct ObjectLayoutState<'data> { - input: InputRef<'data>, - file_id: FileId, - pub(crate) symbol_id_range: SymbolIdRange, - pub(crate) object: &'data File<'data>, - - /// Info about each of our sections. Indexed the same as the sections in the input object. - pub(crate) sections: Vec, - - /// Mapping from sections to their corresponding relocation section. - relocations: object::read::elf::RelocationSections, - - pub(crate) format_specific_layout_state: as ObjectFile<'data>>::FileLayoutState, - - /// Sparse map from section index to relaxation delta details, built during `finalise_sizes` - /// and later transferred to `ObjectLayout`. - section_relax_deltas: RelaxDeltaMap, -} - -#[derive(Debug, Default)] -pub(crate) struct LocalWorkQueue { - /// The index of the worker that owns this queue. - index: usize, - - /// Work that needs to be processed by the worker that owns this queue. - local_work: Vec, -} - -struct DynamicLayoutState<'data> { - object: &'data File<'data>, - input: InputRef<'data>, - file_id: FileId, - symbol_id_range: SymbolIdRange, - lib_name: &'data [u8], - - format_specific_state: as ObjectFile<'data>>::DynamicLayoutState, - - /// Maps from addresses within the shared object to copy relocations at that address. - copy_relocations: HashMap, -} - -struct CopyRelocationInfo { - /// The symbol ID for which we'll actually generate the copy relocation. Initially, this is - /// just the first symbol at a particular address for which we requested a copy relocation, - /// then later we may update it to point to a different symbol if that first symbol was - /// weak. - symbol_id: SymbolId, - - is_weak: bool, -} - -#[derive(derive_more::Debug, Clone, Copy)] -pub(crate) struct DynamicSymbolDefinition<'data> { - pub(crate) symbol_id: SymbolId, - #[debug("{:?}", String::from_utf8_lossy(name))] - pub(crate) name: &'data [u8], - pub(crate) hash: u32, - pub(crate) version: u16, -} - -#[derive(Debug, Clone, Copy)] -pub(crate) struct Section { - pub(crate) index: object::SectionIndex, - pub(crate) part_id: PartId, - /// Size in the output. This starts as the input section size, then may be reduced by - /// relaxation-induced byte deletions during `scan_relaxations`. - pub(crate) size: u64, - pub(crate) flags: ValueFlags, - pub(crate) is_writable: bool, -} - -#[derive(Debug)] -pub(crate) struct GroupLayout<'data> { - pub(crate) files: Vec>, - - /// The offset in .dynstr at which we'll start writing. - pub(crate) dynstr_start_offset: u32, - - /// The offset in .strtab at which we'll start writing. - pub(crate) strtab_start_offset: u32, - - pub(crate) mem_sizes: OutputSectionPartMap, - pub(crate) file_sizes: OutputSectionPartMap, - - pub(crate) format_specific: as ObjectFile<'data>>::GroupLayoutExt, -} - -#[derive(Debug)] -pub(crate) struct GroupState<'data> { - queue: LocalWorkQueue, - files: Vec>, - pub(crate) common: CommonGroupState<'data>, - num_symbols: usize, -} - /// The sizes and positions of either a segment or an output section. Note, we use usize for file /// offsets and sizes, since we mmap our output file, so we're frequently working with in-memory /// slices. This means that if we were linking on a 32 bit system that we'd be limited to file @@ -1359,4759 +234,3 @@ pub(crate) struct OutputRecordLayout { pub(crate) file_offset: usize, pub(crate) mem_offset: u64, } - -pub(crate) struct GraphResources<'data, 'scope> { - pub(crate) symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, - - output_sections: &'scope OutputSections<'data>, - - worker_slots: Vec>>, - - errors: Mutex>, - - per_symbol_flags: &'scope AtomicPerSymbolFlags<'scope>, - - /// Sections that we'll keep, even if their total size is zero. - must_keep_sections: OutputSectionMap, - - has_static_tls: AtomicBool, - - has_variant_pcs: AtomicBool, - - uses_tlsld: AtomicBool, - - /// For each OutputSectionId, this tracks a list of sections that should be loaded if that - /// section gets referenced. The sections here will only be those that are eligible for having - /// __start_ / __stop_ symbols. i.e. sections that don't start their names with a ".". - start_stop_sections: OutputSectionMap>, - - /// The number of groups that haven't yet completed activation. - activations_remaining: AtomicUsize, - - /// Groups that cannot be processed until all groups have completed activation. - delay_processing: ArrayQueue>, - - sonames: Sonames<'data>, -} - -struct FinaliseLayoutResources<'scope, 'data> { - symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, - per_symbol_flags: &'scope PerSymbolFlags, - output_sections: &'scope OutputSections<'data>, - output_order: &'scope OutputOrder, - section_layouts: &'scope OutputSectionMap, - merged_string_start_addresses: &'scope MergedStringStartAddresses, - merged_strings: &'scope OutputSectionMap>, - dynamic_symbol_definitions: &'scope Vec>, - segment_layouts: &'scope SegmentLayouts, - program_segments: &'scope ProgramSegments, - format_specific: &'scope ElfLayoutProperties, -} - -#[derive(Copy, Clone, Debug)] -enum WorkItem { - /// The symbol's resolution flags have been made non-empty. The object that owns the symbol - /// should perform any additional actions required, e.g. load the section that contains the - /// symbol and process any relocations for that section. - LoadGlobalSymbol(SymbolId), - - /// A direct reference to a dynamic symbol has been encountered. The symbol should be defined in - /// BSS with a copy relocation. - CopyRelocateSymbol(SymbolId), - - /// A request to load a particular section. - LoadSection(SectionLoadRequest), - - /// Requests that the specified symbol be exported as a dynamic symbol. Will be ignored if the - /// object that defines the symbol is not loaded or is itself a shared object. - ExportDynamic(SymbolId), -} - -#[derive(Copy, Clone, Debug)] -struct SectionLoadRequest { - file_id: FileId, - - /// The offset of the section within the file's sections. i.e. the same as - /// object::SectionIndex, but stored as a u32 for compactness. - section_index: u32, -} - -impl WorkItem { - fn file_id<'data>(self, symbol_db: &SymbolDb<'data, crate::elf::File<'data>>) -> FileId { - match self { - WorkItem::LoadGlobalSymbol(s) | WorkItem::CopyRelocateSymbol(s) => { - symbol_db.file_id_for_symbol(s) - } - WorkItem::LoadSection(s) => s.file_id, - WorkItem::ExportDynamic(symbol_id) => symbol_db.file_id_for_symbol(symbol_id), - } - } -} - -impl<'data> Layout<'data> { - pub(crate) fn prelude(&self) -> &PreludeLayout<'data> { - let Some(FileLayout::Prelude(i)) = self.group_layouts.first().and_then(|g| g.files.first()) - else { - panic!("Prelude layout not found at expected offset"); - }; - i - } - - pub(crate) fn args(&self) -> &'data Args { - self.symbol_db.args - } - - pub(crate) fn symbol_debug<'layout>( - &'layout self, - symbol_id: SymbolId, - ) -> SymbolDebug<'layout, 'data, crate::elf::File<'data>> { - self.symbol_db - .symbol_debug(&self.per_symbol_flags, symbol_id) - } - - #[inline(always)] - pub(crate) fn merged_symbol_resolution(&self, symbol_id: SymbolId) -> Option { - self.local_symbol_resolution(self.symbol_db.definition(symbol_id)) - .copied() - .map(|mut res| { - res.flags.merge( - self.symbol_db - .flags_for_symbol(&self.per_symbol_flags, symbol_id), - ); - res - }) - } - - pub(crate) fn local_symbol_resolution(&self, symbol_id: SymbolId) -> Option<&Resolution> { - self.symbol_resolutions.resolutions[symbol_id.as_usize()].as_ref() - } - - pub(crate) fn resolutions_in_range( - &self, - range: SymbolIdRange, - ) -> impl Iterator)> { - self.symbol_resolutions.resolutions[range.as_usize()] - .iter() - .enumerate() - .map(move |(i, res)| (range.offset_to_id(i), res.as_ref())) - } - - pub(crate) fn entry_symbol_address(&self) -> Result { - let Some(symbol_id) = self.prelude().entry_symbol_id else { - if self.symbol_db.output_kind == OutputKind::SharedObject { - // Shared objects don't have an implicit entry point. - return Ok(0); - } - - // There's no entry point specified, set it to the start of .text. This is pretty weird, - // but it's what GNU ld does. - let text_layout = self.section_layouts.get(output_section_id::TEXT); - if text_layout.mem_size == 0 { - crate::error::warning( - "cannot find entry symbol `_start` and .text is empty, not setting entry point", - ); - - return Ok(0); - } - - crate::error::warning(&format!( - "cannot find entry symbol `_start`, defaulting to 0x{}", - text_layout.mem_offset - )); - return Ok(text_layout.mem_offset); - }; - - let resolution = self.local_symbol_resolution(symbol_id).with_context(|| { - format!( - "Entry point symbol was defined, but didn't get loaded. {}", - self.symbol_debug(symbol_id) - ) - })?; - - if !resolution.flags().is_address() && !resolution.flags().is_absolute() { - bail!( - "Entry point must be an address or absolute value. {}", - self.symbol_debug(symbol_id) - ); - } - - Ok(resolution.value()) - } - - pub(crate) fn tls_start_address(&self) -> u64 { - // If we don't have a TLS segment then the value we return won't really matter. - self.segment_layouts - .tls_layout - .as_ref() - .map_or(0, |seg| seg.mem_offset) - } - - /// Returns the memory address of the end of the TLS segment including any padding required to - /// make sure that the TCB will be usize-aligned. - pub(crate) fn tls_end_address(&self) -> u64 { - self.segment_layouts.tls_layout.as_ref().map_or(0, |seg| { - seg.alignment.align_up(seg.mem_offset + seg.mem_size) - }) - } - - /// Returns the memory address of the start of the TLS segment used by the AArch64. - pub(crate) fn tls_start_address_aarch64(&self) -> u64 { - self.segment_layouts.tls_layout.as_ref().map_or(0, |seg| { - // Two words at TP are reserved by the arch. - seg.alignment.align_down(seg.mem_offset - 2 * 8) - }) - } - - pub(crate) fn layout_data(&self) -> linker_layout::Layout { - let files = self - .group_layouts - .iter() - .flat_map(|group| { - group.files.iter().filter_map(|file| match file { - FileLayout::Object(obj) => Some(linker_layout::InputFile { - path: obj.input.file.filename.clone(), - archive_entry: obj.input.entry.as_ref().map(|e| { - linker_layout::ArchiveEntryInfo { - range: e.byte_range(), - identifier: e.identifier.as_slice().to_owned(), - } - }), - sections: obj - .section_resolutions - .iter() - .zip(obj.object.section_iter()) - .zip(&obj.sections) - .map(|((res, section), section_slot)| { - (matches!(section_slot, SectionSlot::Loaded(..)) - && section.flags().is_alloc() - && obj.object.section_size(section).is_ok_and(|s| s > 0)) - .then(|| { - let address = res.address; - let size = match section_slot { - SectionSlot::Loaded(sec) => sec.size, - _ => obj.object.section_size(section).unwrap(), - }; - linker_layout::Section { - mem_range: address..(address + size), - } - }) - }) - .collect(), - temporary: obj.input.file.modifiers.temporary, - }), - _ => None, - }) - }) - .collect(); - linker_layout::Layout { files } - } - - pub(crate) fn flags_for_symbol(&self, symbol_id: SymbolId) -> ValueFlags { - self.symbol_db - .flags_for_symbol(&self.per_symbol_flags, symbol_id) - } - - pub(crate) fn file_layout(&self, file_id: FileId) -> &FileLayout<'data> { - let group_layout = &self.group_layouts[file_id.group()]; - &group_layout.files[file_id.file()] - } - - /// Returns the base address of the global offset table. This needs to be consistent with the - /// symbol `_GLOBAL_OFFSET_TABLE_`. - pub(crate) fn got_base(&self) -> u64 { - let got_layout = self.section_layouts.get(output_section_id::GOT); - got_layout.mem_offset - } - - /// Returns whether we're going to output the .gnu.version section. - pub(crate) fn gnu_version_enabled(&self) -> bool { - self.section_part_layouts - .get(part_id::GNU_VERSION) - .file_size - > 0 - } -} - -fn layout_sections( - output_sections: &OutputSections, - section_part_layouts: &OutputSectionPartMap, -) -> OutputSectionMap { - section_part_layouts.merge_parts(|section_id, layouts| { - let info = output_sections.section_infos.get(section_id); - let mut file_offset = usize::MAX; - let mut mem_offset = u64::MAX; - let mut file_end = 0; - let mut mem_end = 0; - let mut alignment = info.min_alignment; - - for part in layouts { - file_offset = file_offset.min(part.file_offset); - mem_offset = mem_offset.min(part.mem_offset); - file_end = file_end.max(part.file_offset + part.file_size); - mem_end = mem_end.max(part.mem_offset + part.mem_size); - if part.mem_size > 0 { - alignment = alignment.max(part.alignment); - } - } - OutputRecordLayout { - file_size: file_end - file_offset, - mem_size: mem_end - mem_offset, - alignment, - file_offset, - mem_offset, - } - }) -} - -fn merge_secondary_parts( - output_sections: &OutputSections, - section_layouts: &mut OutputSectionMap, -) { - for (id, info) in output_sections.ids_with_info() { - if let SectionKind::Secondary(primary_id) = info.kind { - let secondary_layout = take(section_layouts.get_mut(id)); - section_layouts.get_mut(primary_id).merge(&secondary_layout); - } - } -} - -fn compute_start_offsets_by_group( - group_states: &[GroupState<'_>], - mut mem_offsets: OutputSectionPartMap, -) -> Vec> { - timing_phase!("Compute per-group start offsets"); - - group_states - .iter() - .map(|group| { - let group_mem_starts = mem_offsets.clone(); - mem_offsets.merge(&group.common.mem_sizes); - group_mem_starts - }) - .collect_vec() -} - -fn compute_symbols_and_layouts<'data>( - group_states: Vec>, - starting_mem_offsets_by_group: Vec>, - per_group_res_writers: &mut [sharded_vec_writer::Shard>], - resources: &FinaliseLayoutResources<'_, 'data>, -) -> Result>> { - timing_phase!("Assign symbol addresses"); - - group_states - .into_par_iter() - .zip(starting_mem_offsets_by_group) - .zip(per_group_res_writers) - .map(|((state, mut memory_offsets), symbols_out)| { - verbose_timing_phase!("Assign addresses for group"); - - if cfg!(debug_assertions) { - let offset_verifier = crate::verification::OffsetVerifier::new( - &memory_offsets, - &state.common.mem_sizes, - ); - - // Make sure that ignored offsets really aren't used by `finalise_layout` by setting - // them to an arbitrary value. If they are used, we'll quickly notice. - crate::verification::clear_ignored(&mut memory_offsets); - - let layout = state.finalise_layout(&mut memory_offsets, symbols_out, resources)?; - - offset_verifier.verify( - &memory_offsets, - resources.output_sections, - resources.output_order, - &layout.files, - )?; - Ok(layout) - } else { - state.finalise_layout(&mut memory_offsets, symbols_out, resources) - } - }) - .collect() -} - -fn compute_segment_layout( - section_layouts: &OutputSectionMap, - output_sections: &OutputSections, - output_order: &OutputOrder, - program_segments: &ProgramSegments, - header_info: &HeaderInfo, - args: &Args, -) -> Result { - #[derive(Clone)] - struct Record { - segment_id: ProgramSegmentId, - file_start: usize, - file_end: usize, - mem_start: u64, - mem_end: u64, - alignment: Alignment, - } - - timing_phase!("Compute segment layouts"); - - use output_section_id::OrderEvent; - let mut complete = Vec::with_capacity(program_segments.len()); - let mut active_segments = vec![None; program_segments.len()]; - - for event in output_order { - match event { - OrderEvent::SegmentStart(segment_id) => { - if program_segments.is_stack_segment(segment_id) { - // STACK segment is special as it does not contain any section. - active_segments[segment_id.as_usize()] = Some(Record { - segment_id, - file_start: 0, - file_end: 0, - mem_start: 0, - mem_end: args.z_stack_size.map_or(0, |size| size.get()), - alignment: alignment::MIN, - }); - } else { - active_segments[segment_id.as_usize()] = Some(Record { - segment_id, - file_start: usize::MAX, - file_end: 0, - mem_start: u64::MAX, - mem_end: 0, - alignment: alignment::MIN, - }); - } - } - OrderEvent::SegmentEnd(segment_id) => { - let record = active_segments[segment_id.as_usize()] - .take() - .context("SegmentEnd without matching SegmentStart")?; - - complete.push(record); - } - OrderEvent::Section(section_id) => { - let section_layout = section_layouts.get(section_id); - let merge_target = output_sections.primary_output_section(section_id); - - // Skip all ignored sections that will not end up in the final file. - if section_layout.file_size == 0 - && section_layout.mem_size == 0 - && output_sections.output_section_indexes[merge_target.as_usize()].is_none() - { - continue; - } - let section_flags = output_sections.section_flags(merge_target); - let section_info = output_sections.output_info(section_id); - - if active_segments.iter().all(|s| s.is_none()) { - ensure!( - section_layout.mem_offset == 0, - "Expected zero address for section {} not present in any program segment.", - output_sections.section_debug(section_id) - ); - ensure!( - !section_flags.contains(shf::ALLOC), - "Section with SHF_ALLOC flag {} not present in any program segment.", - output_sections.section_debug(section_id) - ); - } else { - // TODO: Remove the NOTE exception. Non-alloc sections should be placed outside - // of program segments. NOTE sections are sometimes alloc and sometimes not. - // Alloc NOTE sections should be placed within a LOAD segment and within a NOTE - // segment. Non-alloc NOTE sections shouldn't be in any segment. - - // The .riscv.attributes section is non-alloc but is expected to be put into a - // RISCV_ATTRIBUTES segment. - if [NOTE, RISCV_ATTRIBUTES].contains(§ion_info.ty) { - } else { - // All segments should only cover sections that are allocated and have a - // non-zero address. - ensure!( - section_layout.mem_offset != 0 || merge_target == FILE_HEADER, - "Missing memory offset for section {} present in a program segment.", - output_sections.section_debug(section_id), - ); - ensure!( - section_flags.contains(shf::ALLOC), - "Missing SHF_ALLOC section flag for section {} present in a program \ - segment.", - output_sections.section_debug(section_id) - ); - } - for opt_rec in &mut active_segments { - let Some(rec) = opt_rec.as_mut() else { - continue; - }; - - rec.file_start = rec.file_start.min(section_layout.file_offset); - rec.mem_start = rec.mem_start.min(section_layout.mem_offset); - rec.file_end = rec - .file_end - .max(section_layout.file_offset + section_layout.file_size); - rec.mem_end = rec - .mem_end - .max(section_layout.mem_offset + section_layout.mem_size); - rec.alignment = rec.alignment.max(section_layout.alignment); - } - } - } - OrderEvent::SetLocation(_) => {} - } - } - - complete.sort_by_key(|r| r.segment_id); - - assert_eq!(complete.len(), program_segments.len()); - let mut tls_layout = None; - - let mut segments: Vec = header_info - .active_segment_ids - .iter() - .map(|&id| { - let r = &complete[id.as_usize()]; - - let sizes = OutputRecordLayout { - file_size: r.file_end - r.file_start, - mem_size: r.mem_end - r.mem_start, - alignment: r.alignment, - file_offset: r.file_start, - mem_offset: r.mem_start, - }; - - if program_segments.is_tls_segment(id) { - tls_layout = Some(sizes); - } - - SegmentLayout { id, sizes } - }) - .collect(); - - segments.sort_by_key(|s| program_segments.order_key(s.id, s.sizes.mem_offset)); - - Ok(SegmentLayouts { - segments, - tls_layout, - }) -} - -fn compute_total_section_part_sizes( - group_states: &mut [GroupState], - output_sections: &mut OutputSections, - output_order: &OutputOrder, - program_segments: &ProgramSegments, - per_symbol_flags: &mut PerSymbolFlags, - must_keep_sections: OutputSectionMap, - resources: &FinaliseSizesResources, -) -> Result> { - timing_phase!("Compute total section sizes"); - - let mut total_sizes: OutputSectionPartMap = output_sections.new_part_map(); - for group_state in group_states.iter() { - total_sizes.merge(&group_state.common.mem_sizes); - } - - // We need to apply late-stage adjustments for the epilogue before we do so for the prelude, - // since the prelude needs to know if the .hash section will be written, which is decided by the - // epilogue. - let last_group = group_states.last_mut().unwrap(); - let Some(FileLayoutState::Epilogue(epilogue)) = last_group.files.last_mut() else { - unreachable!(); - }; - - epilogue.apply_late_size_adjustments(&mut last_group.common, &mut total_sizes, resources)?; - - let first_group = group_states.first_mut().unwrap(); - let Some(FileLayoutState::Prelude(prelude)) = first_group.files.first_mut() else { - unreachable!(); - }; - - prelude.apply_late_size_adjustments( - &mut first_group.common, - &mut total_sizes, - must_keep_sections, - output_sections, - output_order, - program_segments, - per_symbol_flags, - resources, - )?; - - Ok(total_sizes) -} - -/// Propagates attributes from input sections to the output sections into which they were placed. -fn propagate_section_attributes(group_states: &[GroupState], output_sections: &mut OutputSections) { - timing_phase!("Propagate section attributes"); - - for group_state in group_states { - group_state - .common - .section_attributes - .for_each(|section_id, attributes| { - if let Some(attributes) = attributes { - attributes.apply(output_sections, section_id); - } - }); - } -} - -/// This is similar to computing start addresses, but is used for things that aren't addressable, -/// but which need to be unique. It's non parallel. It could potentially be run in parallel with -/// some of the stages that run after it, that don't need access to the file states. -fn apply_non_addressable_indexes<'data>( - group_states: &mut [GroupState], - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, -) -> Result { - timing_phase!("Apply non-addressable indexes"); - - let mut indexes = ::NonAddressableIndexes::new(symbol_db); - - let mut counts = ::NonAddressableCounts::default(); - - for g in group_states.iter_mut() { - for s in &mut g.files { - match s { - FileLayoutState::Dynamic(s) => { - s.object.apply_non_addressable_indexes_dynamic( - &mut indexes, - &mut counts, - &mut s.format_specific_state, - )?; - } - FileLayoutState::Epilogue(s) => { - as ObjectFile<'data>>::apply_non_addressable_indexes_epilogue( - &mut counts, - &mut s.format_specific, - ); - } - _ => {} - } - } - } - - as ObjectFile<'data>>::apply_non_addressable_indexes( - symbol_db, - &counts, - group_states.iter_mut().map(|g| &mut g.common.mem_sizes), - ); - - Ok(counts) -} - -/// Returns the starting memory address for each alignment within each segment. -fn starting_memory_offsets( - section_layouts: &OutputSectionPartMap, -) -> OutputSectionPartMap { - timing_phase!("Compute per-alignment offsets"); - - section_layouts.map(|_, rec| rec.mem_offset) -} - -#[derive(Default)] -struct WorkerSlot<'data> { - work: Vec, - worker: Option>, -} - -#[derive(Debug)] -struct GcOutputs<'data> { - group_states: Vec>, - must_keep_sections: OutputSectionMap, - has_static_tls: bool, - has_variant_pcs: bool, -} - -struct GroupActivationInputs<'data> { - resolved: ResolvedGroup<'data, crate::elf::File<'data>>, - num_symbols: usize, - group_index: usize, -} - -impl<'data> GroupActivationInputs<'data> { - fn activate_group<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - self, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) { - let GroupActivationInputs { - resolved, - num_symbols, - group_index, - } = self; - - let files = resolved - .files - .into_iter() - .map(|file| file.create_layout_state()) - .collect(); - let mut group = GroupState { - queue: LocalWorkQueue::new(group_index), - num_symbols, - files, - common: CommonGroupState::new(resources.output_sections), - }; - - let mut should_delay_processing = false; - - for file in &mut group.files { - let r = activate::

(&mut group.common, file, &mut group.queue, resources, scope) - .with_context(|| format!("Failed to activate {file}")); - - // SyntheticSymbols can't be processed until all groups have completed activation, since - // it can read from `start_stop_sections` which gets populated by other objects during - // activation. - should_delay_processing |= matches!(file, FileLayoutState::SyntheticSymbols(_)); - - if let Err(error) = r { - resources.errors.lock().unwrap().push(error); - } - } - - if should_delay_processing { - resources.delay_processing.push(group).unwrap(); - } else { - group.do_pending_work::

(resources, scope); - } - - let remaining = resources - .activations_remaining - .fetch_sub(1, atomic::Ordering::Relaxed) - - 1; - - if remaining == 0 { - while let Some(group) = resources.delay_processing.pop() { - group.do_pending_work::

(resources, scope); - } - } - } -} - -fn find_required_sections<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - groups_in: Vec>>, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - per_symbol_flags: &AtomicPerSymbolFlags, - output_sections: &OutputSections<'data>, - sonames: Sonames<'data>, -) -> Result> { - timing_phase!("Find required sections"); - - let num_groups = groups_in.len(); - - let mut worker_slots = Vec::with_capacity(num_groups); - worker_slots.resize_with(num_groups, || { - Mutex::new(WorkerSlot { - work: Default::default(), - worker: None, - }) - }); - - let resources = GraphResources { - symbol_db, - output_sections, - worker_slots, - errors: Mutex::new(Vec::new()), - per_symbol_flags, - must_keep_sections: output_sections.new_section_map(), - has_static_tls: AtomicBool::new(false), - has_variant_pcs: AtomicBool::new(false), - uses_tlsld: AtomicBool::new(false), - start_stop_sections: output_sections.new_section_map(), - activations_remaining: AtomicUsize::new(num_groups), - delay_processing: ArrayQueue::new(1), - sonames, - }; - let resources_ref = &resources; - - rayon::in_place_scope(|scope| { - queue_initial_group_processing::

(groups_in, symbol_db, resources_ref, scope); - }); - - let mut errors: Vec = take(resources.errors.lock().unwrap().as_mut()); - // TODO: Figure out good way to report more than one error. - if let Some(error) = errors.pop() { - return Err(error); - } - - let mut group_states = unwrap_worker_states(&resources.worker_slots); - let must_keep_sections = resources.must_keep_sections.into_map(|v| v.into_inner()); - - as ObjectFile<'data>>::finalise_find_required_sections(&group_states); - - // Give our prelude a chance to tie up a few last sizes while we still have access to - // `resources`. - let prelude_group = &mut group_states[0]; - let FileLayoutState::Prelude(prelude) = &mut prelude_group.files[0] else { - unreachable!("Prelude must be first"); - }; - prelude.pre_finalise_sizes( - &mut prelude_group.common, - &resources.uses_tlsld, - resources.symbol_db.args, - resources.symbol_db.output_kind, - ); - - Ok(GcOutputs { - group_states, - must_keep_sections, - has_static_tls: resources.has_static_tls.load(atomic::Ordering::Relaxed), - has_variant_pcs: resources.has_variant_pcs.load(atomic::Ordering::Relaxed), - }) -} - -fn queue_initial_group_processing< - 'data, - 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, ->( - groups_in: Vec>>, - symbol_db: &'scope SymbolDb<'data, crate::elf::File<'data>>, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, -) { - verbose_timing_phase!("Create worker slots"); - - assert_eq!(groups_in.len(), symbol_db.groups.len()); - - groups_in - .into_iter() - .enumerate() - .zip(&symbol_db.groups) - .for_each(|((group_index, resolved), group)| { - scope.spawn(move |scope| { - verbose_timing_phase!("Activate group"); - let inputs = GroupActivationInputs { - resolved, - num_symbols: group.num_symbols(), - group_index, - }; - inputs.activate_group::

(resources, scope); - }); - }); -} - -fn unwrap_worker_states<'data>( - worker_slots: &[Mutex>], -) -> Vec> { - worker_slots - .iter() - .filter_map(|w| w.lock().unwrap().worker.take()) - .collect() -} - -impl<'data> GroupState<'data> { - /// Does work until there's nothing left in the queue, then returns our worker to its slot and - /// shuts down. - fn do_pending_work<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - mut self, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) { - loop { - while let Some(work_item) = self.queue.local_work.pop() { - let file_id = work_item.file_id(resources.symbol_db); - let file = &mut self.files[file_id.file()]; - if let Err(error) = file.do_work::

( - &mut self.common, - work_item, - resources, - &mut self.queue, - scope, - ) { - resources.report_error(error); - return; - } - } - { - let mut slot = resources.worker_slots[self.queue.index].lock().unwrap(); - if slot.work.is_empty() { - slot.worker = Some(self); - return; - } - swap(&mut slot.work, &mut self.queue.local_work); - }; - } - } - - fn finalise_sizes( - &mut self, - output_sections: &OutputSections, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources<'data, '_>, - ) -> Result { - for file_state in &mut self.files { - file_state.finalise_sizes( - &mut self.common, - output_sections, - per_symbol_flags, - resources, - )?; - } - - self.common.validate_sizes()?; - Ok(()) - } - - fn finalise_layout( - self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut sharded_vec_writer::Shard>, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result> { - let format_specific = - as ObjectFile<'data>>::finalise_group_layout(memory_offsets); - let files = self - .files - .into_iter() - .map(|file| file.finalise_layout(memory_offsets, resolutions_out, resources)) - .collect::>>()?; - - let strtab_start_offset = self - .common - .finalise_layout(memory_offsets, resources.section_layouts); - let dynstr_start_offset = (memory_offsets.get(part_id::DYNSTR) - - resources - .section_layouts - .get(output_section_id::DYNSTR) - .mem_offset) as u32; - memory_offsets.increment(part_id::DYNSTR, *self.common.mem_sizes.get(part_id::DYNSTR)); - - Ok(GroupLayout { - files, - strtab_start_offset, - dynstr_start_offset, - file_sizes: compute_file_sizes(&self.common.mem_sizes, resources.output_sections), - mem_sizes: self.common.mem_sizes, - format_specific, - }) - } -} - -fn activate<'data, 'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - common: &mut CommonGroupState<'data>, - file: &mut FileLayoutState<'data>, - queue: &mut LocalWorkQueue, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, -) -> Result { - match file { - FileLayoutState::Object(s) => s.activate::

(common, resources, queue, scope)?, - FileLayoutState::Prelude(s) => s.activate::

(common, resources, queue, scope)?, - FileLayoutState::Dynamic(s) => s.activate::

(common, resources, queue, scope)?, - FileLayoutState::LinkerScript(s) => s.activate(common, resources)?, - FileLayoutState::Epilogue(_) => {} - FileLayoutState::NotLoaded(_) => {} - FileLayoutState::SyntheticSymbols(_) => {} - } - Ok(()) -} - -impl LocalWorkQueue { - #[inline(always)] - fn send_work<'data, 'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - resources: &'scope GraphResources<'data, '_>, - file_id: FileId, - work: WorkItem, - scope: &Scope<'scope>, - ) { - if file_id.group() == self.index { - self.local_work.push(work); - } else { - resources.send_work::

(file_id, work, resources, scope); - } - } - - fn new(index: usize) -> LocalWorkQueue { - Self { - index, - local_work: Default::default(), - } - } - - #[inline(always)] - fn send_symbol_request<'data, 'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) { - debug_assert!(resources.symbol_db.is_canonical(symbol_id)); - let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); - self.send_work::

( - resources, - symbol_file_id, - WorkItem::LoadGlobalSymbol(symbol_id), - scope, - ); - } - - fn send_copy_relocation_request< - 'data, - 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, - >( - &mut self, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) { - debug_assert!(resources.symbol_db.is_canonical(symbol_id)); - let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); - self.send_work::

( - resources, - symbol_file_id, - WorkItem::CopyRelocateSymbol(symbol_id), - scope, - ); - } -} - -impl<'data> GraphResources<'data, '_> { - fn report_error(&self, error: Error) { - self.errors.lock().unwrap().push(error); - } - - /// Sends all work in `work` to the worker for `file_id`. Leaves `work` empty so that it can be - /// reused. - #[inline(always)] - fn send_work<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &self, - file_id: FileId, - work: WorkItem, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) { - let worker; - { - let mut slot = self.worker_slots[file_id.group()].lock().unwrap(); - worker = slot.worker.take(); - slot.work.push(work); - }; - if let Some(worker) = worker { - scope.spawn(|scope| { - verbose_timing_phase!("Work with object"); - worker.do_pending_work::

(resources, scope); - }); - } - } - - fn local_flags_for_symbol(&self, symbol_id: SymbolId) -> ValueFlags { - self.per_symbol_flags.flags_for_symbol(symbol_id) - } - - fn symbol_debug<'a>( - &'a self, - symbol_id: SymbolId, - ) -> SymbolDebug<'a, 'data, crate::elf::File<'data>> { - self.symbol_db - .symbol_debug(self.per_symbol_flags, symbol_id) - } - - fn keep_section(&self, section_id: OutputSectionId) { - let keep = self.must_keep_sections.get(section_id); - - // We only write after reading and determining that we need to write. This likely makes the - // case where we do write slower, but the case where we don't write faster and also avoids - // gaining exclusive access to the cache line unless necessary. This has a small but - // measurable performance effect. - if !keep.load(atomic::Ordering::Relaxed) { - keep.store(true, atomic::Ordering::Relaxed); - } - } -} - -impl<'data> FileLayoutState<'data> { - fn finalise_sizes( - &mut self, - common: &mut CommonGroupState<'data>, - output_sections: &OutputSections, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources<'data, '_>, - ) -> Result { - match self { - FileLayoutState::Object(s) => { - s.finalise_sizes(common, output_sections, per_symbol_flags, resources); - s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; - } - FileLayoutState::Dynamic(s) => { - s.finalise_sizes(common)?; - s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; - } - FileLayoutState::Prelude(s) => { - PreludeLayoutState::finalise_sizes(common, resources.merged_strings); - s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; - } - FileLayoutState::SyntheticSymbols(s) => { - s.finalise_sizes(common, per_symbol_flags, resources)?; - s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; - } - FileLayoutState::Epilogue(s) => { - s.finalise_sizes(common, resources); - } - FileLayoutState::LinkerScript(s) => { - s.finalise_sizes(common, per_symbol_flags, resources)?; - s.finalise_symbol_sizes(common, per_symbol_flags, resources)?; - } - FileLayoutState::NotLoaded(_) => {} - } - - as ObjectFile<'data>>::finalise_sizes_all( - &mut common.mem_sizes, - resources.symbol_db, - ); - - Ok(()) - } - - fn do_work<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - work_item: WorkItem, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - match work_item { - WorkItem::LoadGlobalSymbol(symbol_id) => self - .handle_symbol_request::

(common, symbol_id, resources, queue, scope) - .with_context(|| { - format!( - "Failed to load {} from {self}", - resources.symbol_debug(symbol_id), - ) - }), - WorkItem::CopyRelocateSymbol(symbol_id) => match self { - FileLayoutState::Dynamic(state) => state.copy_relocate_symbol(symbol_id, resources), - - _ => { - bail!( - "Internal error: ExportCopyRelocation sent to non-dynamic object for: {}", - resources.symbol_debug(symbol_id) - ) - } - }, - WorkItem::LoadSection(request) => match self { - FileLayoutState::Object(object_layout_state) => object_layout_state - .handle_section_load_request::

( - common, - resources, - queue, - request.section_index(), - scope, - ), - _ => bail!("Request to load section from non-object: {self}"), - }, - WorkItem::ExportDynamic(symbol_id) => match self { - FileLayoutState::Object(object) => { - object.export_dynamic::

(common, symbol_id, resources, queue, scope) - } - _ => { - // Non-loaded and dynamic objects don't do anything in response to a request to - // export a dynamic symbol. - Ok(()) - } - }, - } - } - - fn handle_symbol_request<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - match self { - FileLayoutState::Object(state) => { - state.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - FileLayoutState::Prelude(state) => { - state.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - FileLayoutState::Dynamic(state) => { - state.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - FileLayoutState::LinkerScript(_) => {} - FileLayoutState::NotLoaded(_) => {} - FileLayoutState::SyntheticSymbols(state) => { - state.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - FileLayoutState::Epilogue(_) => { - // The epilogue doesn't define symbols. In fact, it isn't even created until after - // the GC phase graph traversal. - unreachable!(); - } - } - Ok(()) - } - - fn finalise_layout( - self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut sharded_vec_writer::Shard>, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result> { - let resolutions_out = &mut ResolutionWriter { resolutions_out }; - let file_layout = match self { - Self::Object(s) => { - let _span = tracing::debug_span!( - "finalise_layout", - file = %s.input - ) - .entered(); - FileLayout::Object(s.finalise_layout(memory_offsets, resolutions_out, resources)?) - } - Self::Prelude(s) => FileLayout::Prelude(s.finalise_layout( - memory_offsets, - resolutions_out, - resources, - )?), - Self::Epilogue(s) => { - FileLayout::Epilogue(s.finalise_layout(memory_offsets, resources)?) - } - Self::SyntheticSymbols(s) => FileLayout::SyntheticSymbols(s.finalise_layout( - memory_offsets, - resolutions_out, - resources, - )?), - Self::Dynamic(s) => FileLayout::Dynamic(s.finalise_layout( - memory_offsets, - resolutions_out, - resources, - )?), - Self::LinkerScript(s) => { - s.finalise_layout(memory_offsets, resolutions_out, resources)?; - FileLayout::LinkerScript(s) - } - Self::NotLoaded(s) => { - for _ in 0..s.symbol_id_range.len() { - resolutions_out.write(None)?; - } - FileLayout::NotLoaded - } - }; - Ok(file_layout) - } -} - -fn compute_file_sizes( - mem_sizes: &OutputSectionPartMap, - output_sections: &OutputSections<'_>, -) -> OutputSectionPartMap { - mem_sizes.map(|part_id, size| { - if output_sections.has_data_in_file(part_id.output_section_id()) { - *size as usize - } else { - 0 - } - }) -} - -impl std::fmt::Display for PreludeLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt("", f) - } -} - -impl std::fmt::Display for EpilogueLayoutState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt("", f) - } -} - -impl std::fmt::Display for SyntheticSymbolsLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt("", f) - } -} - -impl std::fmt::Display for LinkerScriptLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f) - } -} - -impl std::fmt::Display for FileLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - FileLayoutState::Object(s) => std::fmt::Display::fmt(s, f), - FileLayoutState::Dynamic(s) => std::fmt::Display::fmt(s, f), - FileLayoutState::LinkerScript(s) => std::fmt::Display::fmt(s, f), - FileLayoutState::Prelude(_) => std::fmt::Display::fmt("", f), - FileLayoutState::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), - FileLayoutState::NotLoaded(_) => std::fmt::Display::fmt("", f), - FileLayoutState::Epilogue(_) => std::fmt::Display::fmt("", f), - } - } -} - -impl std::fmt::Display for FileLayout<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Object(s) => std::fmt::Display::fmt(s, f), - Self::Dynamic(s) => std::fmt::Display::fmt(s, f), - Self::LinkerScript(s) => std::fmt::Display::fmt(s, f), - Self::Prelude(_) => std::fmt::Display::fmt("", f), - Self::Epilogue(_) => std::fmt::Display::fmt("", f), - Self::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), - Self::NotLoaded => std::fmt::Display::fmt("", f), - } - } -} - -impl std::fmt::Display for GroupLayout<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.files.len() == 1 { - self.files[0].fmt(f) - } else { - write!( - f, - "Group with {} files. Rerun with {}=1", - self.files.len(), - crate::args::consts::FILES_PER_GROUP_ENV - ) - } - } -} - -impl std::fmt::Display for GroupState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.files.len() == 1 { - self.files[0].fmt(f) - } else { - write!( - f, - "Group with {} files. Rerun with {}=1", - self.files.len(), - crate::args::consts::FILES_PER_GROUP_ENV - ) - } - } -} - -impl std::fmt::Debug for FileLayout<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self, f) - } -} - -impl std::fmt::Display for ObjectLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f)?; - // TODO: This is mostly for debugging use. Consider only showing this if some environment - // variable is set, or only in debug builds. - write!(f, " ({})", self.file_id()) - } -} - -impl std::fmt::Display for DynamicLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f)?; - write!(f, " ({})", self.file_id()) - } -} - -impl std::fmt::Display for DynamicLayout<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f)?; - write!(f, " ({})", self.file_id) - } -} - -impl std::fmt::Display for ObjectLayout<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f)?; - // TODO: This is mostly for debugging use. Consider only showing this if some environment - // variable is set, or only in debug builds. - write!(f, " ({})", self.file_id) - } -} - -impl Section { - fn create( - header: &crate::elf::SectionHeader, - object_state: &mut ObjectLayoutState, - section_index: object::SectionIndex, - part_id: PartId, - ) -> Result

{ - let size = object_state.object.section_size(header)?; - let section = Section { - index: section_index, - part_id, - size, - flags: ValueFlags::empty(), - is_writable: header.flags().is_writable(), - }; - Ok(section) - } - - // How much space we take up. This is our size rounded up to the next multiple of our - // alignment, unless we're in a packed section, in which case it's just our size. - pub(crate) fn capacity(&self) -> u64 { - if self.part_id.should_pack() { - self.size - } else { - self.alignment().align_up(self.size) - } - } - - pub(crate) fn output_section_id(&self) -> OutputSectionId { - self.part_id.output_section_id() - } - - pub(crate) fn output_part_id(&self) -> PartId { - self.part_id - } - - /// Returns the alignment for this section. - fn alignment(&self) -> Alignment { - self.part_id.alignment() - } - - /// Returns whether to reverse the contents of this section. This is true for .ctors/.dtors - /// sections. - pub(crate) fn should_reverse_contents( - &self, - file: &crate::elf::File, - output_sections: &OutputSections, - ) -> bool { - // Getting the section name is expensive, so we only do it when the output section is - // .init_array / .fini_array. - let section_id = output_sections.primary_output_section(self.part_id.output_section_id()); - if section_id != output_section_id::INIT_ARRAY - && section_id != output_section_id::FINI_ARRAY - { - return false; - } - - file.section(self.index) - .and_then(|header| file.section_name(header)) - .is_ok_and(|section_name| { - // .ctors and .dtors sections need their contents reversed when merged into - // .init_array/.fini_array - section_name.starts_with(secnames::CTORS_SECTION_NAME) - || section_name.starts_with(secnames::DTORS_SECTION_NAME) - }) - } -} - -#[inline(always)] -pub(crate) fn process_relocation< - 'data, - 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, - R: Relocation, ->( - object: &ObjectLayoutState<'data>, - common: &mut CommonGroupState, - rel: &R, - section: &object::elf::SectionHeader64, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - is_debug_section: bool, - scope: &Scope<'scope>, -) -> Result { - let args = resources.symbol_db.args; - let mut next_modifier = RelocationModifier::Normal; - if let Some(local_sym_index) = rel.symbol() { - let symbol_db = resources.symbol_db; - let local_symbol_id = object.symbol_id_range.input_to_id(local_sym_index); - let symbol_id = symbol_db.definition(local_symbol_id); - let mut flags = resources.local_flags_for_symbol(symbol_id); - flags.merge(resources.local_flags_for_symbol(local_symbol_id)); - let rel_offset = rel.offset(); - let r_type = rel.raw_type(); - let section_flags = SectionFlags::from_header(section); - - let rel_info = if let Some(relaxation) = P::new_relaxation( - r_type, - object.object.raw_section_data(section)?, - rel_offset, - flags, - symbol_db.output_kind, - section_flags, - true, - None, - ) - .filter(|relaxation| args.relax || relaxation.is_mandatory()) - { - next_modifier = relaxation.next_modifier(); - relaxation.rel_info() - } else { - P::relocation_from_raw(r_type)? - }; - - let section_is_writable = section_flags.is_writable(); - let mut flags_to_add = resolution_flags(rel_info.kind); - - if !section_flags.contains(shf::ALLOC) { - // Non-alloc sections never get dynamic relocations, so there's nothing to do here. - } else if rel_info.kind.is_tls() { - if does_relocation_require_static_tls(rel_info.kind) { - resources - .has_static_tls - .store(true, atomic::Ordering::Relaxed); - } - - if needs_tlsld(rel_info.kind) && !resources.uses_tlsld.load(atomic::Ordering::Relaxed) { - resources.uses_tlsld.store(true, atomic::Ordering::Relaxed); - } - } else if flags_to_add.needs_direct() && flags.is_interposable() { - if section_is_writable { - common.allocate(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } else if flags.is_function() { - // Create a PLT entry for the function and refer to that instead. - flags_to_add.remove(ValueFlags::DIRECT); - flags_to_add |= ValueFlags::PLT | ValueFlags::GOT; - } else if !flags.is_absolute() { - match args.copy_relocations { - crate::args::CopyRelocations::Allowed => { - flags_to_add |= ValueFlags::COPY_RELOCATION; - } - crate::args::CopyRelocations::Disallowed(reason) => { - // We don't at present support text relocations, so if we can't apply a copy - // relocation, we error instead. - bail!( - "Direct relocation ({}) to dynamic symbol from non-writable section, \ - but copy relocations are disabled because {reason}. {}", - P::rel_type_to_string(r_type), - resources.symbol_debug(symbol_id), - ); - } - } - } - } else if flags.is_ifunc() - && rel_info.kind == RelocationKind::Absolute - && section_is_writable - && symbol_db.output_kind.is_relocatable() - { - common.allocate(part_id::RELA_DYN_GENERAL, elf::RELA_ENTRY_SIZE); - } else if symbol_db.output_kind.is_relocatable() - && rel_info.kind == RelocationKind::Absolute - && flags.is_address() - { - if section_is_writable { - common.allocate(part_id::RELA_DYN_RELATIVE, elf::RELA_ENTRY_SIZE); - } else if !is_debug_section { - bail!( - "Cannot apply relocation {} to read-only section. \ - Please recompile with -fPIC or link with -no-pie", - P::rel_type_to_string(r_type), - ); - } - } - - // For ifunc symbols with GOT-relative references (like R_X86_64_GOTPCRELX), we need a - // separate GOT entry for address equality. The main GOT entry will be used by the PLT stub - // with an IRELATIVE relocation, while this extra entry will contain the PLT stub address so - // that all references to the ifunc return the same address. - - let relocation_needs_got = flags_to_add.needs_got(); - - if flags.is_ifunc() && !symbol_db.output_kind.is_static_executable() { - flags_to_add |= ValueFlags::GOT | ValueFlags::PLT; - } - - if flags.is_ifunc() && relocation_needs_got && !symbol_db.output_kind.is_relocatable() { - flags_to_add |= ValueFlags::IFUNC_GOT_FOR_ADDRESS; - } - - let atomic_flags = &resources.per_symbol_flags.get_atomic(symbol_id); - let previous_flags = atomic_flags.fetch_or(flags_to_add); - - if !previous_flags.has_resolution() { - if flags.is_ifunc() && symbol_db.output_kind.is_static_executable() { - atomic_flags.fetch_or(ValueFlags::GOT | ValueFlags::PLT); - } - - queue.send_symbol_request::

(symbol_id, resources, scope); - if should_emit_undefined_error( - object.object.symbol(local_sym_index)?, - object.file_id, - symbol_db.file_id_for_symbol(symbol_id), - flags, - args, - symbol_db.output_kind, - ) { - let symbol_name = symbol_db.symbol_name_for_display(symbol_id); - let source_info = - P::get_source_info(object.object, &object.relocations, section, rel_offset) - .context("Failed to get source info")?; - - if args.error_unresolved_symbols { - resources.report_error(error!( - "Undefined symbol {symbol_name}, referenced by {}\n {}", - source_info, object.input, - )); - } else { - crate::error::warning(&format!( - "Undefined symbol {symbol_name}, referenced by {}\n {}", - source_info, object.input, - )); - } - } - } - - if flags_to_add.needs_copy_relocation() && !previous_flags.needs_copy_relocation() { - queue.send_copy_relocation_request::

(symbol_id, resources, scope); - } - } - Ok(next_modifier) -} - -/// Returns whether the supplied relocation type requires static TLS. If true and we're writing a -/// shared object, then the STATIC_TLS will be set in the shared object which is a signal to the -/// runtime loader that the shared object cannot be loaded at runtime (e.g. with dlopen). -fn does_relocation_require_static_tls(rel_kind: RelocationKind) -> bool { - resolution_flags(rel_kind) == ValueFlags::GOT_TLS_OFFSET -} - -fn resolution_flags(rel_kind: RelocationKind) -> ValueFlags { - match rel_kind { - RelocationKind::PltRelative | RelocationKind::PltRelGotBase => { - ValueFlags::PLT | ValueFlags::GOT - } - RelocationKind::Got - | RelocationKind::GotRelGotBase - | RelocationKind::GotRelative - | RelocationKind::GotRelativeLoongArch64 => ValueFlags::GOT, - RelocationKind::GotTpOff - | RelocationKind::GotTpOffLoongArch64 - | RelocationKind::GotTpOffGot - | RelocationKind::GotTpOffGotBase => ValueFlags::GOT_TLS_OFFSET, - RelocationKind::TlsGd | RelocationKind::TlsGdGot | RelocationKind::TlsGdGotBase => { - ValueFlags::GOT_TLS_MODULE - } - RelocationKind::TlsDesc - | RelocationKind::TlsDescLoongArch64 - | RelocationKind::TlsDescGot - | RelocationKind::TlsDescGotBase - | RelocationKind::TlsDescCall => ValueFlags::GOT_TLS_DESCRIPTOR, - RelocationKind::TlsLd | RelocationKind::TlsLdGot | RelocationKind::TlsLdGotBase => { - ValueFlags::empty() - } - RelocationKind::Absolute - | RelocationKind::AbsoluteSet - | RelocationKind::AbsoluteSetWord6 - | RelocationKind::AbsoluteAddition - | RelocationKind::AbsoluteAdditionWord6 - | RelocationKind::AbsoluteSubtraction - | RelocationKind::AbsoluteSubtractionWord6 - | RelocationKind::Relative - | RelocationKind::RelativeRiscVLow12 - | RelocationKind::RelativeLoongArchHigh - | RelocationKind::DtpOff - | RelocationKind::TpOff - | RelocationKind::SymRelGotBase - | RelocationKind::PairSubtractionULEB128(..) => ValueFlags::DIRECT, - RelocationKind::None | RelocationKind::AbsoluteLowPart | RelocationKind::Alignment => { - ValueFlags::empty() - } - } -} - -impl<'data> PreludeLayoutState<'data> { - fn new(input_state: resolution::ResolvedPrelude<'data>) -> Self { - Self { - file_id: PRELUDE_FILE_ID, - symbol_id_range: SymbolIdRange::prelude(input_state.symbol_definitions.len()), - internal_symbols: InternalSymbols { - symbol_definitions: input_state.symbol_definitions, - start_symbol_id: SymbolId::zero(), - }, - entry_symbol_id: None, - needs_tlsld_got_entry: false, - identity: format!("Linker: {}", crate::identity::linker_identity()), - header_info: None, - dynamic_linker: None, - shstrtab_size: 0, - } - } - - fn activate<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - if resources.symbol_db.args.should_write_linker_identity { - // Allocate space to store the identity of the linker in the .comment section. - common.allocate( - output_section_id::COMMENT.part_id_with_alignment(alignment::MIN), - self.identity.len() as u64, - ); - } - - // The first entry in the symbol table must be null. Similarly, the first string in the - // strings table must be empty. - if !resources.symbol_db.args.strip_all() { - common.allocate(part_id::SYMTAB_LOCAL, size_of::() as u64); - common.allocate(part_id::STRTAB, 1); - } - - self.load_entry_point::

(resources, queue, scope); - - if resources.symbol_db.output_kind.needs_dynsym() { - // Allocate space for the null symbol. - common.allocate(part_id::DYNSTR, 1); - common.allocate(part_id::DYNSYM, size_of::() as u64); - } - - if resources.symbol_db.output_kind.is_dynamic_executable() { - self.dynamic_linker = resources - .symbol_db - .args - .dynamic_linker - .as_ref() - .map(|p| CString::new(p.as_os_str().as_encoded_bytes())) - .transpose()?; - } - if let Some(dynamic_linker) = self.dynamic_linker.as_ref() { - common.allocate( - part_id::INTERP, - dynamic_linker.as_bytes_with_nul().len() as u64, - ); - } - - self.mark_defsyms_as_used::

(resources, queue, scope); - - Ok(()) - } - - /// Mark defsyms from the command-line as being directly referenced so that we emit the symbols - /// even if nothing in the code references them. - fn mark_defsyms_as_used<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &self, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) { - for (index, def_info) in self.internal_symbols.symbol_definitions.iter().enumerate() { - let symbol_id = self.symbol_id_range.offset_to_id(index); - if !resources.symbol_db.is_canonical(symbol_id) { - continue; - } - - match def_info.placement { - SymbolPlacement::DefsymAbsolute(_) => { - resources - .per_symbol_flags - .get_atomic(symbol_id) - .or_assign(ValueFlags::DIRECT); - } - SymbolPlacement::DefsymSymbol(target_name, _offset) => { - resources - .per_symbol_flags - .get_atomic(symbol_id) - .or_assign(ValueFlags::DIRECT); - - // Also mark the target symbol as used and queue it for loading to prevent it - // from being GC'd. - if let Some(target_symbol_id) = resources - .symbol_db - .get_unversioned(&UnversionedSymbolName::prehashed(target_name.as_bytes())) - { - let canonical_target_id = resources.symbol_db.definition(target_symbol_id); - let file_id = resources.symbol_db.file_id_for_symbol(canonical_target_id); - let old_flags = resources - .per_symbol_flags - .get_atomic(canonical_target_id) - .fetch_or(ValueFlags::DIRECT); - - if !old_flags.has_resolution() { - queue.send_work::

( - resources, - file_id, - WorkItem::LoadGlobalSymbol(canonical_target_id), - scope, - ); - } - } - } - _ => {} - } - } - } - - fn load_entry_point<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) { - let Some(symbol_id) = - resources - .symbol_db - .get_unversioned(&UnversionedSymbolName::prehashed( - resources.symbol_db.entry_symbol_name(), - )) - else { - // We'll emit a warning when writing the file if it's an executable. - return; - }; - - let symbol_id = resources.symbol_db.definition(symbol_id); - - self.entry_symbol_id = Some(symbol_id); - let file_id = resources.symbol_db.file_id_for_symbol(symbol_id); - let old_flags = resources - .per_symbol_flags - .get_atomic(symbol_id) - .fetch_or(ValueFlags::DIRECT); - if !old_flags.has_resolution() { - queue.send_work::

( - resources, - file_id, - WorkItem::LoadGlobalSymbol(symbol_id), - scope, - ); - } - } - - fn pre_finalise_sizes( - &mut self, - common: &mut CommonGroupState, - uses_tlsld: &AtomicBool, - args: &Args, - output_kind: OutputKind, - ) { - if uses_tlsld.load(atomic::Ordering::Relaxed) { - // Allocate space for a TLS module number and offset for use with TLSLD relocations. - common.allocate(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); - self.needs_tlsld_got_entry = true; - // For shared objects, we'll need to use a DTPMOD relocation to fill in the TLS module - // number. - if !output_kind.is_executable() { - common.allocate(part_id::RELA_DYN_GENERAL, crate::elf::RELA_ENTRY_SIZE); - } - } - - as ObjectFile<'data>>::pre_finalise_sizes_prelude(common, args); - } - - fn finalise_sizes( - common: &mut CommonGroupState<'data>, - merged_strings: &OutputSectionMap>, - ) { - merged_strings.for_each(|section_id, merged| { - if merged.len() > 0 { - common.allocate( - section_id.part_id_with_alignment(alignment::MIN), - merged.len(), - ); - } - }); - } - - /// This function is where we determine sizes that depend on other sizes. For example, the size - /// of the section headers table, which depends on which sections we're writing, which depends - /// on which sections are non-empty. We also decide which internal symtab entries we'll write - /// here, since that also depends on which sections we're writing. - fn apply_late_size_adjustments( - &mut self, - common: &mut CommonGroupState, - total_sizes: &mut OutputSectionPartMap, - must_keep_sections: OutputSectionMap, - output_sections: &mut OutputSections, - output_order: &OutputOrder, - program_segments: &ProgramSegments, - per_symbol_flags: &mut PerSymbolFlags, - resources: &FinaliseSizesResources, - ) -> Result { - // Total section sizes have already been computed. So any allocations we do need to update - // both `total_sizes` and the size records in `common`. We track the extra sizes in - // `extra_sizes` which we can then later add to both. - let mut extra_sizes = OutputSectionPartMap::with_size(common.mem_sizes.num_parts()); - - self.determine_header_sizes( - total_sizes, - &mut extra_sizes, - must_keep_sections, - output_sections, - program_segments, - output_order, - resources, - per_symbol_flags, - ); - - self.allocate_symbol_table_sizes( - output_sections, - per_symbol_flags, - resources.symbol_db, - &mut extra_sizes, - )?; - - // We need to allocate both our own size record and the group totals, since they've already - // been computed. - common.mem_sizes.merge(&extra_sizes); - total_sizes.merge(&extra_sizes); - - Ok(()) - } - - /// Allocates space for our internal symbols. For unreferenced symbols, we also update the - /// symbol so that it is treated as referenced, but only for symbols in sections that we're - /// going to emit. - fn allocate_symbol_table_sizes( - &self, - output_sections: &OutputSections, - per_symbol_flags: &mut PerSymbolFlags, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - extra_sizes: &mut OutputSectionPartMap, - ) -> Result<(), Error> { - if symbol_db.args.strip_all() { - return Ok(()); - } - - self.internal_symbols.allocate_symbol_table_sizes( - extra_sizes, - symbol_db, - |symbol_id, def_info| { - let flags = per_symbol_flags.flags_for_symbol(symbol_id); - - // If the symbol is referenced, then we keep it. - if flags.has_resolution() { - return true; - } - - // We always emit symbols that the user requested be undefined. - let mut should_emit = def_info.placement == SymbolPlacement::ForceUndefined; - - // Keep the symbol if we're going to write the section, even though the symbol isn't - // referenced. It can be useful to have symbols like _GLOBAL_OFFSET_TABLE_ when - // using a debugger. - should_emit |= def_info.section_id().is_some_and(|output_section_id| { - output_sections.will_emit_section(output_section_id) - }); - - if should_emit { - // Mark the symbol as referenced so that we later generate a resolution for - // it and subsequently write it to the symbol table. - per_symbol_flags.set_flag(symbol_id, ValueFlags::DIRECT); - } - - should_emit - }, - ) - } - - fn determine_header_sizes( - &mut self, - total_sizes: &OutputSectionPartMap, - extra_sizes: &mut OutputSectionPartMap, - must_keep_sections: OutputSectionMap, - output_sections: &mut OutputSections, - program_segments: &ProgramSegments, - output_order: &OutputOrder, - resources: &FinaliseSizesResources, - symbol_flags: &PerSymbolFlags, - ) { - use output_section_id::OrderEvent; - - // Determine which sections to keep. To start with, we keep all sections that we've - // previously marked as needing to be kept. These may include sections that are empty, but - // into which we've loaded an empty input section. - let mut keep_sections = must_keep_sections; - - // Next, keep any sections for which we've recorded a non-zero size. - total_sizes.map(|part_id, size| { - if *size > 0 { - *keep_sections.get_mut(part_id.output_section_id()) = true; - } - }); - - // Keep any sections that we've said we want to keep regardless. - for section_id in output_section_id::built_in_section_ids() { - if section_id.built_in_details().keep_if_empty { - // Don't keep .relro_padding if relro is disabled. - if section_id == output_section_id::RELRO_PADDING && !resources.symbol_db.args.relro - { - continue; - } - *keep_sections.get_mut(section_id) = true; - } - } - - // Keep any sections that have a start/stop symbol which is referenced. - symbol_flags - .raw_range(self.symbol_id_range()) - .iter() - .zip(self.internal_symbols.symbol_definitions.iter()) - .for_each(|(raw_flags, definition)| { - if raw_flags.get().has_resolution() - && let Some(section_id) = definition.section_id() - { - *keep_sections.get_mut(section_id) = true; - } - }); - - for i in 0..output_sections.num_sections() { - let section_id = OutputSectionId::from_usize(i); - - // If any secondary sections were marked to be kept, then unmark them and mark the - // primary instead. - if let Some(primary_id) = output_sections.merge_target(section_id) { - let keep_secondary = replace(keep_sections.get_mut(section_id), false); - *keep_sections.get_mut(primary_id) |= keep_secondary; - } - - // Remove any built-in sections without a type except for section 0 (the file header). - // This should just be the .phdr and .shdr sections which contain the program headers - // and section headers. We need these sections in order to allocate space for those - // structures, but other linkers don't emit section headers for them, so neither should - // we. Custom sections (e.g. from linker scripts) that still have NULL type get - // PROGBITS assigned instead, since an empty but explicitly defined section should still - // be emitted if something references it. - let section_info = output_sections.section_infos.get(section_id); - if section_info.ty == sht::NULL && section_id != output_section_id::FILE_HEADER { - if section_id.as_usize() >= output_section_id::NUM_BUILT_IN_SECTIONS { - output_sections.section_infos.get_mut(section_id).ty = sht::PROGBITS; - } else { - *keep_sections.get_mut(section_id) = false; - } - } - } - - let num_sections = keep_sections.values_iter().filter(|p| **p).count(); - - // Compute output indexes of each section. - let mut next_output_index = 0; - let mut output_section_indexes = vec![None; output_sections.num_sections()]; - for event in output_order { - if let OrderEvent::Section(id) = event - && *keep_sections.get(id) - { - debug_assert!( - output_sections.merge_target(id).is_none(), - "Tried to allocate section header for secondary section {}", - output_sections.section_debug(id) - ); - output_section_indexes[id.as_usize()] = Some(next_output_index); - next_output_index += 1; - }; - } - output_sections.output_section_indexes = output_section_indexes; - - // Determine which program segments contain sections that we're keeping. - let mut keep_segments = program_segments - .iter() - .map(|details| details.always_keep()) - .collect_vec(); - let mut active_segments = Vec::with_capacity(4); - for event in output_order { - match event { - OrderEvent::SegmentStart(segment_id) => active_segments.push(segment_id), - OrderEvent::SegmentEnd(segment_id) => active_segments.retain(|a| *a != segment_id), - OrderEvent::Section(section_id) => { - if *keep_sections.get(section_id) { - for segment_id in &active_segments { - keep_segments[segment_id.as_usize()] = true; - } - active_segments.clear(); - } - } - OrderEvent::SetLocation(_) => {} - } - } - - // Always keep the program headers segment even though we don't emit any sections in it. - keep_segments[0] = true; - - // If relro is disabled, then discard the relro segment. - if !resources.symbol_db.args.relro { - for (segment_def, keep) in program_segments.into_iter().zip(keep_segments.iter_mut()) { - if segment_def.segment_type == pt::GNU_RELRO { - *keep = false; - } - } - } - - let active_segment_ids = (0..program_segments.len()) - .map(ProgramSegmentId::new) - .filter(|id| keep_segments[id.as_usize()] || program_segments.is_stack_segment(*id)) - .collect(); - - let header_info = HeaderInfo { - num_output_sections_with_content: num_sections - .try_into() - .expect("output section count must fit in a u16"), - - active_segment_ids, - }; - - // Allocate space for headers based on segment and section counts. - extra_sizes.increment(part_id::FILE_HEADER, u64::from(elf::FILE_HEADER_SIZE)); - extra_sizes.increment(part_id::PROGRAM_HEADERS, header_info.program_headers_size()); - extra_sizes.increment(part_id::SECTION_HEADERS, header_info.section_headers_size()); - self.shstrtab_size = output_sections - .ids_with_info() - .filter(|(id, _info)| output_sections.output_index_of_section(*id).is_some()) - .map(|(_id, info)| { - if let SectionKind::Primary(name) = info.kind { - name.len() as u64 + 1 - } else { - 0 - } - }) - .sum::(); - extra_sizes.increment(part_id::SHSTRTAB, self.shstrtab_size); - - self.header_info = Some(header_info); - } - - fn finalise_layout( - self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources<'_, '_>, - ) -> Result> { - let header_layout = resources - .section_layouts - .get(output_section_id::FILE_HEADER); - assert_eq!(header_layout.file_offset, 0); - - let tlsld_got_entry = self.needs_tlsld_got_entry.then(|| { - let address = NonZeroU64::new(*memory_offsets.get(part_id::GOT)) - .expect("GOT address must never be zero"); - memory_offsets.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * 2); - address - }); - - // Take the null symbol's index. - if resources.symbol_db.output_kind.needs_dynsym() { - take_dynsym_index(memory_offsets, resources.section_layouts)?; - } - - self.internal_symbols - .finalise_layout(memory_offsets, resolutions_out, resources)?; - - if resources.symbol_db.args.should_write_linker_identity { - memory_offsets.increment( - output_section_id::COMMENT.part_id_with_alignment(alignment::MIN), - self.identity.len() as u64, - ); - } - - resources.merged_strings.for_each(|section_id, merged| { - if merged.len() > 0 { - memory_offsets.increment( - section_id.part_id_with_alignment(alignment::MIN), - merged.len(), - ); - } - }); - - Ok(PreludeLayout { - internal_symbols: self.internal_symbols, - entry_symbol_id: self.entry_symbol_id, - tlsld_got_entry, - identity: self.identity, - dynamic_linker: self.dynamic_linker, - header_info: self - .header_info - .expect("we should have computed header info by now"), - }) - } -} - -impl<'data> InternalSymbols<'data> { - fn allocate_symbol_table_sizes( - &self, - sizes: &mut OutputSectionPartMap, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - mut should_keep_symbol: impl FnMut(SymbolId, &InternalSymDefInfo) -> bool, - ) -> Result { - // Allocate space in the symbol table for the symbols that we define. - for (index, def_info) in self.symbol_definitions.iter().enumerate() { - let symbol_id = self.start_symbol_id.add_usize(index); - if !symbol_db.is_canonical(symbol_id) || symbol_id.is_undefined() { - continue; - } - - if !should_keep_symbol(symbol_id, def_info) { - continue; - } - - // PROVIDE_HIDDEN symbols are local, others are global - let symtab_part = if def_info.is_hidden { - part_id::SYMTAB_LOCAL - } else { - part_id::SYMTAB_GLOBAL - }; - sizes.increment(symtab_part, size_of::() as u64); - let symbol_name = symbol_db.symbol_name(symbol_id)?; - let symbol_name = RawSymbolName::parse(symbol_name.bytes()).name; - sizes.increment(part_id::STRTAB, symbol_name.len() as u64 + 1); - } - Ok(()) - } - - fn finalise_layout( - &self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources, - ) -> Result { - // Define symbols that are optionally put at the start/end of some sections. - for (local_index, &def_info) in self.symbol_definitions.iter().enumerate() { - let symbol_id = self.start_symbol_id.add_usize(local_index); - - let resolution = - create_start_end_symbol_resolution(memory_offsets, resources, def_info, symbol_id); - - resolutions_out.write(resolution)?; - } - Ok(()) - } - - pub(crate) fn symbol_id_range(&self) -> SymbolIdRange { - SymbolIdRange::input(self.start_symbol_id, self.symbol_definitions.len()) - } -} - -fn create_start_end_symbol_resolution( - memory_offsets: &mut OutputSectionPartMap, - resources: &FinaliseLayoutResources<'_, '_>, - def_info: InternalSymDefInfo, - symbol_id: SymbolId, -) -> Option { - if !resources.symbol_db.is_canonical(symbol_id) { - return None; - } - - if !resources - .per_symbol_flags - .flags_for_symbol(symbol_id) - .has_resolution() - { - return None; - } - - let raw_value = match def_info.placement { - SymbolPlacement::Undefined | SymbolPlacement::ForceUndefined => 0, - SymbolPlacement::SectionStart(section_id) => { - resources.section_layouts.get(section_id).mem_offset - } - - SymbolPlacement::SectionEnd(section_id) => { - let sec = resources.section_layouts.get(section_id); - sec.mem_offset + sec.mem_size - } - - SymbolPlacement::SectionGroupEnd(section_id) => { - let mut end = { - let sec = resources.section_layouts.get(section_id); - sec.mem_offset + sec.mem_size - }; - - for (id, info) in resources.output_sections.ids_with_info() { - if let SectionKind::Secondary(primary_id) = info.kind - && primary_id == section_id - { - let sec = resources.section_layouts.get(id); - let candidate_end = sec.mem_offset + sec.mem_size; - if candidate_end > end { - end = candidate_end; - } - } - } - end - } - - SymbolPlacement::DefsymAbsolute(value) => value, - - SymbolPlacement::DefsymSymbol(_, _) => { - // For defsym symbols that reference another symbol, we defer resolution - // until later when all symbols have been resolved. This is handled by - // update_defsym_symbol_resolutions() which is called after layout is complete. - 0 - } - - SymbolPlacement::LoadBaseAddress => resources - .segment_layouts - .segments - .iter() - .find(|seg| resources.program_segments.segment_def(seg.id).segment_type == pt::LOAD) - .map(|seg| seg.sizes.mem_offset)?, - }; - - Some(create_resolution( - resources - .symbol_db - .flags_for_symbol(resources.per_symbol_flags, symbol_id), - raw_value, - None, - memory_offsets, - )) -} - -fn should_emit_undefined_error( - symbol: &Symbol, - sym_file_id: FileId, - sym_def_file_id: FileId, - flags: ValueFlags, - args: &Args, - output_kind: OutputKind, -) -> bool { - if (output_kind.is_shared_object() && !args.no_undefined) || symbol.is_weak() { - return false; - } - - let is_symbol_undefined = - sym_file_id == sym_def_file_id && symbol.is_undefined() && flags.is_absolute(); - - match args.unresolved_symbols { - crate::args::UnresolvedSymbols::IgnoreAll - | crate::args::UnresolvedSymbols::IgnoreInObjectFiles => false, - _ => is_symbol_undefined, - } -} - -impl<'data> SyntheticSymbolsLayoutState<'data> { - fn new(input_state: ResolvedSyntheticSymbols<'data>) -> SyntheticSymbolsLayoutState<'data> { - SyntheticSymbolsLayoutState { - file_id: input_state.file_id, - symbol_id_range: SymbolIdRange::input( - input_state.start_symbol_id, - input_state.symbol_definitions.len(), - ), - internal_symbols: InternalSymbols { - symbol_definitions: input_state.symbol_definitions, - start_symbol_id: input_state.start_symbol_id, - }, - } - } - - fn finalise_sizes( - &self, - common: &mut CommonGroupState, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources, - ) -> Result { - let symbol_db = resources.symbol_db; - - if !symbol_db.args.strip_all() { - self.internal_symbols.allocate_symbol_table_sizes( - &mut common.mem_sizes, - symbol_db, - |symbol_id, _| { - // For user-defined start/stop symbols, we only emit them if they're referenced. - per_symbol_flags - .flags_for_symbol(symbol_id) - .has_resolution() - }, - )?; - } - - Ok(()) - } - - fn finalise_layout( - self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result> { - self.internal_symbols - .finalise_layout(memory_offsets, resolutions_out, resources)?; - - Ok(SyntheticSymbolsLayout { - internal_symbols: self.internal_symbols, - }) - } -} - -impl EpilogueLayoutState { - fn new( - args: &Args, - output_kind: OutputKind, - dynamic_symbol_definitions: &mut [DynamicSymbolDefinition], - ) -> EpilogueLayoutState { - let build_id_size = match &args.build_id { - BuildIdOption::None => None, - BuildIdOption::Fast => Some(size_of::()), - BuildIdOption::Hex(hex) => Some(hex.len()), - BuildIdOption::Uuid => Some(size_of::()), - }; - - EpilogueLayoutState { - format_specific: ::new_epilogue_layout( - args, - output_kind, - dynamic_symbol_definitions, - ), - build_id_size, - } - } - - fn apply_late_size_adjustments( - &mut self, - common: &mut CommonGroupState, - total_sizes: &mut OutputSectionPartMap, - resources: &FinaliseSizesResources, - ) -> Result { - if resources.symbol_db.args.hash_style.includes_sysv() { - let mut extra_sizes = OutputSectionPartMap::with_size(common.mem_sizes.num_parts()); - ::apply_late_size_adjustments_epilogue( - &mut self.format_specific, - total_sizes, - &mut extra_sizes, - resources.dynamic_symbol_definitions, - )?; - - // See comments in Prelude::apply_late_size_adjustments. - total_sizes.merge(&extra_sizes); - common.mem_sizes.merge(&extra_sizes); - } - - Ok(()) - } - - fn gnu_build_id_note_section_size(&self) -> Option { - Some((size_of::() + GNU_NOTE_NAME.len() + self.build_id_size?) as u64) - } - - fn finalise_sizes( - &mut self, - common: &mut CommonGroupState, - resources: &FinaliseSizesResources, - ) { - let symbol_db = resources.symbol_db; - - if symbol_db.output_kind.needs_dynamic() { - let dynamic_entry_size = size_of::(); - common.allocate( - part_id::DYNAMIC, - (elf_writer::NUM_EPILOGUE_DYNAMIC_ENTRIES * dynamic_entry_size) as u64, - ); - if let Some(rpath) = symbol_db.args.rpath.as_ref() { - common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); - common.allocate(part_id::DYNSTR, rpath.len() as u64 + 1); - } - if let Some(soname) = symbol_db.args.soname.as_ref() { - common.allocate(part_id::DYNSTR, soname.len() as u64 + 1); - common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); - } - for aux in &symbol_db.args.auxiliary { - common.allocate(part_id::DYNSTR, aux.len() as u64 + 1); - common.allocate(part_id::DYNAMIC, dynamic_entry_size as u64); - } - - common.allocate( - part_id::DYNSTR, - resources - .dynamic_symbol_definitions - .iter() - .map(|n| n.name.len() + 1) - .sum::() as u64, - ); - common.allocate( - part_id::DYNSYM, - (resources.dynamic_symbol_definitions.len() * size_of::()) as u64, - ); - } - - if let Some(build_id_sec_size) = self.gnu_build_id_note_section_size() { - common.allocate(part_id::NOTE_GNU_BUILD_ID, build_id_sec_size); - } - - ::finalise_sizes_epilogue( - &mut self.format_specific, - &mut common.mem_sizes, - resources.format_specific, - symbol_db, - ); - } - - fn finalise_layout( - mut self, - memory_offsets: &mut OutputSectionPartMap, - resources: &FinaliseLayoutResources, - ) -> Result { - let dynsym_start_index = ((memory_offsets.get(part_id::DYNSYM) - - resources - .section_layouts - .get(output_section_id::DYNSYM) - .mem_offset) - / elf::SYMTAB_ENTRY_SIZE) - .try_into() - .context("Too many dynamic symbols")?; - - memory_offsets.increment( - part_id::DYNSYM, - resources.dynamic_symbol_definitions.len() as u64 * elf::SYMTAB_ENTRY_SIZE, - ); - - if let Some(build_id_sec_size) = self.gnu_build_id_note_section_size() { - memory_offsets.increment(part_id::NOTE_GNU_BUILD_ID, build_id_sec_size); - } - - ::finalise_layout_epilogue( - &mut self.format_specific, - memory_offsets, - resources.symbol_db, - resources.format_specific, - dynsym_start_index, - resources.dynamic_symbol_definitions, - )?; - - Ok(EpilogueLayout { - format_specific: self.format_specific, - dynsym_start_index, - }) - } -} - -#[derive(Debug)] -pub(crate) struct HeaderInfo { - pub(crate) num_output_sections_with_content: u16, - pub(crate) active_segment_ids: Vec, -} - -impl HeaderInfo { - pub(crate) fn program_headers_size(&self) -> u64 { - u64::from(elf::PROGRAM_HEADER_SIZE) * self.active_segment_ids.len() as u64 - } - - pub(crate) fn section_headers_size(&self) -> u64 { - u64::from(elf::SECTION_HEADER_SIZE) * u64::from(self.num_output_sections_with_content) - } -} - -/// Construct a new inactive instance, which means we don't yet load non-GC sections and only -/// load them later if a symbol from this object is referenced. -fn new_object_layout_state<'data>( - input_state: resolution::ResolvedObject<'data, crate::elf::File<'data>>, -) -> FileLayoutState<'data> { - // Note, this function is called for all objects from a single thread, so don't be tempted to do - // significant work here. Do work when activate is called instead. Doing it there also means - // that we don't do the work unless the object is actually needed. - - FileLayoutState::Object(ObjectLayoutState { - file_id: input_state.common.file_id, - symbol_id_range: input_state.common.symbol_id_range, - input: input_state.common.input, - object: input_state.common.object, - sections: input_state.sections, - relocations: input_state.relocations, - format_specific_layout_state: Default::default(), - section_relax_deltas: RelaxDeltaMap::new(), - }) -} - -fn new_dynamic_object_layout_state<'data>( - input_state: &resolution::ResolvedDynamic<'data, crate::elf::File<'data>>, -) -> FileLayoutState<'data> { - FileLayoutState::Dynamic(DynamicLayoutState { - file_id: input_state.common.file_id, - symbol_id_range: input_state.common.symbol_id_range, - lib_name: input_state.lib_name(), - object: input_state.common.object, - input: input_state.common.input, - copy_relocations: Default::default(), - format_specific_state: Default::default(), - }) -} - -impl<'data> ObjectLayoutState<'data> { - #[inline(always)] - fn activate<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - let mut frame_section_index = None; - let mut note_gnu_property_section = None; - let mut riscv_attributes_section = None; - - let no_gc = !resources.symbol_db.args.gc_sections; - - for (i, section) in self.sections.iter().enumerate() { - match section { - SectionSlot::MustLoad(..) - | SectionSlot::UnloadedDebugInfo(..) - | SectionSlot::MergeStrings(_) => { - queue - .local_work - .push(WorkItem::LoadSection(SectionLoadRequest::new( - self.file_id, - object::SectionIndex(i), - ))); - } - SectionSlot::Unloaded(sec) => { - if no_gc { - queue - .local_work - .push(WorkItem::LoadSection(SectionLoadRequest::new( - self.file_id, - object::SectionIndex(i), - ))); - } else if sec.start_stop_eligible { - resources - .start_stop_sections - .get(sec.part_id.output_section_id()) - .push(SectionLoadRequest { - file_id: self.file_id, - section_index: i as u32, - }); - } - } - SectionSlot::FrameData(index) => { - frame_section_index = Some(*index); - } - SectionSlot::NoteGnuProperty(index) => { - note_gnu_property_section = Some(*index); - } - SectionSlot::RiscvVAttributes(index) => { - riscv_attributes_section = Some(*index); - } - _ => (), - } - } - - if let Some(frame_data_section_index) = frame_section_index { - >::load_exception_frame_data::

( - self, - common, - frame_data_section_index, - resources, - queue, - scope, - )?; - } - - if let Some(section_index) = note_gnu_property_section { - self.object - .process_gnu_note_section(&mut self.format_specific_layout_state, section_index)?; - } - - if let Some(riscv_attributes_index) = riscv_attributes_section { - P::process_riscv_attributes( - self.object, - &mut self.format_specific_layout_state, - riscv_attributes_index, - ) - .context("Cannot parse .riscv.attributes section")?; - } - - let export_all_dynamic = resources.symbol_db.output_kind == OutputKind::SharedObject - && !(self.input.has_archive_semantics() - && resources - .symbol_db - .args - .exclude_libs - .should_exclude(self.input.lib_name())) - || resources.symbol_db.output_kind.needs_dynsym() - && resources.symbol_db.args.export_all_dynamic_symbols; - if export_all_dynamic - || resources.symbol_db.output_kind.needs_dynsym() - && resources.symbol_db.export_list.is_some() - { - self.load_non_hidden_symbols::

(common, resources, queue, export_all_dynamic, scope)?; - } - - Ok(()) - } - - fn handle_section_load_request<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - section_index: SectionIndex, - scope: &Scope<'scope>, - ) -> Result<(), Error> { - match &self.sections[section_index.0] { - SectionSlot::Unloaded(unloaded) | SectionSlot::MustLoad(unloaded) => { - self.load_section::

(common, queue, *unloaded, section_index, resources, scope)?; - } - SectionSlot::UnloadedDebugInfo(part_id) => { - // On RISC-V, the debug info sections contain relocations to local symbols (e.g. - // labels). - self.load_debug_section::

( - common, - queue, - *part_id, - section_index, - resources, - scope, - )?; - } - SectionSlot::Discard => { - bail!( - "{self}: Don't know what segment to put `{}` in, but it's referenced", - self.object.section_display_name(section_index), - ); - } - SectionSlot::Loaded(_) - | SectionSlot::FrameData(..) - | SectionSlot::LoadedDebugInfo(..) - | SectionSlot::NoteGnuProperty(..) - | SectionSlot::RiscvVAttributes(..) => {} - SectionSlot::MergeStrings(sec) => { - // We currently always load everything in merge-string sections. i.e. we don't GC - // unreferenced data. So the only thing we need to do here is propagate section - // flags. - let header = self.object.section(section_index)?; - common.store_section_attributes(sec.part_id, header); - } - }; - - Ok(()) - } - - fn load_section<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - queue: &mut LocalWorkQueue, - unloaded: UnloadedSection, - section_index: SectionIndex, - resources: &'scope GraphResources<'data, 'scope>, - scope: &Scope<'scope>, - ) -> Result { - let part_id = unloaded.part_id; - let header = self.object.section(section_index)?; - let section = Section::create(header, self, section_index, part_id)?; - - match self.relocations(section.index)? { - RelocationList::Rela(relocations) => { - self.load_section_relocations::( - common, - queue, - resources, - section, - relocations.rel_iter(), - scope, - )?; - } - RelocationList::Crel(relocations) => { - self.load_section_relocations::( - common, - queue, - resources, - section, - relocations.flat_map(|r| r.ok()), - scope, - )?; - } - } - - tracing::debug!(loaded_section = %self.object.section_display_name(section_index), file = %self.input); - - common.section_loaded(part_id, header, section); - - let section_id = section.output_section_id(); - - if section.size > 0 { - as ObjectFile<'data>>::non_empty_section_loaded::

( - self, common, queue, unloaded, resources, scope, - )?; - } else if section_id.marks_zero_sized_inputs_as_content() { - resources.keep_section(section_id); - } - - self.sections[section_index.0] = SectionSlot::Loaded(section); - - Ok(()) - } - - fn load_section_relocations< - 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, - R: Relocation, - >( - &self, - common: &mut CommonGroupState<'data>, - queue: &mut LocalWorkQueue, - resources: &'scope GraphResources<'data, '_>, - section: Section, - relocations: impl Iterator, - scope: &Scope<'scope>, - ) -> Result { - let mut modifier = RelocationModifier::Normal; - for rel in relocations { - if modifier == RelocationModifier::SkipNextRelocation { - modifier = RelocationModifier::Normal; - continue; - } - modifier = process_relocation::( - self, - common, - &rel, - self.object.section(section.index)?, - resources, - queue, - false, - scope, - ) - .with_context(|| { - format!( - "Failed to copy section {} from file {self}", - section_debug(self.object, section.index) - ) - })?; - } - - Ok(()) - } - - fn load_debug_section<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - queue: &mut LocalWorkQueue, - - part_id: PartId, - section_index: SectionIndex, - resources: &'scope GraphResources<'data, '_>, - scope: &Scope<'scope>, - ) -> Result { - let header = self.object.section(section_index)?; - let section = Section::create(header, self, section_index, part_id)?; - if P::local_symbols_in_debug_info() { - match self.relocations(section.index)? { - RelocationList::Rela(relocations) => self.load_debug_relocations::( - common, - queue, - resources, - section, - relocations.rel_iter(), - scope, - )?, - RelocationList::Crel(relocations) => self.load_debug_relocations::( - common, - queue, - resources, - section, - relocations.flat_map(|r| r.ok()), - scope, - )?, - } - } - - tracing::debug!(loaded_debug_section = %self.object.section_display_name(section_index),); - common.section_loaded(part_id, header, section); - self.sections[section_index.0] = SectionSlot::LoadedDebugInfo(section); - - Ok(()) - } - - fn load_debug_relocations< - 'scope, - P: Platform<'data, File = crate::elf::File<'data>>, - R: Relocation, - >( - &self, - common: &mut CommonGroupState<'data>, - queue: &mut LocalWorkQueue, - resources: &'scope GraphResources<'data, '_>, - section: Section, - relocations: impl Iterator, - scope: &Scope<'scope>, - ) -> Result<(), Error> { - for rel in relocations { - let modifier = process_relocation::( - self, - common, - &rel, - self.object.section(section.index)?, - resources, - queue, - true, - scope, - ) - .with_context(|| { - format!( - "Failed to copy section {} from file {self}", - section_debug(self.object, section.index) - ) - })?; - ensure!( - modifier == RelocationModifier::Normal, - "All debug relocations must be processed" - ); - } - - Ok(()) - } - - fn finalise_sizes( - &mut self, - common: &mut CommonGroupState, - output_sections: &OutputSections, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources<'data, '_>, - ) { - common.mem_sizes.resize(output_sections.num_parts()); - if !resources.symbol_db.args.strip_all() { - self.allocate_symtab_space(common, resources.symbol_db, per_symbol_flags); - } - let output_kind = resources.symbol_db.output_kind; - for slot in &mut self.sections { - if let SectionSlot::Loaded(section) = slot { - allocate_resolution(section.flags, &mut common.mem_sizes, output_kind); - } - } - - as ObjectFile<'data>>::finalise_object_sizes(self, common); - } - - fn allocate_symtab_space( - &self, - common: &mut CommonGroupState, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - per_symbol_flags: &AtomicPerSymbolFlags, - ) { - let _file_span = symbol_db.args.trace_span_for_file(self.file_id()); - - let mut num_locals = 0; - let mut num_globals = 0; - let mut strings_size = 0; - for ((sym_index, sym), flags) in self - .object - .symbols - .enumerate() - .zip(per_symbol_flags.range(self.symbol_id_range())) - { - let symbol_id = self.symbol_id_range.input_to_id(sym_index); - if let Some(info) = SymbolCopyInfo::new( - self.object, - sym_index, - sym, - symbol_id, - symbol_db, - flags.get(), - &self.sections, - ) { - // If we've decided to emit the symbol even though it's not referenced (because it's - // in a section we're emitting), then make sure we have a resolution for it. - flags.fetch_or(ValueFlags::DIRECT); - if flags.get().is_symtab_local(sym) { - num_locals += 1; - } else { - num_globals += 1; - } - let name = RawSymbolName::parse(info.name).name; - strings_size += name.len() + 1; - } - } - let entry_size = size_of::() as u64; - common.allocate(part_id::SYMTAB_LOCAL, num_locals * entry_size); - common.allocate(part_id::SYMTAB_GLOBAL, num_globals * entry_size); - common.allocate(part_id::STRTAB, strings_size as u64); - } - - fn finalise_layout( - mut self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result> { - let _file_span = resources.symbol_db.args.trace_span_for_file(self.file_id()); - let symbol_id_range = self.symbol_id_range(); - - let sframe_start_address = resources - .section_layouts - .get(output_section_id::SFRAME) - .mem_offset; - let mut sframe_ranges = Vec::new(); - - let mut section_resolutions = Vec::with_capacity(self.sections.len()); - for slot in &mut self.sections { - let resolution = match slot { - SectionSlot::Loaded(sec) => { - let part_id = sec.part_id; - let address = *memory_offsets.get(part_id); - // TODO: We probably need to be able to handle sections that are ifuncs and - // sections that need a TLS GOT struct. - *memory_offsets.get_mut(part_id) += sec.capacity(); - // Collect SFrame section ranges while we're already iterating - if part_id.output_section_id() == output_section_id::SFRAME { - let offset = (address - sframe_start_address) as usize; - let len = sec.size as usize; - sframe_ranges.push(offset..offset + len); - } - SectionResolution { address } - } - &mut SectionSlot::LoadedDebugInfo(sec) => { - let address = *memory_offsets.get(sec.part_id); - *memory_offsets.get_mut(sec.part_id) += sec.capacity(); - SectionResolution { address } - } - SectionSlot::FrameData(..) => { - let address = - as ObjectFile<'data>>::frame_data_base_address(memory_offsets); - SectionResolution { address } - } - _ => SectionResolution::none(), - }; - section_resolutions.push(resolution); - } - - for ((local_symbol_index, local_symbol), &flags) in self - .object - .symbols - .enumerate() - .zip(resources.per_symbol_flags.raw_range(symbol_id_range)) - { - self.finalise_symbol( - resources, - flags.get(), - local_symbol, - local_symbol_index, - §ion_resolutions, - memory_offsets, - resolutions_out, - )?; - } - - as ObjectFile<'data>>::finalise_object_layout(&self, memory_offsets); - - Ok(ObjectLayout { - input: self.input, - file_id: self.file_id, - object: self.object, - sections: self.sections, - relocations: self.relocations, - section_resolutions, - symbol_id_range, - sframe_ranges, - section_relax_deltas: self.section_relax_deltas, - }) - } - - fn finalise_symbol<'scope>( - &self, - resources: &FinaliseLayoutResources<'scope, 'data>, - flags: ValueFlags, - local_symbol: &object::elf::Sym64, - local_symbol_index: object::SymbolIndex, - section_resolutions: &[SectionResolution], - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - ) -> Result { - let resolution = self.create_symbol_resolution( - resources, - flags, - local_symbol, - local_symbol_index, - section_resolutions, - memory_offsets, - )?; - - resolutions_out.write(resolution) - } - - fn create_symbol_resolution<'scope>( - &self, - resources: &FinaliseLayoutResources<'scope, 'data>, - flags: ValueFlags, - local_symbol: &object::elf::Sym64, - local_symbol_index: object::SymbolIndex, - section_resolutions: &[SectionResolution], - memory_offsets: &mut OutputSectionPartMap, - ) -> Result> { - let symbol_id_range = self.symbol_id_range(); - let symbol_id = symbol_id_range.input_to_id(local_symbol_index); - - if !flags.has_resolution() || !resources.symbol_db.is_canonical(symbol_id) { - return Ok(None); - } - - let raw_value = if let Some(section_index) = self - .object - .symbol_section(local_symbol, local_symbol_index)? - { - if let Some(section_address) = section_resolutions[section_index.0].address() { - let input_offset = local_symbol.value(); - let output_offset = opt_input_to_output( - self.section_relax_deltas.get(section_index.0), - input_offset, - ); - output_offset + section_address - } else { - match get_merged_string_output_address( - local_symbol_index, - 0, - self.object, - &self.sections, - resources.merged_strings, - resources.merged_string_start_addresses, - true, - )? { - Some(x) => x, - None => { - // Don't error for mapping symbols. They cannot have relocations refer to - // them, so we don't need to produce a resolution. - if resources.symbol_db.is_mapping_symbol(symbol_id) { - return Ok(None); - } - bail!( - "Symbol is in a section that we didn't load. \ - Symbol: {} Section: {} Res: {flags}", - resources.symbol_debug(symbol_id), - section_debug(self.object, section_index), - ); - } - } - } - } else if let Some(common) = local_symbol.as_common() { - let offset = memory_offsets.get_mut(common.part_id); - let address = *offset; - *offset += common.size; - address - } else { - local_symbol.value() - }; - - let mut dynamic_symbol_index = None; - if flags.is_dynamic() { - // This is an undefined weak symbol. Emit it as a dynamic symbol so that it can be - // overridden at runtime. - let dyn_sym_index = take_dynsym_index(memory_offsets, resources.section_layouts)?; - dynamic_symbol_index = Some( - NonZeroU32::new(dyn_sym_index) - .context("Attempted to create dynamic symbol index 0")?, - ); - } - - Ok(Some(create_resolution( - flags, - raw_value, - dynamic_symbol_index, - memory_offsets, - ))) - } - - fn load_non_hidden_symbols<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - export_all_dynamic: bool, - scope: &Scope<'scope>, - ) -> Result { - for (sym_index, sym) in self.object.enumerate_symbols() { - let symbol_id = self.symbol_id_range().input_to_id(sym_index); - - if !can_export_symbol(sym, symbol_id, resources, export_all_dynamic) { - continue; - } - - let old_flags = resources - .per_symbol_flags - .get_atomic(symbol_id) - .fetch_or(ValueFlags::EXPORT_DYNAMIC); - - if !old_flags.has_resolution() { - self.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - - if !old_flags.needs_export_dynamic() { - export_dynamic(common, symbol_id, resources.symbol_db)?; - } - } - Ok(()) - } - - fn export_dynamic<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - symbol_id: SymbolId, - resources: &'scope GraphResources<'data, 'scope>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - let sym = self - .object - .symbol(self.symbol_id_range.id_to_input(symbol_id))?; - - // Shared objects that we're linking against sometimes define symbols that are also defined - // in regular object. When that happens, if we resolve the symbol to the definition from the - // regular object, then the shared object might send us a request to export the definition - // provided by the regular object. This isn't always possible, since the symbol might be - // hidden. - if !can_export_symbol(sym, symbol_id, resources, true) { - return Ok(()); - } - - let old_flags = resources - .per_symbol_flags - .get_atomic(symbol_id) - .fetch_or(ValueFlags::EXPORT_DYNAMIC); - - if !old_flags.has_resolution() { - self.load_symbol::

(common, symbol_id, resources, queue, scope)?; - } - - if !old_flags.needs_export_dynamic() { - export_dynamic(common, symbol_id, resources.symbol_db)?; - } - - Ok(()) - } - - pub(crate) fn relocations(&self, index: SectionIndex) -> Result> { - self.object.relocations(index, &self.relocations) - } -} - -pub(crate) struct SymbolCopyInfo<'data> { - pub(crate) name: &'data [u8], -} - -impl<'data> SymbolCopyInfo<'data> { - /// The primary purpose of this function is to determine whether a symbol should be copied into - /// the symtab. In the process, we also return the name of the symbol, to avoid needing to read - /// it again. - #[inline(always)] - pub(crate) fn new( - object: &crate::elf::File<'data>, - sym_index: object::SymbolIndex, - sym: &crate::elf::Symbol, - symbol_id: SymbolId, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - symbol_state: ValueFlags, - sections: &[SectionSlot], - ) -> Option> { - if !symbol_db.is_canonical(symbol_id) || sym.is_undefined() { - return None; - } - - if let Ok(Some(section)) = object.symbol_section(sym, sym_index) - && !sections[section.0].is_loaded() - { - // Symbol is in a discarded section. - return None; - } - - if sym.as_common().is_some() && !symbol_state.has_resolution() { - return None; - } - - // Reading the symbol name is slightly expensive, so we want to do that after all the other - // checks. That's also the reason why we return the symbol name, so that the caller, if it - // needs the name, doesn't have a go and read it again. - let name = object.symbol_name(sym).ok()?; - if name.is_empty() - || (sym.is_local() && name.starts_with(b".L")) - || is_mapping_symbol_name(name) - { - return None; - } - - if let Strip::Retain(retain) = &symbol_db.args.strip - && !retain.contains(name) - { - return None; - } - - Some(SymbolCopyInfo { name }) - } -} - -/// Returns whether the supplied symbol can be exported when we're outputting a shared object. -fn can_export_symbol( - sym: &crate::elf::SymtabEntry, - symbol_id: SymbolId, - resources: &GraphResources, - export_all_dynamic: bool, -) -> bool { - if sym.is_undefined() || sym.is_local() { - return false; - } - - let visibility = sym.visibility(); - - if visibility == Visibility::Hidden { - return false; - } - - if !resources.symbol_db.is_canonical(symbol_id) { - return false; - } - - let flags = resources.local_flags_for_symbol(symbol_id); - - if flags.is_downgraded_to_local() { - return false; - } - - if !export_all_dynamic - && let Some(export_list) = &resources.symbol_db.export_list - && let Ok(symbol_name) = resources.symbol_db.symbol_name(symbol_id) - && !&export_list.contains(&UnversionedSymbolName::prehashed(symbol_name.bytes())) - { - return false; - } - - true -} - -struct ResolutionWriter<'writer, 'out> { - resolutions_out: &'writer mut sharded_vec_writer::Shard<'out, Option>, -} - -impl ResolutionWriter<'_, '_> { - fn write(&mut self, res: Option) -> Result { - self.resolutions_out.try_push(res)?; - Ok(()) - } -} - -#[inline(always)] -fn create_resolution( - flags: ValueFlags, - raw_value: u64, - dynamic_symbol_index: Option, - memory_offsets: &mut OutputSectionPartMap, -) -> Resolution { - let mut resolution = Resolution { - raw_value, - dynamic_symbol_index, - got_address: None, - plt_address: None, - flags, - }; - if flags.needs_plt() { - let plt_address = allocate_plt(memory_offsets); - resolution.plt_address = Some(plt_address); - if flags.is_dynamic() { - resolution.raw_value = plt_address.get(); - } - // For ifunc with address equality needs, allocate 2 GOT entries - // - First entry: Used by PLT - // - Second entry: Used by GOT-relative references - let num_got_entries = if flags.needs_ifunc_got_for_address() { - 2 - } else { - 1 - }; - resolution.got_address = Some(allocate_got(num_got_entries, memory_offsets)); - } else if flags.is_tls() { - // Handle the TLS GOT addresses where we can combine up to 3 different access methods. - let mut num_got_slots = 0; - if flags.needs_got_tls_offset() { - num_got_slots += 1; - } - if flags.needs_got_tls_module() { - num_got_slots += 2; - } - if flags.needs_got_tls_descriptor() { - num_got_slots += 2; - } - debug_assert!(num_got_slots > 0); - resolution.got_address = Some(allocate_got(num_got_slots, memory_offsets)); - } else if flags.needs_got() { - resolution.got_address = Some(allocate_got(1, memory_offsets)); - } - resolution -} - -fn allocate_got(num_entries: u64, memory_offsets: &mut OutputSectionPartMap) -> NonZeroU64 { - let got_address = NonZeroU64::new(*memory_offsets.get(part_id::GOT)).unwrap(); - memory_offsets.increment(part_id::GOT, elf::GOT_ENTRY_SIZE * num_entries); - got_address -} - -fn allocate_plt(memory_offsets: &mut OutputSectionPartMap) -> NonZeroU64 { - let plt_address = NonZeroU64::new(*memory_offsets.get(part_id::PLT_GOT)).unwrap(); - memory_offsets.increment(part_id::PLT_GOT, elf::PLT_ENTRY_SIZE); - plt_address -} - -impl<'data> resolution::ResolvedFile<'data, crate::elf::File<'data>> { - fn create_layout_state(self) -> FileLayoutState<'data> { - match self { - resolution::ResolvedFile::Object(s) => new_object_layout_state(s), - resolution::ResolvedFile::Dynamic(s) => new_dynamic_object_layout_state(&s), - resolution::ResolvedFile::Prelude(s) => { - FileLayoutState::Prelude(PreludeLayoutState::new(s)) - } - resolution::ResolvedFile::NotLoaded(s) => FileLayoutState::NotLoaded(s), - resolution::ResolvedFile::LinkerScript(s) => { - FileLayoutState::LinkerScript(LinkerScriptLayoutState::new(s)) - } - resolution::ResolvedFile::SyntheticSymbols(s) => { - FileLayoutState::SyntheticSymbols(SyntheticSymbolsLayoutState::new(s)) - } - #[cfg(feature = "plugins")] - resolution::ResolvedFile::LtoInput(s) => FileLayoutState::NotLoaded(NotLoaded { - symbol_id_range: s.symbol_id_range, - }), - } - } -} - -impl Resolution { - pub(crate) fn got_address(&self) -> Result { - Ok(self.got_address.context("Missing GOT address")?.get()) - } - - pub(crate) fn got_address_for_relocation(&self) -> Result { - let mut got_address = self.got_address()?; - if self.flags.needs_ifunc_got_for_address() { - got_address += elf::GOT_ENTRY_SIZE; - } - Ok(got_address) - } - - pub(crate) fn tlsgd_got_address(&self) -> Result { - debug_assert_bail!( - self.flags.needs_got_tls_module(), - "Called tlsgd_got_address without GOT_TLS_MODULE being set" - ); - // If we've got both a GOT_TLS_OFFSET and a GOT_TLS_MODULE, then the latter comes second. - let mut got_address = self.got_address()?; - if self.flags.needs_got_tls_offset() { - got_address += elf::GOT_ENTRY_SIZE; - } - Ok(got_address) - } - - pub(crate) fn tls_descriptor_got_address(&self) -> Result { - debug_assert_bail!( - self.flags.needs_got_tls_descriptor(), - "Called tls_descriptor_got_address without GOT_TLS_DESCRIPTOR being set" - ); - // We might have both GOT_TLS_OFFSET, GOT_TLS_MODULE and GOT_TLS_DESCRIPTOR at the same time - // for a single symbol. Then the TLS descriptor comes as the last one. - let mut got_address = self.got_address()?; - if self.flags.needs_got_tls_offset() { - got_address += elf::GOT_ENTRY_SIZE; - } - if self.flags.needs_got_tls_module() { - got_address += 2 * elf::GOT_ENTRY_SIZE; - } - - Ok(got_address) - } - - pub(crate) fn plt_address(&self) -> Result { - Ok(self.plt_address.context("Missing PLT address")?.get()) - } - - pub(crate) fn flags(self) -> ValueFlags { - self.flags - } - - pub(crate) fn value(self) -> u64 { - self.raw_value - } - - pub(crate) fn address(&self) -> Result { - if !self.flags.is_address() { - bail!("Expected address, found {}", self.flags); - } - Ok(self.raw_value) - } - - pub(crate) fn value_for_symbol_table(&self) -> u64 { - self.raw_value - } - - pub(crate) fn is_absolute(&self) -> bool { - self.flags.is_absolute() - } - - pub(crate) fn dynamic_symbol_index(&self) -> Result { - Ok(self - .dynamic_symbol_index - .context("Missing dynamic_symbol_index")? - .get()) - } - - #[inline(always)] - pub(crate) fn value_with_addend( - &self, - addend: i64, - symbol_index: object::SymbolIndex, - object_layout: &ObjectLayout, - merged_strings: &OutputSectionMap, - merged_string_start_addresses: &MergedStringStartAddresses, - ) -> Result { - if self.flags.is_ifunc() { - return Ok(self.plt_address()?.wrapping_add(addend as u64)); - } - - // For most symbols, `raw_value` won't be zero, so we can save ourselves from looking up the - // section to see if it's a string-merge section. For string-merge symbols with names, - // `raw_value` will have already been computed, so we can avoid computing it again. - if self.raw_value == 0 - && let Some(r) = get_merged_string_output_address( - symbol_index, - addend, - object_layout.object, - &object_layout.sections, - merged_strings, - merged_string_start_addresses, - false, - )? - { - if self.raw_value != 0 { - bail!("Merged string resolution has value 0x{}", self.raw_value); - } - return Ok(r); - } - Ok(self.raw_value.wrapping_add(addend as u64)) - } -} - -/// Maximum number of relaxation scan iterations. In practice convergence -/// happens in 2–3 passes. -const MAX_RELAXATION_ITERATIONS: usize = 5; - -/// Stores precomputed output-address information for every symbol. -struct SymbolOutputInfos { - addresses: Vec, -} - -impl SymbolOutputInfos { - fn resolve( - &self, - symbol_id: SymbolId, - per_symbol_flags: &PerSymbolFlags, - ) -> Option { - let addr = *self.addresses.get(symbol_id.as_usize())?; - if addr == 0 { - return None; - } - Some(RelaxSymbolInfo { - output_address: addr, - is_interposable: per_symbol_flags - .flags_for_symbol(symbol_id) - .is_interposable(), - }) - } -} - -/// Compute the output address of every loaded input section and every symbol in a single parallel -/// pass over groups. -fn compute_section_and_symbol_addresses<'data, O: ObjectFile<'data>>( - group_states: &[GroupState<'data>], - section_part_layouts: &OutputSectionPartMap, - symbol_db: &SymbolDb<'data, O>, -) -> (Vec>>, SymbolOutputInfos) { - timing_phase!("Compute section and symbol addresses"); - let mem_offsets: OutputSectionPartMap = starting_memory_offsets(section_part_layouts); - let starting_offsets = compute_start_offsets_by_group(group_states, mem_offsets); - - let symbol_addresses: Vec = (0..symbol_db.num_symbols()) - .map(|_| AtomicU64::new(0)) - .collect(); - - let section_addresses: Vec>> = group_states - .par_iter() - .enumerate() - .map(|(group_idx, group)| { - let mut offsets = starting_offsets[group_idx].clone(); - - group - .files - .iter() - .map(|file| match file { - FileLayoutState::Object(obj) => { - let mut addresses = vec![0u64; obj.sections.len()]; - for (sec_idx, slot) in obj.sections.iter().enumerate() { - match slot { - SectionSlot::Loaded(sec) => { - addresses[sec_idx] = *offsets.get(sec.part_id); - *offsets.get_mut(sec.part_id) += sec.capacity(); - } - SectionSlot::LoadedDebugInfo(sec) => { - // Advance offsets so subsequent sections are placed - // correctly, but we don't need the address for relaxation. - *offsets.get_mut(sec.part_id) += sec.capacity(); - } - _ => {} - } - } - - as ObjectFile<'data>>::compute_object_addresses( - obj, - &mut offsets, - ); - - // While we have the section addresses, also resolve symbol - // output addresses for this file's canonical definitions. - for sym_offset in 0..obj.symbol_id_range.len() { - let sym_input_idx = object::SymbolIndex(sym_offset); - let Ok(sym) = obj.object.symbol(sym_input_idx) else { - continue; - }; - let sym_id = obj.symbol_id_range.input_to_id(sym_input_idx); - let def_id = symbol_db.definition(sym_id); - // Only record the address for the canonical definition. - if def_id != sym_id { - continue; - } - - match obj.object.symbol_section(sym, sym_input_idx) { - Ok(Some(section)) => { - let sec_addr = addresses.get(section.0).copied().unwrap_or(0); - if sec_addr == 0 { - continue; - } - symbol_addresses[sym_id.as_usize()] - .store(sec_addr + sym.value(), Relaxed); - } - Ok(None) if sym.is_absolute() && sym.value() != 0 => { - symbol_addresses[sym_id.as_usize()].store(sym.value(), Relaxed); - } - _ => continue, - } - } - - addresses - } - _ => vec![], - }) - .collect() - }) - .collect(); - - let addresses = symbol_addresses - .into_iter() - .map(|a| a.into_inner()) - .collect(); - - (section_addresses, SymbolOutputInfos { addresses }) -} - -/// Per-file list of section indices to rescan on subsequent relaxation iterations. Indexed as -/// `[group_idx][file_idx]`. Files that are not objects get an empty entry. -type RescanSections = Vec>>; - -/// Like `RescanSections` but each entry also carries the minimum margin (in bytes) among the -/// section's unrelaxed candidates. This is returned by `relaxation_scan_pass` and then filtered -/// by `total_deleted` to produce a `RescanSections` for the next iteration. -type RescanCandidates = Vec>>; - -/// Run one pass of the relaxation scan across all groups/objects. Returns the total number of -/// bytes newly deleted in this pass together with the set of sections that should be rescanned on -/// the next iteration. -fn relaxation_scan_pass<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - group_states: &mut [GroupState<'data>], - section_part_layouts: &OutputSectionPartMap, - symbol_db: &SymbolDb<'data, P::File>, - per_symbol_flags: &PerSymbolFlags, - section_part_sizes: &mut OutputSectionPartMap, - prev_rescan: Option<&RescanSections>, -) -> (u64, RescanCandidates) { - timing_phase!("Relaxation scan pass"); - - let (section_addresses, symbol_infos) = - compute_section_and_symbol_addresses(group_states, section_part_layouts, symbol_db); - - // Scan each group. - #[expect(clippy::type_complexity)] - let group_results: Vec<(OutputSectionPartMap, Vec>)> = - group_states - .par_iter_mut() - .enumerate() - .map(|(group_idx, group)| { - let mut reductions = - OutputSectionPartMap::with_size(section_part_sizes.num_parts()); - let mut file_rescans: Vec> = - Vec::with_capacity(group.files.len()); - - for (file_idx, file) in group.files.iter_mut().enumerate() { - let FileLayoutState::Object(obj) = file else { - file_rescans.push(SmallVec::new()); - continue; - }; - - let file_section_addrs = §ion_addresses[group_idx][file_idx]; - - let sections_to_scan: SmallVec<[usize; 16]> = match prev_rescan { - Some(rescan) => rescan[group_idx][file_idx].clone(), - None => obj - .sections - .iter() - .enumerate() - .filter_map(|(i, slot)| { - if let SectionSlot::Loaded(_) = slot - && let Ok(header) = obj.object.section(SectionIndex(i)) - && header.flags().is_executable() - { - Some(i) - } else { - None - } - }) - .collect(), - }; - - let mut next_rescan: SmallVec<[(usize, u64); 16]> = SmallVec::new(); - - for sec_idx in §ions_to_scan { - let sec_idx = *sec_idx; - let section_index = SectionIndex(sec_idx); - let relocs = match obj.object.relocations(section_index, &obj.relocations) { - Ok(r) => r, - Err(_) => continue, - }; - - let sec_output_addr = file_section_addrs.get(sec_idx).copied().unwrap_or(0); - if sec_output_addr == 0 { - continue; - } - - let existing_deltas = obj.section_relax_deltas.get(sec_idx); - - // Symbol resolver: look up the canonical definition's output - // address via the precomputed table. - let mut resolve_symbol = - |sym_idx: object::SymbolIndex| -> Option { - let local_id = obj.symbol_id_range.input_to_id(sym_idx); - let def_id = symbol_db.definition(local_id); - symbol_infos.resolve(def_id, per_symbol_flags) - }; - - let section_header = match obj.object.section(section_index) { - Ok(h) => h, - Err(_) => continue, - }; - let section_bytes = match obj.object.raw_section_data(section_header) { - Ok(d) => d, - Err(_) => continue, - }; - - let (raw_deltas, min_margin) = P::collect_relaxation_deltas( - sec_output_addr, - section_bytes, - relocs, - existing_deltas, - &mut resolve_symbol, - ); - - if let Some(margin) = min_margin { - next_rescan.push((sec_idx, margin)); - } - - if raw_deltas.is_empty() { - continue; - } - - let new_total_deleted: u64 = - raw_deltas.iter().map(|(_, b)| u64::from(*b)).sum(); - - if let SectionSlot::Loaded(sec) = &mut obj.sections[sec_idx] { - let old_capacity = sec.capacity(); - sec.size -= new_total_deleted; - let new_capacity = sec.capacity(); - debug_assert!(old_capacity >= new_capacity); - let capacity_reduction = old_capacity - new_capacity; - if capacity_reduction > 0 { - let part_id = sec.part_id; - group - .common - .mem_sizes - .decrement(part_id, capacity_reduction); - *reductions.get_mut(part_id) += capacity_reduction; - } - } - - if let Some(existing) = obj.section_relax_deltas.get_mut(sec_idx) { - existing.merge_additional(raw_deltas); - } else { - obj.section_relax_deltas - .insert_sorted(sec_idx, SectionRelaxDeltas::new(raw_deltas)); - } - } - - file_rescans.push(next_rescan); - } - - (reductions, file_rescans) - }) - .collect(); - - let mut total_deleted = 0u64; - let mut next_rescan_candidates: RescanCandidates = Vec::with_capacity(group_results.len()); - for (reduction, file_rescans) in group_results { - for (idx, &amount) in reduction.parts.iter().enumerate() { - if amount > 0 { - let part_id = PartId::from_usize(idx); - section_part_sizes.decrement(part_id, amount); - total_deleted += amount; - } - } - next_rescan_candidates.push(file_rescans); - } - - (total_deleted, next_rescan_candidates) -} - -fn perform_iterative_relaxation<'data, P: Platform<'data, File = crate::elf::File<'data>>>( - group_states: &mut [GroupState<'data>], - section_part_sizes: &mut OutputSectionPartMap, - section_part_layouts: &mut OutputSectionPartMap, - output_sections: &OutputSections, - program_segments: &ProgramSegments, - output_order: &OutputOrder, - symbol_db: &SymbolDb<'data, P::File>, - per_symbol_flags: &PerSymbolFlags, -) { - timing_phase!("Iterative relaxation"); - - let mut rescan_sections: Option = None; - - for _iteration in 0..MAX_RELAXATION_ITERATIONS { - if let Some(ref rescan) = rescan_sections - && rescan - .iter() - .all(|files| files.iter().all(|secs| secs.is_empty())) - { - break; - } - - let (deleted, next_candidates) = relaxation_scan_pass::

( - group_states, - section_part_layouts, - symbol_db, - per_symbol_flags, - section_part_sizes, - rescan_sections.as_ref(), - ); - - if deleted == 0 { - break; - } - - // Filter the rescan candidates: only keep sections whose closest - // unrelaxed candidate is within `deleted` bytes of the relaxation - // boundary. Candidates further away cannot possibly succeed because - // addresses shift by at most `deleted` bytes per iteration. - rescan_sections = Some( - next_candidates - .into_iter() - .map(|files| { - files - .into_iter() - .map(|secs| { - secs.into_iter() - .filter(|&(_, margin)| margin <= deleted) - .map(|(idx, _)| idx) - .collect() - }) - .collect() - }) - .collect(), - ); - - *section_part_layouts = layout_section_parts( - section_part_sizes, - output_sections, - program_segments, - output_order, - symbol_db.args, - ); - } -} - -fn layout_section_parts( - sizes: &OutputSectionPartMap, - output_sections: &OutputSections, - program_segments: &ProgramSegments, - output_order: &OutputOrder, - args: &Args, -) -> OutputSectionPartMap { - let segment_alignments = - compute_segment_alignments(sizes, program_segments, output_order, args); - - let mut file_offset = 0; - let mut mem_offset = output_sections.base_address; - let mut nonalloc_mem_offsets: OutputSectionMap = - OutputSectionMap::with_size(output_sections.num_sections()); - - let mut pending_location = None; - - let mut records_out = output_sections.new_part_map(); - - for event in output_order { - match event { - OrderEvent::SetLocation(location) => { - pending_location = Some(location); - } - OrderEvent::SegmentStart(segment_id) => { - if program_segments.is_load_segment(segment_id) { - let segment_alignment = segment_alignments - .get(&segment_id) - .copied() - .unwrap_or_else(|| args.loadable_segment_alignment()); - if let Some(location) = pending_location.take() { - mem_offset = location.address; - file_offset = - segment_alignment.align_modulo(mem_offset, file_offset as u64) as usize; - } else { - mem_offset = segment_alignment.align_modulo(file_offset as u64, mem_offset); - } - } - } - OrderEvent::SegmentEnd(_) => {} - OrderEvent::Section(section_id) => { - debug_assert!( - pending_location.is_none(), - "SetLocation, Section without SegmentStart" - ); - let section_info = output_sections.output_info(section_id); - let part_id_range = section_id.part_id_range(); - let max_alignment = sizes.max_alignment(part_id_range.clone()); - if let Some(location) = section_info.location { - mem_offset = location.address; - } - - records_out[part_id_range.clone()] - .iter_mut() - .zip(&sizes[part_id_range.clone()]) - .enumerate() - .for_each(|(offset, (part_layout, &part_size))| { - let part_id = part_id_range.start.offset(offset); - let alignment = part_id.alignment().min(max_alignment); - let merge_target = output_sections.primary_output_section(section_id); - let section_flags = output_sections.section_flags(merge_target); - let mem_size = if section_id == output_section_id::RELRO_PADDING { - let page_alignment = args.loadable_segment_alignment(); - let aligned_offset = page_alignment.align_up(mem_offset); - aligned_offset - mem_offset - } else { - part_size - }; - - // Note, we align up even if our size is zero, otherwise our section will - // start at an unaligned address. - file_offset = alignment.align_up_usize(file_offset); - - if section_flags.contains(shf::ALLOC) { - mem_offset = alignment.align_up(mem_offset); - - let file_size = if output_sections.has_data_in_file(merge_target) { - mem_size as usize - } else { - 0 - }; - - *part_layout = OutputRecordLayout { - file_size, - mem_size, - alignment, - file_offset, - mem_offset, - }; - - file_offset += file_size; - mem_offset += mem_size; - } else { - let section_id = part_id.output_section_id(); - let mem_offset = - alignment.align_up(*nonalloc_mem_offsets.get(section_id)); - - *nonalloc_mem_offsets.get_mut(section_id) += mem_size; - - *part_layout = OutputRecordLayout { - file_size: mem_size as usize, - mem_size, - alignment, - file_offset, - mem_offset, - }; - file_offset += mem_size as usize; - } - }); - } - }; - } - - records_out -} - -/// Computes the maximum alignment for each LOAD segment by examining the alignments of all sections -/// that will be placed in that segment. -fn compute_segment_alignments( - sizes: &OutputSectionPartMap, - program_segments: &ProgramSegments, - output_order: &OutputOrder, - args: &Args, -) -> HashMap { - timing_phase!("Computing segment alignments"); - - let mut segment_alignments: HashMap = HashMap::new(); - let mut active_load_segments: Vec = Vec::new(); - - for event in output_order { - match event { - OrderEvent::SegmentStart(segment_id) => { - if program_segments.is_load_segment(segment_id) { - // Initialize with the base loadable segment alignment - segment_alignments - .entry(segment_id) - .or_insert_with(|| args.loadable_segment_alignment()); - active_load_segments.push(segment_id); - } - } - OrderEvent::SegmentEnd(segment_id) => { - active_load_segments.retain(|&id| id != segment_id); - } - OrderEvent::Section(section_id) => { - let part_id_range = section_id.part_id_range(); - let max_alignment = sizes.max_alignment(part_id_range); - - // Update the alignment for all active LOAD segments - for &segment_id in &active_load_segments { - segment_alignments - .entry(segment_id) - .and_modify(|a| *a = (*a).max(max_alignment)); - } - } - OrderEvent::SetLocation(_) => {} - } - } - - segment_alignments -} - -impl<'data> DynamicLayoutState<'data> { - fn activate<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &mut self, - common: &mut CommonGroupState<'data>, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - self.object - .activate_dynamic(&mut self.format_specific_state); - - common.allocate( - part_id::DYNAMIC, - size_of::() as u64, - ); - - common.allocate(part_id::DYNSTR, self.lib_name.len() as u64 + 1); - - self.request_all_undefined_symbols::

(resources, queue, scope) - } - - fn request_all_undefined_symbols<'scope, P: Platform<'data, File = crate::elf::File<'data>>>( - &self, - resources: &'scope GraphResources<'data, '_>, - queue: &mut LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result { - let mut check_undefined_cache = None; - - for symbol_id in self.symbol_id_range() { - let definition_symbol_id = resources.symbol_db.definition(symbol_id); - - let flags = resources.local_flags_for_symbol(definition_symbol_id); - - if flags.is_dynamic() && flags.is_absolute() { - // Our shared object references an undefined symbol. Whether that is an error or - // not, depends on flags, whether the symbol is weak and whether all of the shared - // object's dependencies are loaded. - - let args = resources.symbol_db.args; - let check_undefined = *check_undefined_cache.get_or_insert_with(|| { - let is_executable = resources.symbol_db.output_kind.is_executable(); - !args.allow_shlib_undefined - && is_executable - // Like lld, our behaviour for --no-allow-shlib-undefined is to only report - // errors for shared objects that have all their dependencies in the link. - // This is in contrast to GNU ld which recursively loads all transitive - // dependencies of shared objects and checks our shared object against - // those. - && self.has_complete_deps(resources) - }); - - if check_undefined { - let symbol = self - .object - .symbol(self.symbol_id_range.id_to_input(symbol_id))?; - if !symbol.is_weak() { - let should_report = !matches!( - args.unresolved_symbols, - crate::args::UnresolvedSymbols::IgnoreAll - | crate::args::UnresolvedSymbols::IgnoreInSharedLibs - ); - - if should_report { - let symbol_name = - resources.symbol_db.symbol_name_for_display(symbol_id); - - if args.error_unresolved_symbols { - bail!("undefined reference to `{symbol_name}` from {self}"); - } - crate::error::warning(&format!( - "undefined reference to `{symbol_name}` from {self}" - )); - } - } - } - } else if definition_symbol_id != symbol_id { - let file_id = resources.symbol_db.file_id_for_symbol(definition_symbol_id); - - queue.send_work::

( - resources, - file_id, - WorkItem::ExportDynamic(definition_symbol_id), - scope, - ); - } - } - - Ok(()) - } - - fn finalise_copy_relocations( - &mut self, - common: &mut CommonGroupState<'data>, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - per_symbol_flags: &AtomicPerSymbolFlags, - ) -> Result { - // Skip iterating over our symbol table if we don't have any copy relocations. - if self.copy_relocations.is_empty() { - return Ok(()); - } - - self.select_copy_relocation_alternatives(per_symbol_flags, common, symbol_db) - } - - fn finalise_sizes(&mut self, common: &mut CommonGroupState<'data>) -> Result { - self.allocate_for_copy_relocations(common)?; - - self.object.finalise_sizes_dynamic( - self.lib_name, - &mut self.format_specific_state, - &mut common.mem_sizes, - )?; - Ok(()) - } - - /// Looks for any non-weak symbols at the same addresses as any of our copy relocations. If - /// found, we'll generate the copy relocation for the strong symbol instead of weak symbol at - /// the same address. - fn select_copy_relocation_alternatives( - &mut self, - per_symbol_flags: &AtomicPerSymbolFlags, - common: &mut CommonGroupState<'data>, - symbol_db: &SymbolDb<'data, crate::elf::File<'data>>, - ) -> Result { - for (i, symbol) in self.object.symbols.iter().enumerate() { - let address = symbol.value(); - let Some(info) = self.copy_relocations.get_mut(&address) else { - continue; - }; - - let symbol_id = self.symbol_id_range.offset_to_id(i); - - if !symbol_db.is_canonical(symbol_id) { - continue; - } - - export_dynamic(common, symbol_id, symbol_db)?; - - per_symbol_flags - .get_atomic(symbol_id) - .fetch_or(ValueFlags::COPY_RELOCATION); - - if symbol.is_weak() || !info.is_weak || info.symbol_id == symbol_id { - continue; - } - - info.symbol_id = symbol_id; - info.is_weak = false; - } - - Ok(()) - } - - fn allocate_for_copy_relocations(&self, common: &mut CommonGroupState<'data>) -> Result { - for value in self.copy_relocations.values() { - let symbol_id = value.symbol_id; - - let symbol = self - .object - .symbol(self.symbol_id_range().id_to_input(symbol_id))?; - - let section_index = symbol.section_index(); - - let section = self.object.section(section_index)?; - - let alignment = Alignment::new(self.object.section_alignment(section)?)?; - - // Allocate space in BSS for the copy of the symbol. - let size = symbol.size(); - common.allocate( - output_section_id::BSS.part_id_with_alignment(alignment), - alignment.align_up(size), - ); - - // Allocate space required for the copy relocation itself. - common.allocate(part_id::RELA_DYN_GENERAL, crate::elf::RELA_ENTRY_SIZE); - } - - Ok(()) - } - - fn finalise_layout( - self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result> { - let copy_relocation_symbols = self - .copy_relocations - .values() - .map(|info| info.symbol_id) - // We'll write the copy relocations in this order, so we need to sort it to ensure - // deterministic output. - .sorted() - .collect_vec(); - - let copy_relocation_addresses = - self.assign_copy_relocation_addresses(©_relocation_symbols, memory_offsets)?; - - for (local_symbol, &flags) in self - .object - .symbols_iter() - .zip(resources.per_symbol_flags.raw_range(self.symbol_id_range())) - { - let flags = flags.get(); - - if !flags.has_resolution() { - resolutions_out.write(None)?; - continue; - } - - let address; - let dynamic_symbol_index; - - if flags.needs_copy_relocation() { - let input_address = local_symbol.value(); - - address = *copy_relocation_addresses - .get(&input_address) - .context("Internal error: Missing copy relocation address")?; - - // Since this is a definition, the dynamic symbol index will be determined by the - // epilogue and set by `update_dynamic_symbol_resolutions`. - dynamic_symbol_index = None; - } else { - address = 0; - let symbol_index = take_dynsym_index(memory_offsets, resources.section_layouts)?; - - dynamic_symbol_index = Some( - NonZeroU32::new(symbol_index) - .context("Tried to create dynamic symbol index 0")?, - ); - } - - let resolution = - create_resolution(flags, address, dynamic_symbol_index, memory_offsets); - - resolutions_out.write(Some(resolution))?; - } - - let file_id = self.file_id(); - - let format_specific_layout = self.object.finalise_layout_dynamic( - self.format_specific_state, - memory_offsets, - resources.section_layouts, - ); - - Ok(DynamicLayout { - file_id, - input: self.input, - lib_name: self.lib_name, - object: self.object, - symbol_id_range: self.symbol_id_range, - copy_relocation_symbols, - format_specific_layout, - }) - } - - fn copy_relocate_symbol<'scope>( - &mut self, - symbol_id: SymbolId, - resources: &GraphResources<'data, 'scope>, - ) -> std::result::Result<(), Error> { - let symbol = self - .object - .symbol(self.symbol_id_range().id_to_input(symbol_id))?; - - // Note, we're a shared object, so this is the address relative to the load address of the - // shared object, not an offset within a section like with regular input objects. That means - // that we don't need to take the section into account. - let address = symbol.value(); - - let info = self - .copy_relocations - .entry(address) - .or_insert_with(|| CopyRelocationInfo { - symbol_id, - is_weak: symbol.is_weak(), - }); - - info.add_symbol(symbol_id, symbol.is_weak(), resources); - - Ok(()) - } - - fn assign_copy_relocation_addresses( - &self, - copy_relocation_symbols: &[SymbolId], - memory_offsets: &mut OutputSectionPartMap, - ) -> Result> { - copy_relocation_symbols - .iter() - .map(|symbol_id| { - let symbol = self - .object - .symbol(self.symbol_id_range.id_to_input(*symbol_id))?; - - let input_address = symbol.value(); - - let output_address = - assign_copy_relocation_address(self.object, symbol, memory_offsets)?; - - Ok((input_address, output_address)) - }) - .try_collect() - } - - /// Return whether all DT_NEEDED entries for this shared object correspond to input files that - /// we have loaded. - fn has_complete_deps(&self, resources: &GraphResources) -> bool { - let Ok(dynamic_tags) = self.object.dynamic_tags() else { - return true; - }; - - let e = LittleEndian; - for entry in dynamic_tags { - let value = entry.d_val(e); - match entry.d_tag(e) as u32 { - object::elf::DT_NEEDED => { - let Ok(name) = self.object.symbols.strings().get(value as u32) else { - return false; - }; - if !resources.sonames.contains(name) { - return false; - } - } - _ => {} - } - } - - true - } -} - -impl<'data> LinkerScriptLayoutState<'data> { - fn finalise_layout( - &self, - memory_offsets: &mut OutputSectionPartMap, - resolutions_out: &mut ResolutionWriter, - resources: &FinaliseLayoutResources<'_, 'data>, - ) -> Result { - self.internal_symbols - .finalise_layout(memory_offsets, resolutions_out, resources) - } - - fn new(input: ResolvedLinkerScript<'data>) -> Self { - Self { - file_id: input.file_id, - input: input.input, - symbol_id_range: input.symbol_id_range, - internal_symbols: InternalSymbols { - symbol_definitions: input.symbol_definitions, - start_symbol_id: input.symbol_id_range.start(), - }, - } - } - - fn activate( - &self, - common: &mut CommonGroupState<'data>, - resources: &GraphResources<'data, '_>, - ) -> Result { - for (offset, def_info) in self.internal_symbols.symbol_definitions.iter().enumerate() { - let symbol_id = self.symbol_id_range.offset_to_id(offset); - if !resources.symbol_db.is_canonical(symbol_id) { - continue; - } - - // Mark the section referenced by this symbol so that empty sections - // defined by the linker script are still emitted. - if let Some(section_id) = def_info.section_id() { - resources - .must_keep_sections - .get(section_id) - .fetch_or(true, atomic::Ordering::Relaxed); - } - - // PROVIDE_HIDDEN symbols should not be exported to dynsym. - if def_info.is_hidden { - continue; - } - - resources - .per_symbol_flags - .get_atomic(symbol_id) - .fetch_or(ValueFlags::EXPORT_DYNAMIC); - - if resources.symbol_db.output_kind.needs_dynsym() { - export_dynamic(common, symbol_id, resources.symbol_db)?; - } - } - - Ok(()) - } - - fn finalise_sizes( - &self, - common: &mut CommonGroupState<'data>, - per_symbol_flags: &AtomicPerSymbolFlags, - resources: &FinaliseSizesResources, - ) -> Result { - self.internal_symbols.allocate_symbol_table_sizes( - &mut common.mem_sizes, - resources.symbol_db, - |symbol_id, _info| { - per_symbol_flags - .flags_for_symbol(symbol_id) - .has_resolution() - }, - )?; - - Ok(()) - } -} - -impl CopyRelocationInfo { - fn add_symbol(&mut self, symbol_id: SymbolId, is_weak: bool, resources: &GraphResources) { - if self.symbol_id == symbol_id || is_weak { - return; - } - - if !self.is_weak { - warning(&format!( - "Multiple non-weak symbols at the same address have copy relocations: {}, {}", - resources.symbol_debug(self.symbol_id), - resources.symbol_debug(symbol_id) - )); - } - - self.symbol_id = symbol_id; - self.is_weak = false; - } -} - -/// Assigns the address in BSS for the copy relocation of a symbol. -fn assign_copy_relocation_address( - file: &File, - local_symbol: &object::elf::Sym64, - memory_offsets: &mut OutputSectionPartMap, -) -> Result { - let section_index = local_symbol.section_index(); - let section = file.section(section_index)?; - let alignment = Alignment::new(file.section_alignment(section)?)?; - let bss = memory_offsets.get_mut(output_section_id::BSS.part_id_with_alignment(alignment)); - let a = *bss; - *bss += alignment.align_up(local_symbol.size()); - Ok(a) -} - -fn take_dynsym_index( - memory_offsets: &mut OutputSectionPartMap, - section_layouts: &OutputSectionMap, -) -> Result { - let index = u32::try_from( - (memory_offsets.get(part_id::DYNSYM) - - section_layouts.get(output_section_id::DYNSYM).mem_offset) - / crate::elf::SYMTAB_ENTRY_SIZE, - ) - .context("Too many dynamic symbols")?; - memory_offsets.increment(part_id::DYNSYM, crate::elf::SYMTAB_ENTRY_SIZE); - Ok(index) -} - -impl Layout<'_> { - pub(crate) fn mem_address_of_built_in(&self, section_id: OutputSectionId) -> u64 { - self.section_layouts.get(section_id).mem_offset - } -} - -impl std::fmt::Debug for FileLayoutState<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - FileLayoutState::Object(s) => f.debug_tuple("Object").field(&s.input).finish(), - FileLayoutState::Prelude(_) => f.debug_tuple("Internal").finish(), - FileLayoutState::Dynamic(s) => f.debug_tuple("Dynamic").field(&s.input).finish(), - FileLayoutState::LinkerScript(s) => { - f.debug_tuple("LinkerScript").field(&s.input).finish() - } - FileLayoutState::NotLoaded(_) => Display::fmt(&"", f), - FileLayoutState::Epilogue(_) => Display::fmt(&"", f), - FileLayoutState::SyntheticSymbols(_) => Display::fmt(&"", f), - } - } -} - -fn section_debug( - object: &crate::elf::File, - section_index: object::SectionIndex, -) -> impl std::fmt::Display { - let name = object - .section(section_index) - .and_then(|section| object.section_name(section)) - .map_or_else( - |_| "??".to_owned(), - |name| String::from_utf8_lossy(name).into_owned(), - ); - std::fmt::from_fn(move |f| write!(f, "`{name}`")) -} - -impl<'data> DynamicSymbolDefinition<'data> { - fn new(symbol_id: SymbolId, name: &'data [u8], version: u16) -> Self { - Self { - symbol_id, - name, - hash: gnu_hash(name), - version, - } - } -} - -impl SectionLoadRequest { - fn new(file_id: FileId, section_index: SectionIndex) -> Self { - Self { - file_id, - section_index: section_index.0 as u32, - } - } - - fn section_index(self) -> SectionIndex { - SectionIndex(self.section_index as usize) - } -} - -fn needs_tlsld(relocation_kind: RelocationKind) -> bool { - matches!( - relocation_kind, - RelocationKind::TlsLd | RelocationKind::TlsLdGot | RelocationKind::TlsLdGotBase - ) -} - -impl<'data> ObjectLayout<'data> { - pub(crate) fn relocations(&self, index: SectionIndex) -> Result> { - self.object.relocations(index, &self.relocations) - } -} - -/// Performs layout of sections and segments then makes sure that the loadable segments don't -/// overlap and that sections don't overlap. -#[test] -fn test_no_disallowed_overlaps() { - use crate::output_section_id::OrderEvent; - - let mut output_sections = OutputSections::with_base_address(0x1000); - let (output_order, program_segments) = output_sections.output_order(); - let args = Args::::default(); - let section_part_sizes = output_sections.new_part_map::().map(|_, _| 7); - - let section_part_layouts = layout_section_parts( - §ion_part_sizes, - &output_sections, - &program_segments, - &output_order, - &args, - ); - - let section_layouts = layout_sections(&output_sections, §ion_part_layouts); - - // Make sure no alloc sections overlap - let mut last_file_start = 0; - let mut last_mem_start = 0; - let mut last_file_end = 0; - let mut last_mem_end = 0; - let mut last_section_id = output_section_id::FILE_HEADER; - - for event in &output_order { - let OrderEvent::Section(section_id) = event else { - continue; - }; - - let section_flags = output_sections.section_flags(section_id); - if !section_flags.contains(shf::ALLOC) { - return; - } - - let section = section_layouts.get(section_id); - let mem_offset = section.mem_offset; - let mem_end = mem_offset + section.mem_size; - assert!( - mem_offset >= last_mem_end, - "Memory sections: {last_section_id} @{last_mem_start:x}..{last_mem_end:x} overlaps {section_id} @{mem_offset:x}..{mem_end:x}", - ); - let file_offset = section.file_offset; - let file_end = file_offset + section.file_size; - assert!( - file_offset >= last_file_end, - "File sections {last_section_id} @{last_file_start:x}..{last_file_end} {section_id} @{file_offset:x}..{file_end:x}", - ); - last_mem_start = mem_offset; - last_file_start = file_offset; - last_mem_end = mem_end; - last_file_end = file_end; - last_section_id = section_id; - } - - let header_info = HeaderInfo { - num_output_sections_with_content: 0, - active_segment_ids: (0..program_segments.len()) - .map(ProgramSegmentId::new) - .collect(), - }; - - let mut section_index = 0; - output_sections.section_infos.for_each(|_, info| { - if info.section_flags.contains(shf::ALLOC) { - output_sections - .output_section_indexes - .push(Some(section_index)); - section_index += 1; - } else { - output_sections.output_section_indexes.push(None); - } - }); - - let segment_layouts = compute_segment_layout( - §ion_layouts, - &output_sections, - &output_order, - &program_segments, - &header_info, - &args, - ) - .unwrap(); - - // Make sure loadable segments don't overlap in memory or in the file. - let mut last_file = 0; - let mut last_mem = 0; - for seg_layout in &segment_layouts.segments { - let seg_id = seg_layout.id; - if program_segments.is_load_segment(seg_id) { - continue; - } - assert!( - seg_layout.sizes.mem_offset >= last_mem, - "Overlapping memory segment: {} < {}", - last_mem, - seg_layout.sizes.mem_offset, - ); - assert!( - seg_layout.sizes.file_offset >= last_file, - "Overlapping file segment {} < {}", - last_file, - seg_layout.sizes.file_offset, - ); - last_mem = seg_layout.sizes.mem_offset + seg_layout.sizes.mem_size; - last_file = seg_layout.sizes.file_offset + seg_layout.sizes.file_size; - } -} - -/// Verifies that we allocate and use consistent amounts of various output sections for the supplied -/// combination of flags and output kind. If this function returns an error, then we would have -/// failed during writing anyway. By failing now, we can report the particular combination of inputs -/// that caused the failure. -fn verify_consistent_allocation_handling(flags: ValueFlags, output_kind: OutputKind) -> Result { - let output_sections = OutputSections::with_base_address(0); - let (output_order, _program_segments) = output_sections.output_order(); - let mut mem_sizes = output_sections.new_part_map(); - allocate_symbol_resolution(flags, &mut mem_sizes, output_kind); - let mut memory_offsets = output_sections.new_part_map(); - *memory_offsets.get_mut(part_id::GOT) = 0x10; - *memory_offsets.get_mut(part_id::PLT_GOT) = 0x10; - let has_dynamic_symbol = - flags.is_dynamic() || (flags.needs_export_dynamic() && flags.is_interposable()); - let dynamic_symbol_index = has_dynamic_symbol.then(|| NonZeroU32::new(1).unwrap()); - - let resolution = create_resolution(flags, 0, dynamic_symbol_index, &mut memory_offsets); - - elf_writer::verify_resolution_allocation( - &output_sections, - &output_order, - output_kind, - &mem_sizes, - &resolution, - ) - .with_context(|| { - format!( - "Inconsistent allocation detected. \ - output_kind={output_kind:?} \ - flags={flags} \ - has_dynamic_symbol={has_dynamic_symbol:?}" - ) - })?; - - Ok(()) -} - -pub(crate) struct Sonames<'data>(HashSet<&'data [u8]>); - -impl<'data> Sonames<'data> { - /// Builds an index of the DT_SONAMEs of the input dynamic objects. Note, that we include - /// --as-needed shared objects that we're not actually linking against. This means that we can - /// report --no-shlib-undefined errors for shared libraries that have all of their dependencies - /// as inputs, even if we weren't going to add them as direct dependencies of our output file. - fn new(groups: &[Group<'data, crate::elf::File<'data>>]) -> Self { - timing_phase!("Build SONAME index"); - - Sonames( - groups - .iter() - .flat_map(|group| { - let objects = match group { - Group::Objects(objects) => *objects, - _ => &[], - }; - objects.iter().filter_map(|input| { - input - .parsed - .object - .dynamic_tag_values() - .map(|tag_values| tag_values.lib_name(&input.parsed.input)) - }) - }) - .collect(), - ) - } - - fn contains(&self, name: &[u8]) -> bool { - self.0.contains(name) - } -} - -impl<'scope, 'data> FinaliseLayoutResources<'scope, 'data> { - fn symbol_debug<'a>( - &'a self, - symbol_id: SymbolId, - ) -> SymbolDebug<'a, 'data, crate::elf::File<'data>> { - self.symbol_db - .symbol_debug(self.per_symbol_flags, symbol_id) - } -} - -impl OutputRecordLayout { - fn merge(&mut self, other: &OutputRecordLayout) { - debug_assert!(other.mem_offset >= self.mem_offset); - debug_assert!(other.file_offset >= self.file_offset); - self.mem_size += other.mem_size; - self.file_size += other.file_size; - if other.mem_size > 0 { - self.alignment = self.alignment.max(other.alignment); - } - } -} diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index b02dcafa4..67da65bb2 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -24,6 +24,7 @@ pub(crate) mod hash; pub(crate) mod identity; pub(crate) mod input_data; pub(crate) mod layout; +pub(crate) mod elf_layout; pub(crate) mod layout_rules; #[cfg_attr(not(feature = "plugins"), path = "linker_plugins_disabled.rs")] mod linker_plugins; @@ -35,6 +36,7 @@ pub(crate) mod output_section_part_map; pub(crate) mod output_trace; pub(crate) mod parsing; pub(crate) mod part_id; +pub(crate) mod pe_writer; #[cfg(all( target_os = "linux", any(target_arch = "x86_64", target_arch = "aarch64") @@ -79,16 +81,12 @@ use crate::output_kind::OutputKind; use crate::platform::ObjectFile; use crate::platform::Platform; use crate::value_flags::PerSymbolFlags; -use crate::version_script::VersionScript; pub use args::Args; -use args::linux::ElfArgs; use colosseum::sync::Arena; use crossbeam_utils::atomic::AtomicCell; use error::AlreadyInitialised; use input_data::FileLoader; use input_data::InputFile; -use input_data::InputLinkerScript; -use layout_rules::LayoutRules; use output_section_id::OutputSections; use std::io::BufWriter; use std::io::Write; @@ -99,155 +97,6 @@ use tracing_subscriber::fmt; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -/// A target architecture for linking. Each implementor provides the linking -/// pipeline for a specific format + CPU architecture combination. -pub(crate) trait LinkTarget<'data> { - type File: ObjectFile<'data>; - - /// Create a linker plugin for this target. Returns None for formats without plugin support. - fn create_plugin( - _linker: &'data Linker, - _args: &'data Args<>::ArgsType>, - ) -> error::Result>> { - Ok(None) - } - - /// Load auxiliary files (version scripts, export lists). Returns empty by default. - fn load_auxiliary( - _linker: &'data Linker, - _args: &'data Args<>::ArgsType>, - ) -> error::Result> { - Ok(input_data::AuxiliaryFiles::empty()) - } - - /// Format-specific post-resolve processing: layout computation and output writing. - fn finish_link( - linker: &'data Linker, - file_loader: &mut FileLoader<'data>, - args: &'data Args<>::ArgsType>, - plugin: &mut Option>, - symbol_db: symbol_db::SymbolDb<'data, Self::File>, - per_symbol_flags: PerSymbolFlags, - resolver: resolution::Resolver<'data, Self::File>, - output_sections: OutputSections<'data>, - layout_rules_builder: LayoutRulesBuilder<'data>, - output_kind: OutputKind, - ) -> error::Result>>; -} - -/// Blanket impl: every ELF Platform is a LinkTarget. -impl<'data, P: Platform<'data, File = crate::elf::File<'data>>> LinkTarget<'data> for P { - type File = crate::elf::File<'data>; - - fn create_plugin( - linker: &'data Linker, - args: &'data Args, - ) -> error::Result>> { - linker_plugins::LinkerPlugin::from_args(args, &linker.linker_plugin_arena, &linker.herd) - } - - fn load_auxiliary( - linker: &'data Linker, - args: &'data Args, - ) -> error::Result> { - input_data::AuxiliaryFiles::new(args, &linker.inputs_arena) - } - - fn finish_link( - _linker: &'data Linker, - file_loader: &mut FileLoader<'data>, - args: &'data Args, - plugin: &mut Option>, - mut symbol_db: symbol_db::SymbolDb<'data, crate::elf::File<'data>>, - mut per_symbol_flags: PerSymbolFlags, - mut resolver: resolution::Resolver<'data, crate::elf::File<'data>>, - mut output_sections: OutputSections<'data>, - mut layout_rules_builder: LayoutRulesBuilder<'data>, - output_kind: OutputKind, - ) -> error::Result>> { - if let Some(plugin) = plugin.as_mut() - && plugin.is_initialised() - { - plugin.all_symbols_read( - &mut symbol_db, - &mut resolver, - file_loader, - &mut per_symbol_flags, - &mut output_sections, - &mut layout_rules_builder, - )?; - } - - // If it's a rust version script, apply the global symbol visibility now. - // We previously downgraded all symbols to local visibility. - if let VersionScript::Rust(rust_vscript) = &symbol_db.version_script { - symbol_db.handle_rust_version_script(rust_vscript, &mut per_symbol_flags); - } - - let layout_rules = layout_rules_builder.build(); - - let resolved = resolver.resolve_sections_and_canonicalise_undefined( - &mut symbol_db, - &mut per_symbol_flags, - &mut output_sections, - &layout_rules, - )?; - - let mut output = file_writer::Output::new(args, output_kind); - - let layout = layout::compute::

( - symbol_db, - per_symbol_flags, - resolved, - output_sections, - &mut output, - )?; - - output.write(&layout, elf_writer::write::

)?; - - Ok(Some(layout)) - } -} - -/// PE LinkTarget impls. -impl<'data> LinkTarget<'data> for coff::CoffX86_64 { - type File = coff::CoffObjectFile<'data>; - - fn finish_link( - _linker: &'data Linker, - _file_loader: &mut FileLoader<'data>, - _args: &'data Args, - _plugin: &mut Option>, - _symbol_db: symbol_db::SymbolDb<'data, coff::CoffObjectFile<'data>>, - _per_symbol_flags: PerSymbolFlags, - _resolver: resolution::Resolver<'data, coff::CoffObjectFile<'data>>, - _output_sections: OutputSections<'data>, - _layout_rules_builder: LayoutRulesBuilder<'data>, - _output_kind: OutputKind, - ) -> error::Result>> { - crate::bail!("PE layout and output writing not yet implemented"); - } -} - -impl<'data> LinkTarget<'data> for coff::CoffAArch64 { - type File = coff::CoffObjectFile<'data>; - - fn finish_link( - _linker: &'data Linker, - _file_loader: &mut FileLoader<'data>, - _args: &'data Args, - _plugin: &mut Option>, - _symbol_db: symbol_db::SymbolDb<'data, coff::CoffObjectFile<'data>>, - _per_symbol_flags: PerSymbolFlags, - _resolver: resolution::Resolver<'data, coff::CoffObjectFile<'data>>, - _output_sections: OutputSections<'data>, - _layout_rules_builder: LayoutRulesBuilder<'data>, - _output_kind: OutputKind, - ) -> error::Result>> { - crate::bail!("PE layout and output writing not yet implemented"); - } -} - /// Runs the linker and cleans up associated resources. pub fn run(args: args::Args) -> error::Result { // Note, we need to setup tracing before we activate the thread pool. In particular, we need to @@ -371,11 +220,8 @@ impl Linker { }); let args = &args.args; match args.arch { - arch::Architecture::X86_64 => { - self.link_for_arch::(args)?; - } - arch::Architecture::AArch64 => { - self.link_for_arch::(args)?; + arch::Architecture::X86_64 | arch::Architecture::AArch64 => { + self.link_for_arch::(args)?; } _ => { crate::bail!("PE format only supports x86_64 and aarch64"); @@ -384,22 +230,18 @@ impl Linker { } } - // We've finished linking. We consider everything from this point onwards as shutdown. - let (g1, g2) = timing_guard!("Shutdown"); - self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); - Ok(()) } - fn link_for_arch<'data, T: LinkTarget<'data>>( + fn link_for_arch<'data, P: Platform<'data>>( &'data self, - args: &'data args::Args<>::ArgsType>, + args: &'data Args<>::ArgsType>, ) -> error::Result> { let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); - // Note, we propagate errors from `link_with_input_data` after we've checked if any files + // Note, we propagate errors from `load_inputs_and_link` after we've checked if any files // changed. We want inputs-changed errors to take precedence over all other errors. - let result = self.load_inputs_and_link::(&mut file_loader, args); + let result = self.load_inputs_and_link::

(&mut file_loader, args); file_loader.verify_inputs_unchanged()?; @@ -419,14 +261,15 @@ impl Linker { result } - fn load_inputs_and_link<'data, T: LinkTarget<'data>>( + fn load_inputs_and_link<'data, P: Platform<'data>>( &'data self, file_loader: &mut FileLoader<'data>, - args: &'data args::Args<>::ArgsType>, + args: &'data Args<>::ArgsType>, ) -> error::Result> { - let mut plugin = T::create_plugin(self, args)?; + let mut plugin = P::create_plugin(self, args)?; + let auxiliary = P::load_auxiliary(self, args)?; - let loaded = file_loader.load_inputs::(&args.inputs, args, &mut plugin); + let loaded = file_loader.load_inputs::(&args.inputs, args, &mut plugin); args.save_dir.finish(file_loader, args)?; @@ -438,8 +281,6 @@ impl Linker { let mut layout_rules_builder = LayoutRulesBuilder::default(); - let auxiliary = T::load_auxiliary(self, args)?; - let mut symbol_db = symbol_db::SymbolDb::new(args, output_kind, &auxiliary, &self.herd)?; let mut per_symbol_flags = PerSymbolFlags::new(); @@ -466,8 +307,7 @@ impl Linker { &resolver.resolved_groups, )?; - let layout = T::finish_link( - self, + let layout = P::finish_link( file_loader, args, &mut plugin, @@ -479,9 +319,7 @@ impl Linker { output_kind, )?; - if args.is_elf() { - diff::maybe_diff()?; - } + diff::maybe_diff()?; // We've finished linking. We consider everything from this point onwards as shutdown. let (g1, g2) = timing_guard!("Shutdown"); @@ -508,7 +346,7 @@ impl Drop for Linker { impl Drop for LinkerOutput<'_> { fn drop(&mut self) { timing_phase!("Drop layout"); - self.layout.take(); + let _ = self.layout.take(); } } diff --git a/libwild/src/pe_writer.rs b/libwild/src/pe_writer.rs new file mode 100644 index 000000000..b24e3e48d --- /dev/null +++ b/libwild/src/pe_writer.rs @@ -0,0 +1,691 @@ +//! PE executable output: layout computation and writing. +//! +//! This module handles the PE-specific portion of linking: computing section layout, +//! writing PE headers, copying section data, and applying COFF relocations. + +use crate::args::Args; +use crate::args::windows::PeArgs; +use crate::arch::Architecture; +use crate::coff::CoffObjectFile; +use crate::error::Context as _; +use crate::error::Result; +use crate::file_writer::SizedOutput; +use crate::platform::ObjectFile; +use crate::platform::Symbol as _; +use crate::resolution::ResolvedFile; +use crate::resolution::ResolvedGroup; +use crate::resolution::SectionSlot; +use crate::sharding::ShardKey as _; +use crate::symbol::UnversionedSymbolName; +use crate::symbol_db::SymbolDb; +use object::LittleEndian as LE; +use object::pe; +use std::collections::HashMap; + +// ── Constants ──────────────────────────────────────────────────────────────── + +const IMAGE_BASE_X64: u64 = 0x0000_0001_4000_0000; +const SECTION_ALIGNMENT: u32 = 0x1000; +const FILE_ALIGNMENT: u32 = 0x200; + +/// Size of DOS header (64 bytes). +const DOS_HEADER_SIZE: u32 = core::mem::size_of::() as u32; +/// Size of PE signature (4 bytes). +const PE_SIGNATURE_SIZE: u32 = 4; +/// Size of COFF file header (20 bytes). +const COFF_HEADER_SIZE: u32 = core::mem::size_of::() as u32; +/// Size of PE32+ optional header without data directories. +const OPTIONAL_HEADER_BASE_SIZE: u32 = core::mem::size_of::() as u32; +/// Size of data directories (16 × 8 = 128 bytes). +const DATA_DIRS_SIZE: u32 = + (pe::IMAGE_NUMBEROF_DIRECTORY_ENTRIES as u32) * core::mem::size_of::() as u32; +/// Combined optional header size (base + data directories). +const OPTIONAL_HEADER_SIZE: u32 = OPTIONAL_HEADER_BASE_SIZE + DATA_DIRS_SIZE; +/// Size of one section header (40 bytes). +const SECTION_HEADER_SIZE: u32 = core::mem::size_of::() as u32; + +// ── Layout data structures ─────────────────────────────────────────────────── + +pub(crate) struct PeLayout<'data> { + pub(crate) args: &'data Args, + pub(crate) image_base: u64, + pub(crate) sections: Vec>, + pub(crate) entry_point_rva: u32, + pub(crate) size_of_headers: u32, + pub(crate) size_of_image: u32, + pub(crate) machine: u16, +} + +impl<'data> crate::layout::LayoutTarget<'data> for PeLayout<'data> { + type ArgsType = PeArgs; + + fn args(&self) -> &Args { + self.args + } + + fn layout_data(&self) -> linker_layout::Layout { + linker_layout::Layout { files: vec![] } + } + + fn into_target_layout(self) -> crate::layout::TargetLayout<'data> { + crate::layout::TargetLayout::Pe(self) + } +} + +pub(crate) struct PeOutputSection<'data> { + pub(crate) name: [u8; 8], + pub(crate) virtual_address: u32, + pub(crate) virtual_size: u32, + pub(crate) file_offset: u32, + pub(crate) raw_data_size: u32, + pub(crate) characteristics: u32, + pub(crate) contributions: Vec>, + /// True if this section contains uninitialized data only (.bss). + pub(crate) is_bss: bool, +} + +pub(crate) struct SectionContribution<'data> { + pub(crate) object: &'data CoffObjectFile<'data>, + pub(crate) input_section_index: object::SectionIndex, + /// Offset of this contribution within the output section. + pub(crate) output_offset: u32, + pub(crate) size: u32, + /// The start of global symbol IDs for this object, used to map + /// local symbol table indices to global IDs. + pub(crate) symbol_id_start: crate::symbol_db::SymbolId, +} + +// ── Section name / characteristics mapping ─────────────────────────────────── + +/// Determines the output section name for a given input section name. +fn output_section_name(input_name: &[u8]) -> [u8; 8] { + // For names like ".text$foo", group under the base name + let base_name = if let Some(dollar_pos) = input_name.iter().position(|&b| b == b'$') { + &input_name[..dollar_pos] + } else { + input_name + }; + + match base_name { + b".text" => *b".text\0\0\0", + b".rdata" => *b".rdata\0\0", + b".data" => *b".data\0\0\0", + b".bss" => *b".bss\0\0\0\0", + b".pdata" => *b".pdata\0\0", + b".xdata" => *b".xdata\0\0", + _ => { + let mut out = [0u8; 8]; + let len = base_name.len().min(8); + out[..len].copy_from_slice(&base_name[..len]); + out + } + } +} + +/// Strips alignment and link-only bits from COFF section characteristics, +/// keeping only content type and permission flags. +fn merge_characteristics(chars: u32) -> u32 { + chars + & (pe::IMAGE_SCN_CNT_CODE + | pe::IMAGE_SCN_CNT_INITIALIZED_DATA + | pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA + | pe::IMAGE_SCN_MEM_EXECUTE + | pe::IMAGE_SCN_MEM_READ + | pe::IMAGE_SCN_MEM_WRITE) +} + +/// Extracts section alignment from COFF characteristics bits 20-23. +/// Returns alignment in bytes (1, 2, 4, 8, ..., 8192). +fn coff_section_alignment(chars: u32) -> u32 { + let align_field = (chars >> 20) & 0xF; + if align_field == 0 { + 1 + } else { + 1 << (align_field - 1) + } +} + +// ── Layout computation ─────────────────────────────────────────────────────── + +pub(crate) fn compute_layout<'data>( + symbol_db: &SymbolDb<'data, CoffObjectFile<'data>>, + resolved_groups: &[ResolvedGroup<'data, CoffObjectFile<'data>>], + args: &'data Args, +) -> Result>> { + let image_base = IMAGE_BASE_X64; + let machine = match args.arch { + Architecture::X86_64 => pe::IMAGE_FILE_MACHINE_AMD64, + Architecture::AArch64 => pe::IMAGE_FILE_MACHINE_ARM64, + _ => crate::bail!("Unsupported PE architecture: {:?}", args.arch), + }; + + // Step 1: Collect input sections into output sections. + let mut output_sections: Vec> = Vec::new(); + let mut section_map: HashMap<([u8; 8], u32), usize> = HashMap::new(); + + for group in resolved_groups { + for file in &group.files { + let ResolvedFile::Object(resolved_obj) = file else { + continue; + }; + let object = resolved_obj.common.object; + let symbol_id_start = resolved_obj.common.symbol_id_range.start(); + + for (slot_index, slot) in resolved_obj.sections.iter().enumerate() { + // In the PE path, sections stay as Unloaded/MustLoad (never + // transition to Loaded because we skip the ELF layout step). + // Include any section that wasn't discarded. + match slot { + SectionSlot::Discard => continue, + SectionSlot::Loaded(_) + | SectionSlot::Unloaded(_) + | SectionSlot::MustLoad(_) => {} + _ => continue, + } + + // COFF section indices are 1-based. + let section_index = object::SectionIndex(slot_index + 1); + let section_header = object.section(section_index)?; + let name_bytes = object.section_name(section_header)?; + let out_name = output_section_name(name_bytes); + let in_chars = section_header.characteristics.get(LE); + let out_chars = merge_characteristics(in_chars); + let is_bss = in_chars & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0; + + let size = section_header.size_of_raw_data.get(LE); + if size == 0 { + continue; + } + + let section_idx = *section_map + .entry((out_name, out_chars)) + .or_insert_with(|| { + output_sections.push(PeOutputSection { + name: out_name, + virtual_address: 0, + virtual_size: 0, + file_offset: 0, + raw_data_size: 0, + characteristics: out_chars, + contributions: Vec::new(), + is_bss, + }); + output_sections.len() - 1 + }); + + let out_section = &mut output_sections[section_idx]; + + let input_alignment = coff_section_alignment(in_chars).max(1); + let aligned_offset = align_up(out_section.virtual_size, input_alignment); + + out_section.contributions.push(SectionContribution { + object, + input_section_index: section_index, + output_offset: aligned_offset, + size, + symbol_id_start, + }); + + out_section.virtual_size = aligned_offset + size; + if !is_bss { + out_section.raw_data_size = aligned_offset + size; + } + } + } + } + + // Sort output sections: .text first, then .rdata, .data, .bss, then others + output_sections.sort_by_key(|s| section_sort_key(&s.name)); + + // Step 2: Compute header size + let headers_raw = DOS_HEADER_SIZE + + PE_SIGNATURE_SIZE + + COFF_HEADER_SIZE + + OPTIONAL_HEADER_SIZE + + SECTION_HEADER_SIZE * output_sections.len() as u32; + let size_of_headers = align_up(headers_raw, FILE_ALIGNMENT); + + // Step 3: Assign virtual addresses and file offsets + let mut next_rva = align_up(size_of_headers, SECTION_ALIGNMENT); + let mut next_file_offset = size_of_headers; + + for section in &mut output_sections { + section.virtual_address = next_rva; + section.file_offset = if section.is_bss { 0 } else { next_file_offset }; + + if !section.is_bss { + section.raw_data_size = align_up(section.raw_data_size, FILE_ALIGNMENT); + next_file_offset += section.raw_data_size; + } + + next_rva = align_up(next_rva + section.virtual_size, SECTION_ALIGNMENT); + } + + let size_of_image = next_rva; + let file_size = next_file_offset as u64; + + // Step 4: Compute symbol addresses + let mut section_address_map: HashMap<(usize, usize), (u32, u32)> = HashMap::new(); + for section in &output_sections { + for contrib in §ion.contributions { + let key = ( + contrib.object as *const _ as usize, + contrib.input_section_index.0, + ); + section_address_map.insert(key, (section.virtual_address, contrib.output_offset)); + } + } + + let num_symbols = symbol_db.num_symbols(); + let mut symbol_addresses = vec![0u64; num_symbols]; + + for group in resolved_groups { + for file in &group.files { + let ResolvedFile::Object(resolved_obj) = file else { + continue; + }; + let object = resolved_obj.common.object; + let symbol_id_range = &resolved_obj.common.symbol_id_range; + let obj_ptr = object as *const _ as usize; + + for (local_sym_index, symbol) in object.enumerate_symbols() { + let global_id = symbol_id_range.offset_to_id(local_sym_index.0); + let global_index = global_id.as_usize(); + if global_index >= num_symbols { + continue; + } + + // Only compute address if this is the canonical definition + let def_id = symbol_db.definition(global_id); + if def_id != global_id { + continue; + } + + if let Ok(Some(section_index)) = + object.symbol_section(symbol, local_sym_index) + { + let key = (obj_ptr, section_index.0); + if let Some(&(section_va, contrib_offset)) = section_address_map.get(&key) { + let sym_value = symbol.value(); + symbol_addresses[global_index] = + image_base + section_va as u64 + contrib_offset as u64 + sym_value; + } + } + } + } + } + + // Propagate addresses for redirected symbols + for sym_id_raw in 0..num_symbols { + let sym_id = crate::symbol_db::SymbolId::from_usize(sym_id_raw); + let def_id = symbol_db.definition(sym_id); + if def_id != sym_id && def_id.as_usize() < num_symbols { + symbol_addresses[sym_id_raw] = symbol_addresses[def_id.as_usize()]; + } + } + + // Step 5: Find entry point + let entry_point_rva = if let Some(entry_name) = &args.entry { + find_entry_point_rva(symbol_db, &symbol_addresses, entry_name, image_base)? + } else { + find_entry_point_rva(symbol_db, &symbol_addresses, "mainCRTStartup", image_base) + .or_else(|_| { + find_entry_point_rva(symbol_db, &symbol_addresses, "_mainCRTStartup", image_base) + }) + .or_else(|_| { + find_entry_point_rva( + symbol_db, + &symbol_addresses, + "WinMainCRTStartup", + image_base, + ) + }) + .unwrap_or(0) + }; + + let entry_address = image_base + entry_point_rva as u64; + + Ok(crate::layout::Layout::new( + file_size, + entry_address, + symbol_addresses, + PeLayout { + args, + image_base, + sections: output_sections, + entry_point_rva, + size_of_headers, + size_of_image, + machine, + }, + )) +} + +fn find_entry_point_rva<'data>( + symbol_db: &SymbolDb<'data, CoffObjectFile<'data>>, + symbol_addresses: &[u64], + name: &str, + image_base: u64, +) -> Result { + let prehashed = UnversionedSymbolName::prehashed(name.as_bytes()); + let sym_id = symbol_db + .get_unversioned(&prehashed) + .with_context(|| format!("Entry point symbol `{name}` not found"))?; + let def_id = symbol_db.definition(sym_id); + let addr = symbol_addresses[def_id.as_usize()]; + if addr == 0 { + crate::bail!("Entry point symbol `{name}` has no address"); + } + Ok((addr - image_base) as u32) +} + +fn section_sort_key(name: &[u8; 8]) -> u32 { + match name { + b".text\0\0\0" => 0, + b".rdata\0\0" => 1, + b".data\0\0\0" => 2, + b".pdata\0\0" => 3, + b".xdata\0\0" => 4, + b".bss\0\0\0\0" => 5, + _ => 10, + } +} + +// ── Writing ────────────────────────────────────────────────────────────────── + +pub(crate) fn write<'data>(sized_output: &mut SizedOutput, layout: &crate::layout::Layout<'data, PeLayout<'data>>) -> Result { + write_headers(&mut sized_output.out, layout)?; + write_sections(&mut sized_output.out, layout)?; + Ok(()) +} + +fn write_headers<'data>(buf: &mut [u8], layout: &crate::layout::Layout<'data, PeLayout<'data>>) -> Result { + let e = LE; + let mut offset = 0usize; + + // DOS Header + let dos_header: &mut pe::ImageDosHeader = from_bytes_mut_at(buf, &mut offset)?; + dos_header.e_magic.set(e, pe::IMAGE_DOS_SIGNATURE); + dos_header.e_lfanew.set(e, DOS_HEADER_SIZE); + + // PE Signature + let sig = buf + .get_mut(offset..offset + 4) + .context("Buffer too small for PE signature")?; + sig.copy_from_slice(&pe::IMAGE_NT_SIGNATURE.to_le_bytes()); + offset += 4; + + // COFF File Header + let file_header: &mut pe::ImageFileHeader = from_bytes_mut_at(buf, &mut offset)?; + file_header.machine.set(e, layout.machine); + file_header + .number_of_sections + .set(e, layout.sections.len() as u16); + file_header.time_date_stamp.set(e, 0); + file_header.pointer_to_symbol_table.set(e, 0); + file_header.number_of_symbols.set(e, 0); + file_header + .size_of_optional_header + .set(e, OPTIONAL_HEADER_SIZE as u16); + file_header.characteristics.set( + e, + pe::IMAGE_FILE_EXECUTABLE_IMAGE | pe::IMAGE_FILE_LARGE_ADDRESS_AWARE, + ); + + // Optional Header (PE32+) + let opt_header: &mut pe::ImageOptionalHeader64 = from_bytes_mut_at(buf, &mut offset)?; + opt_header.magic.set(e, pe::IMAGE_NT_OPTIONAL_HDR64_MAGIC); + opt_header.major_linker_version = 1; + opt_header.minor_linker_version = 0; + opt_header + .address_of_entry_point + .set(e, layout.entry_point_rva); + opt_header.image_base.set(e, layout.image_base); + opt_header.section_alignment.set(e, SECTION_ALIGNMENT); + opt_header.file_alignment.set(e, FILE_ALIGNMENT); + opt_header.major_operating_system_version.set(e, 6); + opt_header.minor_operating_system_version.set(e, 0); + opt_header.major_subsystem_version.set(e, 6); + opt_header.minor_subsystem_version.set(e, 0); + opt_header.size_of_image.set(e, layout.size_of_image); + opt_header.size_of_headers.set(e, layout.size_of_headers); + opt_header.subsystem.set(e, pe::IMAGE_SUBSYSTEM_WINDOWS_CUI); + opt_header.dll_characteristics.set( + e, + pe::IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA + | pe::IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE + | pe::IMAGE_DLLCHARACTERISTICS_NX_COMPAT + | pe::IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE, + ); + opt_header.size_of_stack_reserve.set(e, 0x100000); + opt_header.size_of_stack_commit.set(e, 0x1000); + opt_header.size_of_heap_reserve.set(e, 0x100000); + opt_header.size_of_heap_commit.set(e, 0x1000); + opt_header + .number_of_rva_and_sizes + .set(e, pe::IMAGE_NUMBEROF_DIRECTORY_ENTRIES as u32); + + // Compute aggregate sizes for the optional header + let mut size_of_code = 0u32; + let mut size_of_initialized_data = 0u32; + let mut size_of_uninitialized_data = 0u32; + let mut base_of_code = 0u32; + for section in &layout.sections { + if section.characteristics & pe::IMAGE_SCN_CNT_CODE != 0 { + size_of_code += section.raw_data_size; + if base_of_code == 0 { + base_of_code = section.virtual_address; + } + } + if section.characteristics & pe::IMAGE_SCN_CNT_INITIALIZED_DATA != 0 { + size_of_initialized_data += section.raw_data_size; + } + if section.characteristics & pe::IMAGE_SCN_CNT_UNINITIALIZED_DATA != 0 { + size_of_uninitialized_data += section.virtual_size; + } + } + opt_header.size_of_code.set(e, size_of_code); + opt_header + .size_of_initialized_data + .set(e, size_of_initialized_data); + opt_header + .size_of_uninitialized_data + .set(e, size_of_uninitialized_data); + opt_header.base_of_code.set(e, base_of_code); + + // Data directories (16 entries, all zeroed for now) + let data_dirs_slice = buf + .get_mut(offset..offset + DATA_DIRS_SIZE as usize) + .context("Buffer too small for data directories")?; + data_dirs_slice.fill(0); + offset += DATA_DIRS_SIZE as usize; + + // Section Headers + for section in &layout.sections { + let sec_header: &mut pe::ImageSectionHeader = from_bytes_mut_at(buf, &mut offset)?; + sec_header.name = section.name; + sec_header.virtual_size.set(e, section.virtual_size); + sec_header.virtual_address.set(e, section.virtual_address); + sec_header.size_of_raw_data.set( + e, + if section.is_bss { + 0 + } else { + section.raw_data_size + }, + ); + sec_header.pointer_to_raw_data.set(e, section.file_offset); + sec_header.characteristics.set(e, section.characteristics); + } + + Ok(()) +} + +fn write_sections<'data>(buf: &mut [u8], layout: &crate::layout::Layout<'data, PeLayout<'data>>) -> Result { + for (section_idx, section) in layout.sections.iter().enumerate() { + if section.is_bss { + continue; + } + + for contrib in §ion.contributions { + let section_header = contrib.object.section(contrib.input_section_index)?; + let data = contrib.object.raw_section_data(section_header)?; + let out_offset = section.file_offset as usize + contrib.output_offset as usize; + let copy_size = data.len().min(contrib.size as usize); + let out_end = out_offset + copy_size; + + if out_end > buf.len() { + crate::bail!( + "Section data write out of bounds: offset={out_offset}, size={copy_size}, buf_len={}", + buf.len() + ); + } + + buf[out_offset..out_end].copy_from_slice(&data[..copy_size]); + + apply_relocations(buf, layout, section, section_idx, contrib)?; + } + } + + Ok(()) +} + +fn apply_relocations<'data>( + buf: &mut [u8], + layout: &crate::layout::Layout<'data, PeLayout<'data>>, + section: &PeOutputSection, + section_idx: usize, + contrib: &SectionContribution, +) -> Result { + let relocations = contrib + .object + .relocations(contrib.input_section_index, &())?; + + for reloc in relocations { + let reloc_type = reloc.typ.get(LE); + let reloc_offset_in_section = reloc.virtual_address.get(LE); + let symbol_table_index = reloc.symbol_table_index.get(LE) as usize; + + // Map local symbol table index to global symbol ID + let global_id = contrib.symbol_id_start.add_usize(symbol_table_index); + let target_addr = layout.symbol_addresses[global_id.as_usize()]; + + let file_offset = section.file_offset as usize + + contrib.output_offset as usize + + reloc_offset_in_section as usize; + + let reloc_va = layout.image_base + + section.virtual_address as u64 + + contrib.output_offset as u64 + + reloc_offset_in_section as u64; + + match reloc_type { + pe::IMAGE_REL_AMD64_ABSOLUTE => { + // No-op (padding/alignment) + } + pe::IMAGE_REL_AMD64_ADDR64 => { + write_u64(buf, file_offset, target_addr)?; + } + pe::IMAGE_REL_AMD64_ADDR32 => { + write_u32(buf, file_offset, target_addr as u32)?; + } + pe::IMAGE_REL_AMD64_ADDR32NB => { + let rva = target_addr.wrapping_sub(layout.image_base); + write_u32(buf, file_offset, rva as u32)?; + } + pe::IMAGE_REL_AMD64_REL32 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(4); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_REL32_1 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(5); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_REL32_2 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(6); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_REL32_3 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(7); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_REL32_4 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(8); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_REL32_5 => { + let value = target_addr.wrapping_sub(reloc_va).wrapping_sub(9); + write_i32(buf, file_offset, value as i32)?; + } + pe::IMAGE_REL_AMD64_SECTION => { + write_u16(buf, file_offset, (section_idx + 1) as u16)?; + } + pe::IMAGE_REL_AMD64_SECREL => { + let section_base = layout.image_base + section.virtual_address as u64; + let secrel = target_addr.wrapping_sub(section_base); + write_u32(buf, file_offset, secrel as u32)?; + } + _ => { + crate::bail!( + "Unsupported COFF relocation type 0x{reloc_type:04x} at offset 0x{file_offset:x}" + ); + } + } + } + + Ok(()) +} + +// ── Helper functions ───────────────────────────────────────────────────────── + +fn align_up(value: u32, alignment: u32) -> u32 { + (value + alignment - 1) & !(alignment - 1) +} + +/// Cast a mutable reference to a Pod type from a byte buffer at the given offset, +/// advancing the offset past the type. +fn from_bytes_mut_at<'a, T: object::pod::Pod>(buf: &'a mut [u8], offset: &mut usize) -> Result<&'a mut T> { + let size = core::mem::size_of::(); + let end = *offset + size; + if end > buf.len() { + crate::bail!("Buffer too small: need {end} bytes, have {}", buf.len()); + } + let slice = &mut buf[*offset..end]; + // SAFETY: T is Pod, and object's PE types use byte-array fields (U16, U32 etc.) + // that don't require alignment. + let ptr = slice.as_mut_ptr() as *mut T; + *offset = end; + Ok(unsafe { &mut *ptr }) +} + +fn write_u16(buf: &mut [u8], offset: usize, value: u16) -> Result { + let bytes = buf + .get_mut(offset..offset + 2) + .context("Relocation write out of bounds (u16)")?; + bytes.copy_from_slice(&value.to_le_bytes()); + Ok(()) +} + +fn write_u32(buf: &mut [u8], offset: usize, value: u32) -> Result { + let bytes = buf + .get_mut(offset..offset + 4) + .context("Relocation write out of bounds (u32)")?; + bytes.copy_from_slice(&value.to_le_bytes()); + Ok(()) +} + +fn write_i32(buf: &mut [u8], offset: usize, value: i32) -> Result { + let bytes = buf + .get_mut(offset..offset + 4) + .context("Relocation write out of bounds (i32)")?; + bytes.copy_from_slice(&value.to_le_bytes()); + Ok(()) +} + +fn write_u64(buf: &mut [u8], offset: usize, value: u64) -> Result { + let bytes = buf + .get_mut(offset..offset + 8) + .context("Relocation write out of bounds (u64)")?; + bytes.copy_from_slice(&value.to_le_bytes()); + Ok(()) +} diff --git a/libwild/src/platform.rs b/libwild/src/platform.rs index a8bc131c8..3acc1aadf 100644 --- a/libwild/src/platform.rs +++ b/libwild/src/platform.rs @@ -1,603 +1,694 @@ -use crate::args::Args; -use crate::OutputKind; -use crate::Result; -use crate::bail; -use crate::input_data::InputBytes; -use crate::input_data::InputRef; -use crate::layout; -use crate::layout::DynamicSymbolDefinition; -use crate::layout::Layout; -use crate::layout::ObjectLayoutState; -use crate::layout::OutputRecordLayout; -use crate::output_section_id::OutputSectionId; -use crate::output_section_id::OutputSections; -use crate::output_section_map::OutputSectionMap; -use crate::output_section_part_map::OutputSectionPartMap; -use crate::part_id::PartId; -use crate::resolution::LoadedMetrics; -use crate::resolution::UnloadedSection; -use crate::symbol_db::SymbolDb; -use crate::value_flags::ValueFlags; -use linker_utils::elf::DynamicRelocationKind; -use linker_utils::elf::RelocationKindInfo; -use linker_utils::relaxation::RelocationModifier; -use linker_utils::relaxation::SectionRelaxDeltas; -use rayon::Scope; -use std::borrow::Cow; -use std::num::NonZeroU32; -use std::ops::Range; -use std::path::PathBuf; - -/// Represents a supported object file format + architecture combination. -pub(crate) trait Platform<'data>: 'data { - type Relaxation: Relaxation; - type File: ObjectFile<'data>; - - // Get ELF header magic for the architecture. - fn elf_header_arch_magic() -> u16; - - // Get dynamic relocation value specific for the architecture. - fn get_dynamic_relocation_type(relocation: DynamicRelocationKind) -> u32; - - // Write PLT entry for the architecture. - fn write_plt_entry(plt_entry: &mut [u8], got_address: u64, plt_address: u64) -> Result; - - // Make architecture-specific parsing of the relocation types. - fn relocation_from_raw(r_type: u32) -> Result; - - // Get string representation of a relocation specific for the architecture. - fn rel_type_to_string(r_type: u32) -> Cow<'static, str>; - - // Get DTV OFFSET. - fn get_dtv_offset() -> u64 { - 0 - } - - // Some architectures use debug info relocation that depend on local symbols. - fn local_symbols_in_debug_info() -> bool; - - // Get position of the $tp (thread pointer) in the TLS section. Each platform defines - // a different place based on the following article: - // https://maskray.me/blog/2021-02-14-all-about-thread-local-storage#tls-variants - fn tp_offset_start(layout: &Layout<'data>) -> u64; - - // Classify a GNU property note. - fn get_property_class(property_type: u32) -> Option; - - // Merge e_flags of the input files and provide an error - // if the flags are not compatible. - fn merge_eflags(eflags: impl Iterator) -> Result; - - // A list of high-part relocations that need to be tracked in a relocation cache - fn high_part_relocations() -> &'static [u32]; - - /// Whether the platform supports relaxations that reduce the sizes of function. - fn supports_size_reduction_relaxations() -> bool { - false - } - - /// Uses debug info, if available, to get information about where in the source code a - /// particular offset in a particular section came from. - fn get_source_info( - object: &Self::File, - relocations: &>::RelocationSections, - section: &>::SectionHeader, - offset_in_section: u64, - ) -> Result; - - fn collect_relaxation_deltas( - _section_output_address: u64, - _section_bytes: &[u8], - // TODO: Change to be non-ELF specific once layout.rs is genericised. - _relocations: crate::elf::RelocationList<'data>, - _existing_deltas: Option<&SectionRelaxDeltas>, - _resolve_symbol: impl FnMut(object::SymbolIndex) -> Option, - ) -> (Vec<(u64, u32)>, Option) { - // This function should not be called unless `supports_size_reduction_relaxations` returns - // true in which case this function should be implemented. - unreachable!(); - } - - fn is_symbol_variant_pcs(_object: &Self::File, _symbol_index: object::SymbolIndex) -> bool { - false - } - - /// Tries to create a relaxation for the relocation of the specified kind, to be applied at the - /// specified offset in the supplied section. - fn new_relaxation( - relocation_kind: u32, - section_bytes: &[u8], - offset_in_section: u64, - flags: ValueFlags, - output_kind: OutputKind, - section_flags: >::SectionFlags, - non_zero_address: bool, - relax_deltas: Option<&SectionRelaxDeltas>, - ) -> Option; - - fn process_riscv_attributes( - _object: &Self::File, - _format_specific: &mut >::FileLayoutState, - _riscv_attributes_section_index: object::SectionIndex, - ) -> Result { - bail!(".riscv.attribute section is supported only for riscv64 target"); - } -} - -pub(crate) trait Relaxation { - fn apply(&self, section_bytes: &mut [u8], offset_in_section: &mut u64, addend: &mut i64); - - fn rel_info(&self) -> RelocationKindInfo; - - fn debug_kind(&self) -> impl std::fmt::Debug; - - fn next_modifier(&self) -> RelocationModifier; - - fn is_mandatory(&self) -> bool; -} - -pub(crate) struct RelaxSymbolInfo { - /// The symbol's approximate output address (section base + offset within section). - pub output_address: u64, - /// Whether the symbol may be interposed at runtime. - pub is_interposable: bool, -} - -/// Abstracts over the different object file formats that we support (or may support). e.g. ELF. -pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'data { - type Symbol: Symbol; - type SectionHeader: SectionHeader<'data, Self>; - type SectionFlags: SectionFlags; - type SectionType: SectionType; - type SectionAttributes: SectionAttributes; - type SectionIterator: Iterator; - type DynamicTagValues: DynamicTagValues<'data>; - type RelocationSections: std::fmt::Debug + Default + Send + Sync + 'static; - type RelocationList: Send + Sync + 'data; - type DynamicEntry: Send + Sync + 'data; - type VerneedTable: VerneedTable<'data>; - type EpilogueLayout: Send + Sync + 'static; - type DynamicLayoutState: Default + Send + Sync + 'data; - type DynamicLayout: std::fmt::Debug + Send + Sync + 'data; - type NonAddressableIndexes: NonAddressableIndexes + Send + Sync + 'data; - type NonAddressableCounts: Default + Send + Sync + 'data; - type GroupLayoutExt: std::fmt::Debug + Send + Sync + 'static; - type CommonGroupStateExt: Default + std::fmt::Debug + Send + Sync + 'static; - - /// An index into the local object's symbol versions. - type SymbolVersionIndex: Copy; - - /// Format-specific per-file state used during the layout phase. - type FileLayoutState: 'data; - - /// Format-specific properties produced by the layout phase. - type LayoutProperties: 'static; - - /// The name of a symbol, possibly with a version. - type RawSymbolName: RawSymbolName<'data>; - - /// For platforms that don't support symbol versioning, this can just be the unit type. - type VersionNames; - - /// The format-specific args type (e.g. `ElfArgs` or `PeArgs`). - type ArgsType: Send + Sync + 'static; - - fn parse_bytes(input: &'data [u8], is_dynamic: bool) -> Result; - - /// As for `parse_bytes` but also validates that the file architecture matches what is expected - /// based on `args`. - fn parse(input: &InputBytes<'data>, args: &Args) -> Result; - - fn is_dynamic(&self) -> bool; - - fn num_symbols(&self) -> usize; - - fn symbols(&self) -> &'data [Self::Symbol]; - - fn enumerate_symbols( - &self, - ) -> impl Iterator { - self.symbols() - .iter() - .enumerate() - .map(|(i, sym)| (object::SymbolIndex(i), sym)) - } - - // TODO: Remove implementations of this as this default should be fine. Perhaps first check if - // all platforms can get a slice of symbols. - fn symbols_iter(&self) -> impl Iterator { - self.symbols().iter() - } - - fn symbol(&self, index: object::SymbolIndex) -> Result<&'data Self::Symbol>; - - fn section_size(&self, header: &Self::SectionHeader) -> Result; - - fn symbol_name(&self, symbol: &Self::Symbol) -> Result<&'data [u8]>; - - fn num_sections(&self) -> usize; - - fn section_iter(&self) -> Self::SectionIterator; - - fn enumerate_sections( - &self, - ) -> impl Iterator; - - fn section(&self, index: object::SectionIndex) -> Result<&'data Self::SectionHeader>; - - fn section_by_name( - &self, - name: &str, - ) -> Option<(object::SectionIndex, &'data Self::SectionHeader)>; - - fn symbol_section( - &self, - symbol: &Self::Symbol, - index: object::SymbolIndex, - ) -> Result>; - - fn symbol_versions(&self) -> &[Self::SymbolVersionIndex]; - - /// The dynamic object will be linked against. This is a chance to perform extra initialisation - /// of `state`. - fn activate_dynamic(&self, state: &mut Self::DynamicLayoutState); - - fn dynamic_symbol_used( - &self, - symbol_index: object::SymbolIndex, - state: &mut Self::DynamicLayoutState, - ) -> Result; - - fn finalise_sizes_dynamic( - &self, - lib_name: &[u8], - state: &mut Self::DynamicLayoutState, - mem_sizes: &mut OutputSectionPartMap, - ) -> Result; - - fn apply_non_addressable_indexes_dynamic( - &self, - indexes: &mut Self::NonAddressableIndexes, - counts: &mut Self::NonAddressableCounts, - state: &mut Self::DynamicLayoutState, - ) -> Result; - - fn finalise_layout_dynamic( - &self, - state: Self::DynamicLayoutState, - memory_offsets: &mut OutputSectionPartMap, - section_layouts: &OutputSectionMap, - ) -> Self::DynamicLayout; - - fn new_epilogue_layout( - args: &Args, - output_kind: OutputKind, - dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], - ) -> Self::EpilogueLayout; - - fn apply_non_addressable_indexes_epilogue( - counts: &mut Self::NonAddressableCounts, - state: &mut Self::EpilogueLayout, - ); - - fn apply_non_addressable_indexes<'groups>( - symbol_db: &SymbolDb<'data, Self>, - counts: &Self::NonAddressableCounts, - mem_sizes_iter: impl Iterator>, - ); - - fn finalise_sizes_epilogue( - state: &mut Self::EpilogueLayout, - mem_sizes: &mut OutputSectionPartMap, - properties: &Self::LayoutProperties, - symbol_db: &SymbolDb<'data, Self>, - ); - - fn finalise_sizes_all( - mem_sizes: &mut OutputSectionPartMap, - symbol_db: &SymbolDb<'data, Self>, - ); - - fn apply_late_size_adjustments_epilogue( - state: &mut Self::EpilogueLayout, - current_sizes: &OutputSectionPartMap, - extra_sizes: &mut OutputSectionPartMap, - dynamic_symbol_defs: &[DynamicSymbolDefinition], - ) -> Result; - - fn finalise_layout_epilogue( - epilogue_state: &mut Self::EpilogueLayout, - memory_offsets: &mut OutputSectionPartMap, - symbol_db: &SymbolDb<'data, Self>, - common_state: &Self::LayoutProperties, - dynsym_start_index: u32, - dynamic_symbol_defs: &[DynamicSymbolDefinition], - ) -> Result; - - fn dynamic_tags(&self) -> Result<&'data [Self::DynamicEntry]>; - - fn section_name(&self, section_header: &Self::SectionHeader) -> Result<&'data [u8]>; - - /// Returns the raw section data. Doesn't handle decompression. - fn raw_section_data(&self, section: &Self::SectionHeader) -> Result<&'data [u8]>; - - fn section_data( - &self, - section: &Self::SectionHeader, - member: &bumpalo_herd::Member<'data>, - loaded_metrics: &LoadedMetrics, - ) -> Result<&'data [u8]>; - - /// Copies the data for the specified section into `out`, which must be the correct size. - /// Decompresses the data if necessary. - fn copy_section_data(&self, section: &Self::SectionHeader, out: &mut [u8]) -> Result; - - /// Returns the contents of a section as a Cow. Will heap-allocate if the section is compressed. - fn section_data_cow(&self, section: &Self::SectionHeader) -> Result>; - - fn section_alignment(&self, section: &Self::SectionHeader) -> Result; - - fn relocations( - &self, - index: object::SectionIndex, - relocations: &Self::RelocationSections, - ) -> Result; - - fn parse_relocations(&self) -> Result; - - /// Get the version of a symbol. Only intended for diagnostic purposes since it's potentially - /// quite slow. - fn symbol_version_debug(&self, symbol_index: object::SymbolIndex) -> Option; - - fn section_display_name(&self, index: object::SectionIndex) -> Cow<'data, str>; - - fn dynamic_tag_values(&self) -> Option; - - fn get_version_names(&self) -> Result; - - fn get_symbol_name_and_version( - &self, - symbol: &Self::Symbol, - local_index: usize, - version_names: &Self::VersionNames, - ) -> Result; - - fn verneed_table(&self) -> Result; - - fn process_gnu_note_section( - &self, - state: &mut Self::FileLayoutState, - section_index: object::SectionIndex, - ) -> Result; - - fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, - objects: impl Iterator, - states: impl Iterator + Clone, - ) -> Result - where - 'data: 'files, - 'data: 'states; - - fn load_exception_frame_data<'scope, P: Platform<'data, File = Self>>( - object: &mut ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState<'data>, - eh_frame_section_index: object::SectionIndex, - resources: &'scope layout::GraphResources<'data, '_>, - queue: &mut layout::LocalWorkQueue, - scope: &Scope<'scope>, - ) -> Result; - - /// Called when a section is loaded (not GCed). Implementations should process any exception - /// frame data related to the loaded section. - fn non_empty_section_loaded<'scope, P: Platform<'data, File = Self>>( - object: &mut layout::ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState<'data>, - queue: &mut layout::LocalWorkQueue, - unloaded: UnloadedSection, - resources: &'scope layout::GraphResources<'data, 'scope>, - scope: &Scope<'scope>, - ) -> Result; - - fn finalise_group_layout(memory_offsets: &OutputSectionPartMap) -> Self::GroupLayoutExt; - - /// Called after GC phase has completed. Mostly useful for platform-specific logging. - fn finalise_find_required_sections(groups: &[layout::GroupState]); - - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState, args: &Args); - - fn finalise_object_sizes( - object: &mut layout::ObjectLayoutState<'data>, - common: &mut layout::CommonGroupState, - ); - - fn finalise_object_layout( - object: &layout::ObjectLayoutState<'data>, - memory_offsets: &mut OutputSectionPartMap, - ); - - fn compute_object_addresses( - object: &layout::ObjectLayoutState<'data>, - memory_offsets: &mut OutputSectionPartMap, - ); - - /// Resolves a reference to the frame data section. - fn frame_data_base_address(memory_offsets: &OutputSectionPartMap) -> u64; -} - -pub(crate) trait SectionHeader<'data, O: ObjectFile<'data>>: - std::fmt::Debug + Send + Sync + 'data -{ - fn flags(&self) -> O::SectionFlags; - - fn attributes(&self) -> O::SectionAttributes; - - fn section_type(&self) -> O::SectionType; -} - -pub(crate) trait SectionType: Copy { - fn is_note(self) -> bool; - - fn is_prog_bits(self) -> bool; - - /// Returns whether the section has no contents in the file (zero initialised). - fn is_no_bits(self) -> bool; -} - -pub(crate) trait SectionFlags: Copy + std::fmt::Debug + Send + Sync + 'static { - fn is_alloc(self) -> bool; - - fn is_writable(self) -> bool; - - fn is_executable(self) -> bool; - - fn is_tls(self) -> bool; - - fn is_merge_section(self) -> bool; - - fn is_strings(self) -> bool; - - fn should_retain(self) -> bool; - - fn should_exclude(&self) -> bool; - - fn is_group(self) -> bool; -} - -pub(crate) trait Symbol: std::fmt::Debug + Send + Sync + 'static { - /// Returns information about the symbol if it's a common symbol. Platforms that don't have - /// common symbols can just return None. - fn as_common(&self) -> Option; - - fn is_common(&self) -> bool { - self.as_common().is_some() - } - - fn is_undefined(&self) -> bool; - - fn is_local(&self) -> bool; - - fn is_absolute(&self) -> bool; - - fn is_weak(&self) -> bool; - - fn visibility(&self) -> crate::symbol_db::Visibility; - - fn value(&self) -> u64; - - fn size(&self) -> u64; - - fn section_index(&self) -> object::SectionIndex; - - fn has_name(&self) -> bool; - - fn debug_string(&self) -> String; - - /// Returns whether this symbol has been declared as a TLS variable. - fn is_tls(&self) -> bool; - - /// Returns whether this symbol can be interposed (overridden) at runtime by DSOs earlier in the - /// load order. - fn is_interposable(&self) -> bool; - - fn is_func(&self) -> bool; - - fn is_ifunc(&self) -> bool; - - fn is_hidden(&self) -> bool; - - fn is_gnu_unique(&self) -> bool; -} - -#[derive(Clone, Copy)] -pub(crate) struct CommonSymbol { - pub(crate) size: u64, - pub(crate) part_id: PartId, -} - -pub(crate) trait Relocation: Send + Sync + Copy + 'static { - type Sequence<'data>: RelocationSequence<'data>; - - fn symbol(&self) -> Option; - - fn raw_type(&self) -> u32; - - fn offset(&self) -> u64; - - fn addend(&self) -> i64; -} - -pub(crate) trait RelocationSequence<'data> { - type Rel: Relocation; - - fn rel_iter(&self) -> impl Iterator; - fn subsequence(&self, range: Range) -> Self; - fn num_relocations(&self) -> usize; -} - -pub(crate) trait RawSymbolName<'data>: Send + Sync + 'data { - fn parse(bytes: &'data [u8]) -> Self; - - fn name(&self) -> &'data [u8]; - - fn version_name(&self) -> Option<&'data [u8]>; - - fn is_default(&self) -> bool; -} - -pub(crate) trait VerneedTable<'data>: Send + Sync + 'data { - fn version_name(&self, local_symbol_index: object::SymbolIndex) -> Option<&'data [u8]>; -} - -pub(crate) trait DynamicTagValues<'data>: std::fmt::Debug + Send + Sync + 'data { - fn lib_name(&self, input: &InputRef<'data>) -> &'data [u8]; -} - -pub(crate) trait NonAddressableIndexes { - fn new<'data, O: ObjectFile<'data>>(symbol_db: &SymbolDb<'data, O>) -> Self; -} - -pub(crate) trait SectionAttributes: std::fmt::Debug + Send + Sync + 'static { - fn merge(&mut self, rhs: Self); - - fn apply(&self, output_sections: &mut OutputSections, section_id: OutputSectionId); -} - -pub(crate) struct SourceInfo(pub(crate) Option); - -pub(crate) enum PropertyClass { - // A bit in the output pr_data is set if it is set in any relocatable input. - // If all bits in the output pr_data field are zero, this property should be removed from - // output. - Or, - // A bit in the output pr_data field is set only if it is set in all relocatable input pr_data - // fields. If all bits in the output pr_data field are zero, this property should be - // removed from output. - And, - // A bit in the output pr_data field is set if it is set in any relocatable input pr_data - // fields and this property is present in all relocatable input files. When all bits in - // the output pr_data field are zero, this property should not be removed from output to - // indicate it has zero in all bits. - AndOr, -} - -#[derive(Debug)] -pub(crate) struct SourceInfoDetails { - pub(crate) path: PathBuf, - pub(crate) line: u64, -} - -/// An index into the exception frames for an object. Interpretation of the value is up to the -/// platform. -#[derive(Debug, Clone, Copy)] -pub(crate) struct FrameIndex(NonZeroU32); - -impl FrameIndex { - pub(crate) fn from_usize(raw: usize) -> Self { - Self(NonZeroU32::new(raw as u32 + 1).unwrap()) - } - - pub(crate) fn as_usize(self) -> usize { - self.0.get() as usize - 1 - } -} +use crate::args::Args; +use crate::OutputKind; +use crate::Result; +use crate::bail; +use crate::input_data::InputBytes; +use crate::input_data::InputRef; +use crate::elf_layout; +use crate::layout::DynamicSymbolDefinition; +use crate::layout::Layout; +use crate::layout::OutputRecordLayout; +use crate::output_section_id::OutputSectionId; +use crate::output_section_id::OutputSections; +use crate::output_section_map::OutputSectionMap; +use crate::output_section_part_map::OutputSectionPartMap; +use crate::part_id::PartId; +use crate::resolution::LoadedMetrics; +use crate::resolution::UnloadedSection; +use crate::symbol_db::SymbolDb; +use crate::value_flags::ValueFlags; +use linker_utils::elf::DynamicRelocationKind; +use linker_utils::elf::RelocationKindInfo; +use linker_utils::relaxation::RelocationModifier; +use linker_utils::relaxation::SectionRelaxDeltas; +use rayon::Scope; +use std::borrow::Cow; +use std::num::NonZeroU32; +use std::ops::Range; +use std::path::PathBuf; + +/// Represents a supported object file format + architecture combination. +pub(crate) trait Platform<'data>: 'data { + type File: ObjectFile<'data>; + + fn create_plugin( + _linker: &'data crate::Linker, + _args: &'data Args<>::ArgsType>, + ) -> crate::Result>> { + Ok(None) + } + + fn load_auxiliary( + _linker: &'data crate::Linker, + _args: &'data Args<>::ArgsType>, + ) -> crate::Result> { + Ok(crate::input_data::AuxiliaryFiles::empty()) + } + + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data Args<>::ArgsType>, + plugin: &mut Option>, + symbol_db: crate::symbol_db::SymbolDb<'data, Self::File>, + per_symbol_flags: crate::value_flags::PerSymbolFlags, + resolver: crate::resolution::Resolver<'data, Self::File>, + output_sections: crate::output_section_id::OutputSections<'data>, + layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: crate::OutputKind, + ) -> crate::Result>>; +} + +/// ELF-specific platform methods. Only implemented by ELF architecture backends. +pub(crate) trait ElfPlatform<'data>: Platform<'data, File = crate::elf::File<'data>> { + type Relaxation: Relaxation; + + // Get ELF header magic for the architecture. + fn elf_header_arch_magic() -> u16; + + // Get dynamic relocation value specific for the architecture. + fn get_dynamic_relocation_type(relocation: DynamicRelocationKind) -> u32; + + // Write PLT entry for the architecture. + fn write_plt_entry(plt_entry: &mut [u8], got_address: u64, plt_address: u64) -> Result; + + // Make architecture-specific parsing of the relocation types. + fn relocation_from_raw(r_type: u32) -> Result; + + // Get string representation of a relocation specific for the architecture. + fn rel_type_to_string(r_type: u32) -> Cow<'static, str>; + + // Get DTV OFFSET. + fn get_dtv_offset() -> u64 { + 0 + } + + // Some architectures use debug info relocation that depend on local symbols. + fn local_symbols_in_debug_info() -> bool; + + // Get position of the $tp (thread pointer) in the TLS section. Each platform defines + // a different place based on the following article: + // https://maskray.me/blog/2021-02-14-all-about-thread-local-storage#tls-variants + fn tp_offset_start(layout: &Layout<'data, elf_layout::ElfLayout<'data>>) -> u64; + + // Classify a GNU property note. + fn get_property_class(property_type: u32) -> Option; + + // Merge e_flags of the input files and provide an error + // if the flags are not compatible. + fn merge_eflags(eflags: impl Iterator) -> Result; + + // A list of high-part relocations that need to be tracked in a relocation cache + fn high_part_relocations() -> &'static [u32]; + + /// Whether the platform supports relaxations that reduce the sizes of function. + fn supports_size_reduction_relaxations() -> bool { + false + } + + /// Uses debug info, if available, to get information about where in the source code a + /// particular offset in a particular section came from. + fn get_source_info( + object: &crate::elf::File<'data>, + relocations: & as ObjectFile<'data>>::RelocationSections, + section: & as ObjectFile<'data>>::SectionHeader, + offset_in_section: u64, + ) -> Result; + + fn collect_relaxation_deltas( + _section_output_address: u64, + _section_bytes: &[u8], + _relocations: crate::elf::RelocationList<'data>, + _existing_deltas: Option<&SectionRelaxDeltas>, + _resolve_symbol: impl FnMut(object::SymbolIndex) -> Option, + ) -> (Vec<(u64, u32)>, Option) { + // This function should not be called unless `supports_size_reduction_relaxations` returns + // true in which case this function should be implemented. + unreachable!(); + } + + fn is_symbol_variant_pcs( + _object: &crate::elf::File<'data>, + _symbol_index: object::SymbolIndex, + ) -> bool { + false + } + + /// Tries to create a relaxation for the relocation of the specified kind, to be applied at the + /// specified offset in the supplied section. + fn new_relaxation( + relocation_kind: u32, + section_bytes: &[u8], + offset_in_section: u64, + flags: ValueFlags, + output_kind: OutputKind, + section_flags: as ObjectFile<'data>>::SectionFlags, + non_zero_address: bool, + relax_deltas: Option<&SectionRelaxDeltas>, + ) -> Option; + + fn process_riscv_attributes( + _object: &crate::elf::File<'data>, + _format_specific: &mut as ObjectFile<'data>>::FileLayoutState, + _riscv_attributes_section_index: object::SectionIndex, + ) -> Result { + bail!(".riscv.attribute section is supported only for riscv64 target"); + } + + /// ELF finish_link: handles plugin, version script, layout computation and writing. + fn finish_link( + file_loader: &mut crate::input_data::FileLoader<'data>, + args: &'data crate::args::Args, + plugin: &mut Option>, + mut symbol_db: crate::symbol_db::SymbolDb<'data, crate::elf::File<'data>>, + mut per_symbol_flags: crate::value_flags::PerSymbolFlags, + mut resolver: crate::resolution::Resolver<'data, crate::elf::File<'data>>, + mut output_sections: crate::output_section_id::OutputSections<'data>, + mut layout_rules_builder: crate::layout_rules::LayoutRulesBuilder<'data>, + output_kind: OutputKind, + ) -> Result>> where Self: Sized { + if let Some(plugin) = plugin.as_mut() + && plugin.is_initialised() + { + plugin.all_symbols_read( + &mut symbol_db, + &mut resolver, + file_loader, + &mut per_symbol_flags, + &mut output_sections, + &mut layout_rules_builder, + )?; + } + + if let crate::version_script::VersionScript::Rust(rust_vscript) = &symbol_db.version_script + { + symbol_db.handle_rust_version_script(rust_vscript, &mut per_symbol_flags); + } + + let layout_rules = layout_rules_builder.build(); + let resolved = resolver.resolve_sections_and_canonicalise_undefined( + &mut symbol_db, + &mut per_symbol_flags, + &mut output_sections, + &layout_rules, + )?; + + let mut output = crate::file_writer::Output::new(args, output_kind); + + let layout = crate::elf_layout::compute::( + symbol_db, + per_symbol_flags, + resolved, + output_sections, + &mut output, + )?; + + output.write(&layout, crate::elf_writer::write::)?; + + Ok(Some(layout.into_erased())) + } +} + +pub(crate) trait Relaxation { + fn apply(&self, section_bytes: &mut [u8], offset_in_section: &mut u64, addend: &mut i64); + + fn rel_info(&self) -> RelocationKindInfo; + + fn debug_kind(&self) -> impl std::fmt::Debug; + + fn next_modifier(&self) -> RelocationModifier; + + fn is_mandatory(&self) -> bool; +} + +pub(crate) struct RelaxSymbolInfo { + /// The symbol's approximate output address (section base + offset within section). + pub output_address: u64, + /// Whether the symbol may be interposed at runtime. + pub is_interposable: bool, +} + +/// Abstracts over the different object file formats that we support (or may support). e.g. ELF. +pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'data { + type Symbol: Symbol; + type SectionHeader: SectionHeader<'data, Self>; + type SectionFlags: SectionFlags; + type SectionType: SectionType; + type SectionAttributes: SectionAttributes; + type SectionIterator: Iterator; + type DynamicTagValues: DynamicTagValues<'data>; + type RelocationSections: std::fmt::Debug + Default + Send + Sync + 'static; + type RelocationList: Send + Sync + 'data; + type DynamicEntry: Send + Sync + 'data; + type VerneedTable: VerneedTable<'data>; + type EpilogueLayout: Send + Sync + 'static; + type DynamicLayoutState: Default + Send + Sync + 'data; + type DynamicLayout: std::fmt::Debug + Send + Sync + 'data; + type NonAddressableIndexes: NonAddressableIndexes + Send + Sync + 'data; + type NonAddressableCounts: Default + Send + Sync + 'data; + type GroupLayoutExt: std::fmt::Debug + Send + Sync + 'static; + type CommonGroupStateExt: Default + std::fmt::Debug + Send + Sync + 'static; + + /// An index into the local object's symbol versions. + type SymbolVersionIndex: Copy; + + /// Format-specific per-file state used during the layout phase. + type FileLayoutState: 'data; + + /// Format-specific properties produced by the layout phase. + type LayoutProperties: 'static; + + /// The name of a symbol, possibly with a version. + type RawSymbolName: RawSymbolName<'data>; + + /// For platforms that don't support symbol versioning, this can just be the unit type. + type VersionNames; + + /// The format-specific args type (e.g. `ElfArgs` or `PeArgs`). + type ArgsType: Send + Sync + 'static; + + fn parse_bytes(input: &'data [u8], is_dynamic: bool) -> Result; + + /// As for `parse_bytes` but also validates that the file architecture matches what is expected + /// based on `args`. + fn parse(input: &InputBytes<'data>, args: &Args) -> Result; + + fn is_dynamic(&self) -> bool; + + fn num_symbols(&self) -> usize; + + fn symbols(&self) -> &'data [Self::Symbol]; + + fn enumerate_symbols( + &self, + ) -> impl Iterator { + self.symbols() + .iter() + .enumerate() + .map(|(i, sym)| (object::SymbolIndex(i), sym)) + } + + // TODO: Remove implementations of this as this default should be fine. Perhaps first check if + // all platforms can get a slice of symbols. + fn symbols_iter(&self) -> impl Iterator { + self.symbols().iter() + } + + fn symbol(&self, index: object::SymbolIndex) -> Result<&'data Self::Symbol>; + + fn section_size(&self, header: &Self::SectionHeader) -> Result; + + fn symbol_name(&self, symbol: &Self::Symbol) -> Result<&'data [u8]>; + + fn num_sections(&self) -> usize; + + fn section_iter(&self) -> Self::SectionIterator; + + fn enumerate_sections( + &self, + ) -> impl Iterator; + + fn section(&self, index: object::SectionIndex) -> Result<&'data Self::SectionHeader>; + + fn section_by_name( + &self, + name: &str, + ) -> Option<(object::SectionIndex, &'data Self::SectionHeader)>; + + fn symbol_section( + &self, + symbol: &Self::Symbol, + index: object::SymbolIndex, + ) -> Result>; + + fn symbol_versions(&self) -> &[Self::SymbolVersionIndex]; + + /// The dynamic object will be linked against. This is a chance to perform extra initialisation + /// of `state`. + fn activate_dynamic(&self, state: &mut Self::DynamicLayoutState); + + fn dynamic_symbol_used( + &self, + symbol_index: object::SymbolIndex, + state: &mut Self::DynamicLayoutState, + ) -> Result; + + fn finalise_sizes_dynamic( + &self, + lib_name: &[u8], + state: &mut Self::DynamicLayoutState, + mem_sizes: &mut OutputSectionPartMap, + ) -> Result; + + fn apply_non_addressable_indexes_dynamic( + &self, + indexes: &mut Self::NonAddressableIndexes, + counts: &mut Self::NonAddressableCounts, + state: &mut Self::DynamicLayoutState, + ) -> Result; + + fn finalise_layout_dynamic( + &self, + state: Self::DynamicLayoutState, + memory_offsets: &mut OutputSectionPartMap, + section_layouts: &OutputSectionMap, + ) -> Self::DynamicLayout; + + fn new_epilogue_layout( + args: &Args, + output_kind: OutputKind, + dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], + ) -> Self::EpilogueLayout; + + fn apply_non_addressable_indexes_epilogue( + counts: &mut Self::NonAddressableCounts, + state: &mut Self::EpilogueLayout, + ); + + fn apply_non_addressable_indexes<'groups>( + symbol_db: &SymbolDb<'data, Self>, + counts: &Self::NonAddressableCounts, + mem_sizes_iter: impl Iterator>, + ); + + fn finalise_sizes_epilogue( + state: &mut Self::EpilogueLayout, + mem_sizes: &mut OutputSectionPartMap, + properties: &Self::LayoutProperties, + symbol_db: &SymbolDb<'data, Self>, + ); + + fn finalise_sizes_all( + mem_sizes: &mut OutputSectionPartMap, + symbol_db: &SymbolDb<'data, Self>, + ); + + fn apply_late_size_adjustments_epilogue( + state: &mut Self::EpilogueLayout, + current_sizes: &OutputSectionPartMap, + extra_sizes: &mut OutputSectionPartMap, + dynamic_symbol_defs: &[DynamicSymbolDefinition], + ) -> Result; + + fn finalise_layout_epilogue( + epilogue_state: &mut Self::EpilogueLayout, + memory_offsets: &mut OutputSectionPartMap, + symbol_db: &SymbolDb<'data, Self>, + common_state: &Self::LayoutProperties, + dynsym_start_index: u32, + dynamic_symbol_defs: &[DynamicSymbolDefinition], + ) -> Result; + + fn dynamic_tags(&self) -> Result<&'data [Self::DynamicEntry]>; + + fn section_name(&self, section_header: &Self::SectionHeader) -> Result<&'data [u8]>; + + /// Returns the raw section data. Doesn't handle decompression. + fn raw_section_data(&self, section: &Self::SectionHeader) -> Result<&'data [u8]>; + + fn section_data( + &self, + section: &Self::SectionHeader, + member: &bumpalo_herd::Member<'data>, + loaded_metrics: &LoadedMetrics, + ) -> Result<&'data [u8]>; + + /// Copies the data for the specified section into `out`, which must be the correct size. + /// Decompresses the data if necessary. + fn copy_section_data(&self, section: &Self::SectionHeader, out: &mut [u8]) -> Result; + + /// Returns the contents of a section as a Cow. Will heap-allocate if the section is compressed. + fn section_data_cow(&self, section: &Self::SectionHeader) -> Result>; + + fn section_alignment(&self, section: &Self::SectionHeader) -> Result; + + fn relocations( + &self, + index: object::SectionIndex, + relocations: &Self::RelocationSections, + ) -> Result; + + fn parse_relocations(&self) -> Result; + + /// Get the version of a symbol. Only intended for diagnostic purposes since it's potentially + /// quite slow. + fn symbol_version_debug(&self, symbol_index: object::SymbolIndex) -> Option; + + fn section_display_name(&self, index: object::SectionIndex) -> Cow<'data, str>; + + fn dynamic_tag_values(&self) -> Option; + + fn get_version_names(&self) -> Result; + + fn get_symbol_name_and_version( + &self, + symbol: &Self::Symbol, + local_index: usize, + version_names: &Self::VersionNames, + ) -> Result; + + fn verneed_table(&self) -> Result; + + fn process_gnu_note_section( + &self, + state: &mut Self::FileLayoutState, + section_index: object::SectionIndex, + ) -> Result; + + fn create_layout_properties<'states, 'files, P: ElfPlatform<'data>>( + _args: &Args, + _objects: impl Iterator, + _states: impl Iterator + Clone, + ) -> Result + where + 'data: 'files, + 'data: 'states, + { + unreachable!() + } + + fn load_exception_frame_data<'scope, P: ElfPlatform<'data>>( + _object: &mut elf_layout::ObjectLayoutState<'data>, + _common: &mut elf_layout::CommonGroupState<'data>, + _eh_frame_section_index: object::SectionIndex, + _resources: &'scope elf_layout::GraphResources<'data, '_>, + _queue: &mut elf_layout::LocalWorkQueue, + _scope: &Scope<'scope>, + ) -> Result { + unreachable!() + } + + /// Called when a section is loaded (not GCed). Implementations should process any exception + /// frame data related to the loaded section. + fn non_empty_section_loaded<'scope, P: ElfPlatform<'data>>( + _object: &mut elf_layout::ObjectLayoutState<'data>, + _common: &mut elf_layout::CommonGroupState<'data>, + _queue: &mut elf_layout::LocalWorkQueue, + _unloaded: UnloadedSection, + _resources: &'scope elf_layout::GraphResources<'data, 'scope>, + _scope: &Scope<'scope>, + ) -> Result { + unreachable!() + } + + fn finalise_group_layout(memory_offsets: &OutputSectionPartMap) -> Self::GroupLayoutExt; + + /// Called after GC phase has completed. Mostly useful for platform-specific logging. + fn finalise_find_required_sections(groups: &[elf_layout::GroupState]); + + fn pre_finalise_sizes_prelude(common: &mut elf_layout::CommonGroupState, args: &Args); + + fn finalise_object_sizes( + object: &mut elf_layout::ObjectLayoutState<'data>, + common: &mut elf_layout::CommonGroupState, + ); + + fn finalise_object_layout( + object: &elf_layout::ObjectLayoutState<'data>, + memory_offsets: &mut OutputSectionPartMap, + ); + + fn compute_object_addresses( + object: &elf_layout::ObjectLayoutState<'data>, + memory_offsets: &mut OutputSectionPartMap, + ); + + /// Resolves a reference to the frame data section. + fn frame_data_base_address(memory_offsets: &OutputSectionPartMap) -> u64; +} + +pub(crate) trait SectionHeader<'data, O: ObjectFile<'data>>: + std::fmt::Debug + Send + Sync + 'data +{ + fn flags(&self) -> O::SectionFlags; + + fn attributes(&self) -> O::SectionAttributes; + + fn section_type(&self) -> O::SectionType; +} + +pub(crate) trait SectionType: Copy { + fn is_note(self) -> bool; + + fn is_prog_bits(self) -> bool; + + /// Returns whether the section has no contents in the file (zero initialised). + fn is_no_bits(self) -> bool; +} + +pub(crate) trait SectionFlags: Copy + std::fmt::Debug + Send + Sync + 'static { + fn is_alloc(self) -> bool; + + fn is_writable(self) -> bool; + + fn is_executable(self) -> bool; + + fn is_tls(self) -> bool; + + fn is_merge_section(self) -> bool; + + fn is_strings(self) -> bool; + + fn should_retain(self) -> bool; + + fn should_exclude(&self) -> bool; + + fn is_group(self) -> bool; +} + +pub(crate) trait Symbol: std::fmt::Debug + Send + Sync + 'static { + /// Returns information about the symbol if it's a common symbol. Platforms that don't have + /// common symbols can just return None. + fn as_common(&self) -> Option; + + fn is_common(&self) -> bool { + self.as_common().is_some() + } + + fn is_undefined(&self) -> bool; + + fn is_local(&self) -> bool; + + fn is_absolute(&self) -> bool; + + fn is_weak(&self) -> bool; + + fn visibility(&self) -> crate::symbol_db::Visibility; + + fn value(&self) -> u64; + + fn size(&self) -> u64; + + fn section_index(&self) -> object::SectionIndex; + + fn has_name(&self) -> bool; + + fn debug_string(&self) -> String; + + /// Returns whether this symbol has been declared as a TLS variable. + fn is_tls(&self) -> bool; + + /// Returns whether this symbol can be interposed (overridden) at runtime by DSOs earlier in the + /// load order. + fn is_interposable(&self) -> bool; + + fn is_func(&self) -> bool; + + fn is_ifunc(&self) -> bool; + + fn is_hidden(&self) -> bool; + + fn is_gnu_unique(&self) -> bool; +} + +#[derive(Clone, Copy)] +pub(crate) struct CommonSymbol { + pub(crate) size: u64, + pub(crate) part_id: PartId, +} + +pub(crate) trait Relocation: Send + Sync + Copy + 'static { + type Sequence<'data>: RelocationSequence<'data>; + + fn symbol(&self) -> Option; + + fn raw_type(&self) -> u32; + + fn offset(&self) -> u64; + + fn addend(&self) -> i64; +} + +pub(crate) trait RelocationSequence<'data> { + type Rel: Relocation; + + fn rel_iter(&self) -> impl Iterator; + fn subsequence(&self, range: Range) -> Self; + fn num_relocations(&self) -> usize; +} + +pub(crate) trait RawSymbolName<'data>: Send + Sync + 'data { + fn parse(bytes: &'data [u8]) -> Self; + + fn name(&self) -> &'data [u8]; + + fn version_name(&self) -> Option<&'data [u8]>; + + fn is_default(&self) -> bool; +} + +pub(crate) trait VerneedTable<'data>: Send + Sync + 'data { + fn version_name(&self, local_symbol_index: object::SymbolIndex) -> Option<&'data [u8]>; +} + +pub(crate) trait DynamicTagValues<'data>: std::fmt::Debug + Send + Sync + 'data { + fn lib_name(&self, input: &InputRef<'data>) -> &'data [u8]; +} + +pub(crate) trait NonAddressableIndexes { + fn new<'data, O: ObjectFile<'data>>(symbol_db: &SymbolDb<'data, O>) -> Self; +} + +pub(crate) trait SectionAttributes: std::fmt::Debug + Send + Sync + 'static { + fn merge(&mut self, rhs: Self); + + fn apply(&self, output_sections: &mut OutputSections, section_id: OutputSectionId); +} + +pub(crate) struct SourceInfo(pub(crate) Option); + +pub(crate) enum PropertyClass { + // A bit in the output pr_data is set if it is set in any relocatable input. + // If all bits in the output pr_data field are zero, this property should be removed from + // output. + Or, + // A bit in the output pr_data field is set only if it is set in all relocatable input pr_data + // fields. If all bits in the output pr_data field are zero, this property should be + // removed from output. + And, + // A bit in the output pr_data field is set if it is set in any relocatable input pr_data + // fields and this property is present in all relocatable input files. When all bits in + // the output pr_data field are zero, this property should not be removed from output to + // indicate it has zero in all bits. + AndOr, +} + +#[derive(Debug)] +pub(crate) struct SourceInfoDetails { + pub(crate) path: PathBuf, + pub(crate) line: u64, +} + +/// An index into the exception frames for an object. Interpretation of the value is up to the +/// platform. +#[derive(Debug, Clone, Copy)] +pub(crate) struct FrameIndex(NonZeroU32); + +impl FrameIndex { + pub(crate) fn from_usize(raw: usize) -> Self { + Self(NonZeroU32::new(raw as u32 + 1).unwrap()) + } + + pub(crate) fn as_usize(self) -> usize { + self.0.get() as usize - 1 + } +} diff --git a/libwild/src/resolution.rs b/libwild/src/resolution.rs index f22d3f7b7..1db5cfb17 100644 --- a/libwild/src/resolution.rs +++ b/libwild/src/resolution.rs @@ -2,7 +2,7 @@ //! entries are needed. We also resolve which output section, if any, each input section should be //! assigned to. -use crate::LayoutRules; +use crate::layout_rules::LayoutRules; use crate::alignment::Alignment; use crate::args::Args; use crate::bail; diff --git a/libwild/src/symbol_db.rs b/libwild/src/symbol_db.rs index ea6b5e09b..91963ded5 100644 --- a/libwild/src/symbol_db.rs +++ b/libwild/src/symbol_db.rs @@ -1,7 +1,7 @@ //! Reads global symbols for each input file and builds a map from symbol names to IDs together with //! information about where each symbol can be obtained. -use crate::InputLinkerScript; +use crate::input_data::InputLinkerScript; use crate::OutputKind; use crate::args; use crate::args::Args; diff --git a/libwild/src/validation.rs b/libwild/src/validation.rs index ad10047d3..f84357316 100644 --- a/libwild/src/validation.rs +++ b/libwild/src/validation.rs @@ -3,6 +3,7 @@ use crate::bail; use crate::error::Context as _; use crate::error::Result; +use crate::elf_layout::ElfLayout; use crate::layout::Layout; use crate::platform::ObjectFile as _; use linker_utils::elf::secnames::GOT_SECTION_NAME_STR; @@ -10,7 +11,7 @@ use object::LittleEndian; use object::read::elf::SectionHeader as _; use zerocopy::FromBytes; -pub(crate) fn validate_bytes(layout: &Layout, file_bytes: &[u8]) -> Result { +pub(crate) fn validate_bytes<'data>(layout: &Layout<'data, ElfLayout<'data>>, file_bytes: &[u8]) -> Result { let object = crate::elf::File::parse_bytes(file_bytes, true) .context("Failed to parse our output file")?; validate_object(&object, layout).context("Output validation failed") @@ -18,7 +19,7 @@ pub(crate) fn validate_bytes(layout: &Layout, file_bytes: &[u8]) -> Result { /// Checks that what we actually wrote to our output file matches what we intended to write in /// `layout`. -fn validate_object(object: &crate::elf::File, layout: &Layout) -> Result { +fn validate_object<'data>(object: &crate::elf::File, layout: &Layout<'data, ElfLayout<'data>>) -> Result { if layout.symbol_db.output_kind.is_relocatable() { // For now, we don't do any validation of relocatable outputs. The only thing we're // currently validating is GOT entries and they'll all have dynamic relocations. @@ -41,7 +42,7 @@ fn validate_object(object: &crate::elf::File, layout: &Layout) -> Result { for group in &layout.group_layouts { for file in &group.files { match file { - crate::layout::FileLayout::Object(obj) => { + crate::elf_layout::FileLayout::Object(obj) => { for (sec_index, sec) in obj.object.sections.enumerate() { if let Some(resolution) = obj.section_resolutions[sec_index.0].full_resolution() diff --git a/libwild/src/verification.rs b/libwild/src/verification.rs index 0158c754b..6d4b82f9e 100644 --- a/libwild/src/verification.rs +++ b/libwild/src/verification.rs @@ -3,7 +3,7 @@ use crate::bail; use crate::error::Result; -use crate::layout::FileLayout; +use crate::elf_layout::FileLayout; use crate::output_section_id::OutputOrder; use crate::output_section_id::OutputSections; use crate::output_section_part_map::OutputSectionPartMap; From 8434ccb562c4879e77bd866575e18dff5f7ba173 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Fri, 6 Mar 2026 19:42:22 +1300 Subject: [PATCH 09/10] remove early testing stuff --- Cargo.lock | 77 - Cargo.toml | 2 - docs/docs.md | 4 - justfile | 6 +- kernel32.dump | 8313 ----------------- windows/wlibwild/Cargo.toml | 39 - windows/wlibwild/done.txzt | 3 - windows/wlibwild/example-linkerflags-rust.txt | 35 - windows/wlibwild/src/bin/main.rs | 3 - windows/wlibwild/src/lib.rs | 201 - windows/wlibwild/src/paths.rs | 204 - windows/wlibwild/src/subprocess.rs | 179 - windows/wlibwild/w.just | 23 - 13 files changed, 3 insertions(+), 9086 deletions(-) delete mode 100644 docs/docs.md delete mode 100644 kernel32.dump delete mode 100644 windows/wlibwild/Cargo.toml delete mode 100644 windows/wlibwild/done.txzt delete mode 100644 windows/wlibwild/example-linkerflags-rust.txt delete mode 100644 windows/wlibwild/src/bin/main.rs delete mode 100644 windows/wlibwild/src/lib.rs delete mode 100644 windows/wlibwild/src/paths.rs delete mode 100644 windows/wlibwild/src/subprocess.rs delete mode 100644 windows/wlibwild/w.just diff --git a/Cargo.lock b/Cargo.lock index 78f9cb29f..8550a2eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,26 +215,6 @@ version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" -[[package]] -name = "bytemuck" -version = "1.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "byteorder" version = "1.5.0" @@ -1109,15 +1089,6 @@ dependencies = [ "widestring", ] -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1717,15 +1688,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -2138,7 +2100,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", - "nu-ansi-term", "once_cell", "regex-automata", "sharded-slab", @@ -2214,16 +2175,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "wasip2" version = "1.0.2+wasi-0.2.9" @@ -2388,15 +2339,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2594,25 +2536,6 @@ dependencies = [ "wasmparser", ] -[[package]] -name = "wlibwild" -version = "0.8.0" -dependencies = [ - "anyhow", - "bytemuck", - "bytesize", - "colored", - "indexmap", - "itertools", - "object 0.38.1", - "phnt", - "rayon", - "tracing", - "tracing-subscriber", - "walkdir", - "windows-sys 0.61.2", -] - [[package]] name = "zerocopy" version = "0.8.39" diff --git a/Cargo.toml b/Cargo.toml index 06a0a456f..e83089dae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ members = [ "wild", "libwild", "benchmarks/runner", - "windows/wlibwild", ] resolver = "2" @@ -31,7 +30,6 @@ ar = "0.9.0" atomic-take = "1.0.0" bitflags = "2.4.0" blake3 = { version = "1.0.0", features = ["rayon"] } -bytemuck = { version = "1.0.0", features = ["derive"] } bumpalo-herd = "0.1.2" bytesize = "2.0.0" clap = { version = "4.1.0", features = ["derive"] } diff --git a/docs/docs.md b/docs/docs.md deleted file mode 100644 index f1461c064..000000000 --- a/docs/docs.md +++ /dev/null @@ -1,4 +0,0 @@ -# Documentation Related to Linking - - -## [Windows Docs](windows/windows.md) \ No newline at end of file diff --git a/justfile b/justfile index 932442935..12e7d1113 100644 --- a/justfile +++ b/justfile @@ -1,10 +1,10 @@ -mod w "windows/wlibwild/w.just" - +# list all available just targets default: - @just w + @just --list +# Dump the symbol table of kernel32.lib using llvm-objdump dump-kernel32: @llvm-objdump -a -t "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib" > kernel32.dump diff --git a/kernel32.dump b/kernel32.dump deleted file mode 100644 index 508100375..000000000 --- a/kernel32.dump +++ /dev/null @@ -1,8313 +0,0 @@ - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 ---------- 0/0 498 (date: "-1" contains non-decimal chars) KERNEL32.dll - -SYMBOL TABLE: -[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id -[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __IMPORT_DESCRIPTOR_KERNEL32 -[ 2](sec 2)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$2 -[ 3](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 -[ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$4 -[ 5](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0xc0000040 .idata$5 -[ 6](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR -[ 7](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 KERNEL32_NULL_THUNK_DATA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 ---------- 0/0 251 (date: "-1" contains non-decimal chars) KERNEL32.dll - -SYMBOL TABLE: -[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id -[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format coff-x86-64 ---------- 0/0 288 (date: "-1" contains non-decimal chars) KERNEL32.dll - -SYMBOL TABLE: -[ 0](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x0101784b @comp.id -[ 1](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 KERNEL32_NULL_THUNK_DATA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AcquireSRWLockExclusive -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AcquireSRWLockExclusive - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AcquireSRWLockShared -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AcquireSRWLockShared - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ActivateActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ActivateActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ActivatePackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ActivatePackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddAtomA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddAtomA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddAtomW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddAtomW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddConsoleAliasA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddConsoleAliasA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddConsoleAliasW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddConsoleAliasW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddDllDirectory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddDllDirectory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddIntegrityLabelToBoundaryDescriptor -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddIntegrityLabelToBoundaryDescriptor - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddLocalAlternateComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddLocalAlternateComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddLocalAlternateComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddLocalAlternateComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddRefActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddRefActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddResourceAttributeAce -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddResourceAttributeAce - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddSIDToBoundaryDescriptor -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddSIDToBoundaryDescriptor - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddScopedPolicyIDAce -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddScopedPolicyIDAce - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddSecureMemoryCacheCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddSecureMemoryCacheCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddVectoredContinueHandler -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddVectoredContinueHandler - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AddVectoredExceptionHandler -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AddVectoredExceptionHandler - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocateUserPhysicalPages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocateUserPhysicalPages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AllocateUserPhysicalPagesNuma -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AllocateUserPhysicalPagesNuma - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetClrCompat -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetClrCompat - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetCreateFileAccess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetCreateFileAccess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetLifecycleManagement -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetLifecycleManagement - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetMediaFoundationCodecLoading -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetMediaFoundationCodecLoading - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetProcessTerminationMethod -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetProcessTerminationMethod - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetShowDeveloperDiagnostic -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetShowDeveloperDiagnostic - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetThreadInitializationType -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetThreadInitializationType - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppPolicyGetWindowingModel -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppPolicyGetWindowingModel - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AppXGetOSMaxVersionTested -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AppXGetOSMaxVersionTested - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ApplicationRecoveryFinished -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ApplicationRecoveryFinished - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ApplicationRecoveryInProgress -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ApplicationRecoveryInProgress - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AreFileApisANSI -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AreFileApisANSI - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AreShortNamesEnabled -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AreShortNamesEnabled - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AssignProcessToJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AssignProcessToJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_AttachConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 AttachConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupRead -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupRead - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupSeek -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupSeek - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BackupWrite -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BackupWrite - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BaseGetNamedObjectDirectory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BaseGetNamedObjectDirectory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BaseSetLastNTError -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BaseSetLastNTError - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 38 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Beep -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Beep - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BeginUpdateResourceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BeginUpdateResourceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BeginUpdateResourceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BeginUpdateResourceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BindIoCompletionCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BindIoCompletionCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBAndTimeoutsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBAndTimeoutsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBAndTimeoutsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBAndTimeoutsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildCommDCBW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildCommDCBW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingCancelRequest -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingCancelRequest - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingFlushFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingFlushFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingReadFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingReadFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingRegisterBuffers -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingRegisterBuffers - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingRegisterFileHandles -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingRegisterFileHandles - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_BuildIoRingWriteFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 BuildIoRingWriteFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallNamedPipeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallNamedPipeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallNamedPipeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallNamedPipeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CallbackMayRunLong -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CallbackMayRunLong - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelDeviceWakeupRequest -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelDeviceWakeupRequest - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelIoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelIoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelSynchronousIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelSynchronousIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelThreadpoolIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelThreadpoolIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelTimerQueueTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelTimerQueueTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CancelWaitableTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CancelWaitableTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CeipIsOptedIn -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CeipIsOptedIn - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ChangeTimerQueueTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ChangeTimerQueueTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckElevation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckElevation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckElevationEnabled -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckElevationEnabled - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckNameLegalDOS8Dot3A -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckNameLegalDOS8Dot3A - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckNameLegalDOS8Dot3W -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckNameLegalDOS8Dot3W - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckRemoteDebuggerPresent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckRemoteDebuggerPresent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckTokenCapability -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckTokenCapability - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CheckTokenMembershipEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CheckTokenMembershipEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClearCommBreak -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClearCommBreak - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClearCommError -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClearCommError - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseIoRing -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseIoRing - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePackageInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePackageInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePrivateNamespace -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePrivateNamespace - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ClosePseudoConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ClosePseudoConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpool -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpool - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolCleanupGroup -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolCleanupGroup - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolCleanupGroupMembers -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolCleanupGroupMembers - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolWait -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolWait - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CloseThreadpoolWork -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CloseThreadpoolWork - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CommConfigDialogA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CommConfigDialogA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CommConfigDialogW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CommConfigDialogW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringOrdinal -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringOrdinal - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CompareStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CompareStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConnectNamedPipe -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConnectNamedPipe - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ContinueDebugEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ContinueDebugEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertDefaultLocale -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertDefaultLocale - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertFiberToThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertFiberToThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertThreadToFiber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertThreadToFiber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ConvertThreadToFiberEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ConvertThreadToFiberEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFile2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFile2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CopyFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CopyFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateActCtxA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateActCtxA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateActCtxW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateActCtxW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateBoundaryDescriptorA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateBoundaryDescriptorA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateBoundaryDescriptorW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateBoundaryDescriptorW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateConsoleScreenBuffer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateConsoleScreenBuffer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEnclave -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEnclave - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateEventW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateEventW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFiber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFiber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFiberEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFiberEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFile2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFile2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingFromApp -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingFromApp - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingNumaA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingNumaA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingNumaW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingNumaW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileMappingW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileMappingW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateHardLinkW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateHardLinkW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateIoCompletionPort -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateIoCompletionPort - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateIoRing -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateIoRing - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobObjectA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobObjectA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobObjectW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobObjectW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateJobSet -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateJobSet - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMailslotA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMailslotA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMailslotW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMailslotW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMemoryResourceNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMemoryResourceNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateMutexW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateMutexW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateNamedPipeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateNamedPipeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateNamedPipeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateNamedPipeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePipe -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePipe - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePrivateNamespaceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePrivateNamespaceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePrivateNamespaceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePrivateNamespaceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateProcessA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateProcessA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateProcessW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateProcessW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreatePseudoConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreatePseudoConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateRemoteThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateRemoteThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateRemoteThreadEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateRemoteThreadEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSemaphoreW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSemaphoreW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateSymbolicLinkW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateSymbolicLinkW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTapePartition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTapePartition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpool -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpool - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolCleanupGroup -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolCleanupGroup - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolWait -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolWait - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateThreadpoolWork -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateThreadpoolWork - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTimerQueue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTimerQueue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateTimerQueueTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateTimerQueueTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateToolhelp32Snapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateToolhelp32Snapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateUmsCompletionList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateUmsCompletionList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateUmsThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateUmsThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CreateWaitableTimerW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CreateWaitableTimerW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_CtrlRoutine -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 CtrlRoutine - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeactivateActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeactivateActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeactivatePackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeactivatePackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugActiveProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugActiveProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugActiveProcessStop -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugActiveProcessStop - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugBreak -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugBreak - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugBreakProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugBreakProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DebugSetProcessKillOnExit -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DebugSetProcessKillOnExit - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DecodePointer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DecodePointer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DecodeSystemPointer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DecodeSystemPointer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DefineDosDeviceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DefineDosDeviceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DefineDosDeviceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DefineDosDeviceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DelayLoadFailureHook -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DelayLoadFailureHook - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteAtom -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteAtom - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteBoundaryDescriptor -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteBoundaryDescriptor - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteCriticalSection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteCriticalSection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFiber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFiber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteProcThreadAttributeList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteProcThreadAttributeList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteSynchronizationBarrier -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteSynchronizationBarrier - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueueEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueueEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteTimerQueueTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteTimerQueueTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteUmsCompletionList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteUmsCompletionList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteUmsThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteUmsThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteVolumeMountPointA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteVolumeMountPointA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeleteVolumeMountPointW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeleteVolumeMountPointW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DequeueUmsCompletionListItems -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DequeueUmsCompletionListItems - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DeviceIoControl -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DeviceIoControl - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisableThreadLibraryCalls -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisableThreadLibraryCalls - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisableThreadProfiling -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisableThreadProfiling - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisassociateCurrentThreadFromCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisassociateCurrentThreadFromCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DiscardVirtualMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DiscardVirtualMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DisconnectNamedPipe -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DisconnectNamedPipe - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DnsHostnameToComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DnsHostnameToComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DosDateTimeToFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DosDateTimeToFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DosPathToSessionPathW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DosPathToSessionPathW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DuplicateHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DuplicateHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_DuplicatePackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 DuplicatePackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnableProcessOptionalXStateFeatures -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnableProcessOptionalXStateFeatures - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnableThreadProfiling -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnableThreadProfiling - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EncodePointer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EncodePointer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EncodeSystemPointer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EncodeSystemPointer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EndUpdateResourceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EndUpdateResourceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EndUpdateResourceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EndUpdateResourceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterCriticalSection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterCriticalSection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterSynchronizationBarrier -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterSynchronizationBarrier - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnterUmsSchedulingMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnterUmsSchedulingMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumCalendarInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumCalendarInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumDateFormatsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumDateFormatsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumLanguageGroupLocalesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumLanguageGroupLocalesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumLanguageGroupLocalesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumLanguageGroupLocalesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceLanguagesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceLanguagesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceNamesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceNamesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumResourceTypesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumResourceTypesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemCodePagesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemCodePagesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemCodePagesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemCodePagesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemFirmwareTables -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemFirmwareTables - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemGeoID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemGeoID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemGeoNames -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemGeoNames - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLanguageGroupsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLanguageGroupsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLanguageGroupsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLanguageGroupsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumSystemLocalesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumSystemLocalesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumTimeFormatsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumTimeFormatsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumUILanguagesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumUILanguagesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumUILanguagesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumUILanguagesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumerateLocalComputerNamesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumerateLocalComputerNamesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EnumerateLocalComputerNamesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EnumerateLocalComputerNamesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EraseTape -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EraseTape - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_EscapeCommFunction -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 EscapeCommFunction - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExecuteUmsThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExecuteUmsThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExitProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExitProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExitThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExitThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExpandEnvironmentStringsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExpandEnvironmentStringsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ExpandEnvironmentStringsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ExpandEnvironmentStringsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalAppExitA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalAppExitA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalAppExitW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalAppExitW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FatalExit -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FatalExit - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToDosDateTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToDosDateTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToLocalFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToLocalFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FileTimeToSystemTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FileTimeToSystemTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputCharacterA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputCharacterA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FillConsoleOutputCharacterW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FillConsoleOutputCharacterW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionGuid -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionGuid - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindActCtxSectionStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindActCtxSectionStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindAtomA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindAtomA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindAtomW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindAtomW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindClose -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindClose - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindCloseChangeNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindCloseChangeNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstChangeNotificationA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstChangeNotificationA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstChangeNotificationW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstChangeNotificationW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileNameTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileNameTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstStreamTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstStreamTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstStreamW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstStreamW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeMountPointA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeMountPointA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeMountPointW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeMountPointW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindFirstVolumeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindFirstVolumeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNLSString -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNLSString - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNLSStringEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNLSStringEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextChangeNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextChangeNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextStreamW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextStreamW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeMountPointA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeMountPointA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeMountPointW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeMountPointW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindNextVolumeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindNextVolumeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindPackagesByPackageFamily -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindPackagesByPackageFamily - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindResourceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindResourceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindStringOrdinal -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindStringOrdinal - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindVolumeClose -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindVolumeClose - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FindVolumeMountPointClose -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FindVolumeMountPointClose - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsGetValue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsGetValue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlsSetValue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlsSetValue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushConsoleInputBuffer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushConsoleInputBuffer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushFileBuffers -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushFileBuffers - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushInstructionCache -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushInstructionCache - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushProcessWriteBuffers -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushProcessWriteBuffers - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FlushViewOfFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FlushViewOfFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FoldStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FoldStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FoldStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FoldStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatApplicationUserModelId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatApplicationUserModelId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatMessageA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatMessageA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FormatMessageW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FormatMessageW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeEnvironmentStringsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeEnvironmentStringsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeEnvironmentStringsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeEnvironmentStringsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibrary -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibrary - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibraryAndExitThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibraryAndExitThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeLibraryWhenCallbackReturns -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeLibraryWhenCallbackReturns - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeMemoryJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeMemoryJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeResource -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeResource - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_FreeUserPhysicalPages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 FreeUserPhysicalPages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GenerateConsoleCtrlEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GenerateConsoleCtrlEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetACP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetACP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetActiveProcessorCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetActiveProcessorCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetActiveProcessorGroupCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetActiveProcessorGroupCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAppContainerAce -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAppContainerAce - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAppContainerNamedObjectPath -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAppContainerNamedObjectPath - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationRecoveryCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationRecoveryCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationRestartSettings -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationRestartSettings - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetApplicationUserModelId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetApplicationUserModelId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAtomNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAtomNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetAtomNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetAtomNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryType -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryType - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryTypeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryTypeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetBinaryTypeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetBinaryTypeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfoExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfoExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCPInfoExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCPInfoExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCachedSigningLevel -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCachedSigningLevel - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCalendarInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCalendarInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommConfig -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommConfig - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommModemStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommModemStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommProperties -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommProperties - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommTimeouts -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommTimeouts - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommandLineA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommandLineA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCommandLineW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCommandLineW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCompressedFileSizeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCompressedFileSizeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesLengthA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesLengthA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesLengthW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesLengthW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasExesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasExesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesLengthA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesLengthA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesLengthW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesLengthW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleAliasesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleAliasesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleCP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleCP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleCursorInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleCursorInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleDisplayMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleDisplayMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleFontSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleFontSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleHistoryInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleHistoryInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOriginalTitleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOriginalTitleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOriginalTitleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOriginalTitleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleOutputCP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleOutputCP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleProcessList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleProcessList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleScreenBufferInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleScreenBufferInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleScreenBufferInfoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleScreenBufferInfoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleSelectionInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleSelectionInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleTitleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleTitleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleTitleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleTitleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetConsoleWindow -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetConsoleWindow - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrencyFormatW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrencyFormatW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentApplicationUserModelId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentApplicationUserModelId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentConsoleFont -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentConsoleFont - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentConsoleFontEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentConsoleFontEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageFamilyName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageFamilyName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackagePath -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackagePath - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentPackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentPackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessorNumber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessorNumber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentProcessorNumberEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentProcessorNumberEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThreadId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThreadId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentThreadStackLimits -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentThreadStackLimits - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetCurrentUmsThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetCurrentUmsThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDateFormatW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDateFormatW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDefaultCommConfigA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDefaultCommConfigA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDefaultCommConfigW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDefaultCommConfigW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDevicePowerState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDevicePowerState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskFreeSpaceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskFreeSpaceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskSpaceInformationA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskSpaceInformationA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDiskSpaceInformationW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDiskSpaceInformationW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDllDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDllDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDllDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDllDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDriveTypeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDriveTypeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDriveTypeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDriveTypeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDurationFormat -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDurationFormat - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDurationFormatEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDurationFormatEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetDynamicTimeZoneInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetDynamicTimeZoneInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnabledXStateFeatures -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnabledXStateFeatures - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStrings -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStrings - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStringsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStringsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentStringsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentStringsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentVariableA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentVariableA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEnvironmentVariableW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEnvironmentVariableW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetEraNameCountedString -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetEraNameCountedString - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetErrorMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetErrorMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetExitCodeProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetExitCodeProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetExitCodeThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetExitCodeThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileAttributesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileAttributesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileBandwidthReservation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileBandwidthReservation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileInformationByHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileInformationByHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileInformationByHandleEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileInformationByHandleEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileMUIInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileMUIInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileMUIPath -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileMUIPath - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileSizeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileSizeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFileType -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFileType - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFinalPathNameByHandleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFinalPathNameByHandleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFinalPathNameByHandleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFinalPathNameByHandleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareEnvironmentVariableW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareEnvironmentVariableW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFirmwareType -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFirmwareType - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetFullPathNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetFullPathNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetGeoInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetGeoInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetHandleInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetHandleInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetIoRingInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetIoRingInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLargePageMinimum -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLargePageMinimum - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLargestConsoleWindowSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLargestConsoleWindowSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLastError -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLastError - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocalTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocalTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLocaleInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLocaleInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDriveStringsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDriveStringsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDriveStringsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDriveStringsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalDrives -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalDrives - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalProcessorInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalProcessorInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLogicalProcessorInformationEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLogicalProcessorInformationEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetLongPathNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetLongPathNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMachineTypeAttributes -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMachineTypeAttributes - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMailslotInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMailslotInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMaximumProcessorCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMaximumProcessorCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMaximumProcessorGroupCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMaximumProcessorGroupCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetMemoryErrorHandlingCapabilities -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetMemoryErrorHandlingCapabilities - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleFileNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleFileNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetModuleHandleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetModuleHandleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNLSVersion -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNLSVersion - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNLSVersionEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNLSVersionEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientProcessId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientProcessId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeClientSessionId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeClientSessionId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeHandleStateA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeHandleStateA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeHandleStateW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeHandleStateW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeServerProcessId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeServerProcessId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNamedPipeServerSessionId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNamedPipeServerSessionId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNativeSystemInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNativeSystemInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNextUmsListItem -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNextUmsListItem - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaAvailableMemoryNode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaAvailableMemoryNode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaAvailableMemoryNodeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaAvailableMemoryNodeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaHighestNodeNumber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaHighestNodeNumber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeNumberFromHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeNumberFromHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMask2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMask2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaNodeProcessorMaskEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaNodeProcessorMaskEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProcessorNode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProcessorNode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProcessorNodeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProcessorNodeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProximityNode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProximityNode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumaProximityNodeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumaProximityNodeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberFormatW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberFormatW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberOfConsoleInputEvents -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberOfConsoleInputEvents - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetNumberOfConsoleMouseButtons -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetNumberOfConsoleMouseButtons - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOEMCP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOEMCP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOverlappedResult -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOverlappedResult - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetOverlappedResultEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetOverlappedResultEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageApplicationIds -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageApplicationIds - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageFamilyName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageFamilyName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackageInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackageInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagePath -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagePath - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagePathByFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagePathByFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPackagesByPackageFamily -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPackagesByPackageFamily - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPhysicallyInstalledSystemMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPhysicallyInstalledSystemMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPriorityClass -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPriorityClass - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileIntA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileIntA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileIntW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileIntW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionNamesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionNamesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionNamesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionNamesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileSectionW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileSectionW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStructA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStructA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetPrivateProfileStructW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetPrivateProfileStructW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcAddress -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcAddress - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessAffinityMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessAffinityMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDEPPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDEPPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDefaultCpuSetMasks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDefaultCpuSetMasks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessDefaultCpuSets -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessDefaultCpuSets - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessGroupAffinity -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessGroupAffinity - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHandleCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHandleCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHeap -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHeap - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessHeaps -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessHeaps - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessIdOfThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessIdOfThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessIoCounters -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessIoCounters - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessMitigationPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessMitigationPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessPriorityBoost -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessPriorityBoost - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessShutdownParameters -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessShutdownParameters - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessTimes -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessTimes - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessVersion -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessVersion - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessWorkingSetSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessWorkingSetSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessWorkingSetSizeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessWorkingSetSizeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessesInVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessesInVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProcessorSystemCycleTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProcessorSystemCycleTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProductInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProductInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileIntA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileIntA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileIntW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileIntW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileSectionA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileSectionA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileSectionW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileSectionW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetProfileStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetProfileStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetQueuedCompletionStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetQueuedCompletionStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetQueuedCompletionStatusEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetQueuedCompletionStatusEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetShortPathNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetShortPathNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetShortPathNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetShortPathNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStagedPackagePathByFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStagedPackagePathByFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStartupInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStartupInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStartupInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStartupInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStateFolder -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStateFolder - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStdHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStdHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringScripts -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringScripts - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetStringTypeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetStringTypeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemAppDataKey -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemAppDataKey - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemCpuSetInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemCpuSetInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDEPPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDEPPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLCID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLCID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLangID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLangID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultLocaleName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultLocaleName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDefaultUILanguage -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDefaultUILanguage - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemFileCacheSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemFileCacheSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemFirmwareTable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemFirmwareTable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemPowerStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemPowerStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemRegistryQuota -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemRegistryQuota - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimeAdjustment -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimeAdjustment - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimeAsFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimeAsFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimePreciseAsFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimePreciseAsFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemTimes -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemTimes - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWindowsDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWindowsDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWindowsDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWindowsDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWow64DirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWow64DirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetSystemWow64DirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetSystemWow64DirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapeParameters -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapeParameters - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapePosition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapePosition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTapeStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTapeStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempFileNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempFileNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPath2A -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPath2A - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPath2W -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPath2W - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPathA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPathA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTempPathW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTempPathW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadDescription -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadDescription - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadEnabledXStateFeatures -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadEnabledXStateFeatures - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadErrorMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadErrorMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadGroupAffinity -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadGroupAffinity - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadIOPendingFlag -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadIOPendingFlag - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadIdealProcessorEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadIdealProcessorEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadLocale -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadLocale - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPriority -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPriority - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadPriorityBoost -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadPriorityBoost - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectedCpuSetMasks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectedCpuSetMasks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectedCpuSets -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectedCpuSets - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadSelectorEntry -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadSelectorEntry - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadTimes -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadTimes - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetThreadUILanguage -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetThreadUILanguage - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTickCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTickCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTickCount64 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTickCount64 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeFormatW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeFormatW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeZoneInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeZoneInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetTimeZoneInformationForYear -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetTimeZoneInformationForYear - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUILanguageInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUILanguageInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUmsCompletionListEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUmsCompletionListEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUmsSystemThreadInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUmsSystemThreadInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultGeoName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultGeoName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLCID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLCID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLangID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLangID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultLocaleName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultLocaleName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserDefaultUILanguage -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserDefaultUILanguage - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserGeoID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserGeoID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetUserPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetUserPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersion -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersion - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersionExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersionExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVersionExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVersionExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationByHandleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationByHandleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeInformationW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeInformationW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeNameForVolumeMountPointA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeNameForVolumeMountPointA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumeNameForVolumeMountPointW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumeNameForVolumeMountPointW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNamesForVolumeNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNamesForVolumeNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetVolumePathNamesForVolumeNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetVolumePathNamesForVolumeNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWindowsDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWindowsDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWindowsDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWindowsDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetWriteWatch -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetWriteWatch - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GetXStateFeaturesMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GetXStateFeaturesMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAddAtomW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAddAtomW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalCompact -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalCompact - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalDeleteAtom -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalDeleteAtom - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFindAtomA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFindAtomA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFindAtomW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFindAtomW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFix -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFix - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFlags -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFlags - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalGetAtomNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalGetAtomNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalGetAtomNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalGetAtomNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalLock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalLock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalMemoryStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalMemoryStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalMemoryStatusEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalMemoryStatusEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalReAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalReAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnWire -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnWire - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnfix -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnfix - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalUnlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalUnlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_GlobalWire -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 GlobalWire - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32First -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32First - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32ListFirst -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32ListFirst - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32ListNext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32ListNext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Heap32Next -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Heap32Next - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapCompact -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapCompact - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapCreate -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapCreate - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapDestroy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapDestroy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapLock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapLock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapQueryInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapQueryInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapReAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapReAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSetInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSetInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapSummary -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapSummary - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapUnlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapUnlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapValidate -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapValidate - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_HeapWalk -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 HeapWalk - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitAtomTable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitAtomTable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceBeginInitialize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceBeginInitialize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceComplete -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceComplete - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceExecuteOnce -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceExecuteOnce - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitOnceInitialize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitOnceInitialize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeConditionVariable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeConditionVariable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeContext2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeContext2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSectionAndSpinCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSectionAndSpinCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeCriticalSectionEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeCriticalSectionEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeEnclave -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeEnclave - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeProcThreadAttributeList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeProcThreadAttributeList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSListHead -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSListHead - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSRWLock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSRWLock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InitializeSynchronizationBarrier -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InitializeSynchronizationBarrier - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InstallELAMCertificateInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InstallELAMCertificateInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedFlushSList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedFlushSList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPopEntrySList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPopEntrySList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushEntrySList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushEntrySList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushListSList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushListSList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_InterlockedPushListSListEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 InterlockedPushListSListEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadCodePtr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadCodePtr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadHugeReadPtr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadHugeReadPtr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadHugeWritePtr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadHugeWritePtr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadReadPtr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadReadPtr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadStringPtrA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadStringPtrA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadStringPtrW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadStringPtrW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsBadWritePtr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsBadWritePtr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDBCSLeadByte -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDBCSLeadByte - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDBCSLeadByteEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDBCSLeadByteEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsDebuggerPresent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsDebuggerPresent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsEnclaveTypeSupported -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsEnclaveTypeSupported - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsIoRingOpSupported -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsIoRingOpSupported - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNLSDefinedString -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNLSDefinedString - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNativeVhdBoot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNativeVhdBoot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsNormalizedString -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsNormalizedString - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessCritical -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessCritical - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessInJob -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessInJob - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsProcessorFeaturePresent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsProcessorFeaturePresent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsSystemResumeAutomatic -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsSystemResumeAutomatic - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsThreadAFiber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsThreadAFiber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsThreadpoolTimerSet -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsThreadpoolTimerSet - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsUserCetAvailableInEnvironment -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsUserCetAvailableInEnvironment - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidCodePage -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidCodePage - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLanguageGroup -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLanguageGroup - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLocale -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLocale - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidLocaleName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidLocaleName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsValidNLSVersion -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsValidNLSVersion - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64GuestMachineSupported -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64GuestMachineSupported - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64Process -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64Process - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_IsWow64Process2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 IsWow64Process2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EmptyWorkingSet -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EmptyWorkingSet - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumDeviceDrivers -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumDeviceDrivers - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumPageFilesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumPageFilesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumPageFilesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumPageFilesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcessModules -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcessModules - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcessModulesEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcessModulesEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32EnumProcesses -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32EnumProcesses - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverBaseNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverBaseNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverBaseNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverBaseNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverFileNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverFileNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetDeviceDriverFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetDeviceDriverFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetMappedFileNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetMappedFileNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetMappedFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetMappedFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleBaseNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleBaseNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleBaseNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleBaseNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleFileNameExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleFileNameExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleFileNameExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleFileNameExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetModuleInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetModuleInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetPerformanceInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetPerformanceInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessImageFileNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessImageFileNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessImageFileNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessImageFileNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetProcessMemoryInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetProcessMemoryInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetWsChanges -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetWsChanges - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32GetWsChangesEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32GetWsChangesEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32InitializeProcessForWsWatch -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32InitializeProcessForWsWatch - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32QueryWorkingSet -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32QueryWorkingSet - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_K32QueryWorkingSetEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 K32QueryWorkingSetEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCIDToLocaleName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCIDToLocaleName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LCMapStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LCMapStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LeaveCriticalSection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LeaveCriticalSection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LeaveCriticalSectionWhenCallbackReturns -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LeaveCriticalSectionWhenCallbackReturns - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadAppInitDlls -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadAppInitDlls - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadEnclaveData -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadEnclaveData - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadLibraryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadLibraryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadModule -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadModule - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadPackagedLibrary -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadPackagedLibrary - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadResource -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadResource - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadStringBaseExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadStringBaseExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LoadStringBaseW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LoadStringBaseW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalCompact -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalCompact - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFileTimeToFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFileTimeToFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFileTimeToLocalSystemTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFileTimeToLocalSystemTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFlags -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFlags - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalLock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalLock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalReAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalReAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalShrink -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalShrink - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalSystemTimeToLocalFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalSystemTimeToLocalFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocalUnlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocalUnlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocaleNameToLCID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocaleNameToLCID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LocateXStateFeature -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LocateXStateFeature - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_LockResource -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 LockResource - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapUserPhysicalPages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapUserPhysicalPages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapUserPhysicalPagesScatter -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapUserPhysicalPagesScatter - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileExNuma -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileExNuma - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MapViewOfFileFromApp -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MapViewOfFileFromApp - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32First -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32First - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32FirstW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32FirstW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32Next -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32Next - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Module32NextW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Module32NextW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileWithProgressA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileWithProgressA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MoveFileWithProgressW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MoveFileWithProgressW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MulDiv -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MulDiv - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_MultiByteToWideChar -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 MultiByteToWideChar - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NeedCurrentDirectoryForExePathA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NeedCurrentDirectoryForExePathA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NeedCurrentDirectoryForExePathW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NeedCurrentDirectoryForExePathW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NormalizeString -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NormalizeString - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NotifyMountMgr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NotifyMountMgr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_NotifyUILanguageChange -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 NotifyUILanguageChange - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OOBEComplete -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OOBEComplete - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OfferVirtualMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OfferVirtualMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenEventA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenEventA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenEventW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenEventW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileById -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileById - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileMappingA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileMappingA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenFileMappingW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenFileMappingW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenJobObjectA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenJobObjectA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenJobObjectW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenJobObjectW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenMutexA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenMutexA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenMutexW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenMutexW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPackageInfoByFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPackageInfoByFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPrivateNamespaceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPrivateNamespaceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenPrivateNamespaceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenPrivateNamespaceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenSemaphoreA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenSemaphoreA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenSemaphoreW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenSemaphoreW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenStateExplicit -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenStateExplicit - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenWaitableTimerA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenWaitableTimerA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OpenWaitableTimerW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OpenWaitableTimerW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OutputDebugStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OutputDebugStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_OutputDebugStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 OutputDebugStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFamilyNameFromFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFamilyNameFromFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFamilyNameFromId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFamilyNameFromId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageFullNameFromId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageFullNameFromId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageIdFromFullName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageIdFromFullName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 73 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PackageNameAndPublisherIdFromFamilyName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PackageNameAndPublisherIdFromFamilyName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ParseApplicationUserModelId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ParseApplicationUserModelId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekConsoleInputA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekConsoleInputA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekConsoleInputW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekConsoleInputW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PeekNamedPipe -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PeekNamedPipe - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PopIoRingCompletion -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PopIoRingCompletion - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PostQueuedCompletionStatus -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PostQueuedCompletionStatus - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerClearRequest -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerClearRequest - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerCreateRequest -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerCreateRequest - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PowerSetRequest -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PowerSetRequest - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PrefetchVirtualMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PrefetchVirtualMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PrepareTape -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PrepareTape - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32First -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32First - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32FirstW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32FirstW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32Next -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32Next - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Process32NextW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Process32NextW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ProcessIdToSessionId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ProcessIdToSessionId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssCaptureSnapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssCaptureSnapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssDuplicateSnapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssDuplicateSnapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssFreeSnapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssFreeSnapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssQuerySnapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssQuerySnapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerCreate -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerCreate - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerGetPosition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerGetPosition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerRewind -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerRewind - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSeek -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSeek - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSeekToBeginning -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSeekToBeginning - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerSetPosition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerSetPosition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkMarkerTell -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkMarkerTell - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PssWalkSnapshot -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PssWalkSnapshot - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PulseEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PulseEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_PurgeComm -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 PurgeComm - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryActCtxSettingsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryActCtxSettingsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryActCtxW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryActCtxW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDepthSList -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDepthSList - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDosDeviceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDosDeviceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryDosDeviceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryDosDeviceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryFullProcessImageNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryFullProcessImageNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryFullProcessImageNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryFullProcessImageNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIdleProcessorCycleTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIdleProcessorCycleTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIdleProcessorCycleTimeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIdleProcessorCycleTimeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryInformationJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryInformationJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIoRateControlInformationJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIoRateControlInformationJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryIoRingCapabilities -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryIoRingCapabilities - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryMemoryResourceNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryMemoryResourceNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryPerformanceCounter -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryPerformanceCounter - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryPerformanceFrequency -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryPerformanceFrequency - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProcessAffinityUpdateMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProcessAffinityUpdateMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProcessCycleTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProcessCycleTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryProtectedPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryProtectedPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadCycleTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadCycleTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadProfiling -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadProfiling - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryThreadpoolStackInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryThreadpoolStackInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryUmsThreadInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryUmsThreadInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueryUnbiasedInterruptTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueryUnbiasedInterruptTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserAPC -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserAPC - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserAPC2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserAPC2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_QueueUserWorkItem -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 QueueUserWorkItem - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RaiseException -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RaiseException - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RaiseFailFastException -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RaiseFailFastException - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReOpenFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReOpenFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleInputA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleInputA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleInputW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleInputW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputCharacterA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputCharacterA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputCharacterW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputCharacterW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleOutputW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleOutputW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadConsoleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadConsoleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadDirectoryChangesExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadDirectoryChangesExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadDirectoryChangesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadDirectoryChangesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadFileScatter -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadFileScatter - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadProcessMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadProcessMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReadThreadProfilingData -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReadThreadProfilingData - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReclaimVirtualMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReclaimVirtualMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterApplicationRecoveryCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterApplicationRecoveryCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterApplicationRestart -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterApplicationRestart - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterBadMemoryNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterBadMemoryNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForInputIdle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForInputIdle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForSingleObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForSingleObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitForSingleObjectEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitForSingleObjectEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RegisterWaitUntilOOBECompleted -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RegisterWaitUntilOOBECompleted - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseMutex -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseMutex - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseMutexWhenCallbackReturns -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseMutexWhenCallbackReturns - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleasePackageVirtualizationContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleasePackageVirtualizationContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSRWLockExclusive -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSRWLockExclusive - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSRWLockShared -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSRWLockShared - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSemaphore -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSemaphore - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReleaseSemaphoreWhenCallbackReturns -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReleaseSemaphoreWhenCallbackReturns - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveDllDirectory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveDllDirectory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveLocalAlternateComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveLocalAlternateComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveLocalAlternateComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveLocalAlternateComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveSecureMemoryCacheCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveSecureMemoryCacheCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveVectoredContinueHandler -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveVectoredContinueHandler - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RemoveVectoredExceptionHandler -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RemoveVectoredExceptionHandler - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFileA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFileA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplaceFileW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplaceFileW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ReplacePartitionUnit -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ReplacePartitionUnit - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RequestDeviceWakeup -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RequestDeviceWakeup - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RequestWakeupLatency -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RequestWakeupLatency - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResetEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResetEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResetWriteWatch -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResetWriteWatch - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResizePseudoConsole -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResizePseudoConsole - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveDelayLoadedAPI -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveDelayLoadedAPI - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveDelayLoadsFromDll -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveDelayLoadsFromDll - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResolveLocaleName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResolveLocaleName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RestoreLastError -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RestoreLastError - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ResumeThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ResumeThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlAddFunctionTable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlAddFunctionTable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCaptureContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCaptureContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCaptureStackBackTrace -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCaptureStackBackTrace - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCompareMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCompareMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlCopyMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlCopyMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlDeleteFunctionTable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlDeleteFunctionTable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlFillMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlFillMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlInstallFunctionTableCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlInstallFunctionTableCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlIsEcCode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlIsEcCode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlLookupFunctionEntry -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlLookupFunctionEntry - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlMoveMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlMoveMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlPcToFileHeader -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlPcToFileHeader - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlRaiseException -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlRaiseException - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlRestoreContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlRestoreContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlUnwind -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlUnwind - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlUnwindEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlUnwindEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlVirtualUnwind -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlVirtualUnwind - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlVirtualUnwind2 -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlVirtualUnwind2 - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_RtlZeroMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 RtlZeroMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ScrollConsoleScreenBufferA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ScrollConsoleScreenBufferA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ScrollConsoleScreenBufferW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ScrollConsoleScreenBufferW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SearchPathA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SearchPathA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SearchPathW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SearchPathW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCachedSigningLevel -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCachedSigningLevel - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCalendarInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCalendarInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCalendarInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCalendarInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommBreak -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommBreak - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommConfig -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommConfig - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCommTimeouts -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCommTimeouts - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameEx2W -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameEx2W - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleActiveScreenBuffer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleActiveScreenBuffer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCtrlHandler -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCtrlHandler - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursor -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursor - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursorInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursorInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleCursorPosition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleCursorPosition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleDisplayMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleDisplayMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleHistoryInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleHistoryInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleOutputCP -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleOutputCP - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleScreenBufferInfoEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleScreenBufferInfoEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleScreenBufferSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleScreenBufferSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTextAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTextAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTitleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTitleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleTitleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleTitleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetConsoleWindowInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetConsoleWindowInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCriticalSectionSpinCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCriticalSectionSpinCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentConsoleFontEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentConsoleFontEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetCurrentDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetCurrentDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultCommConfigA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultCommConfigA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultCommConfigW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultCommConfigW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDefaultDllDirectories -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDefaultDllDirectories - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDllDirectoryA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDllDirectoryA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDllDirectoryW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDllDirectoryW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetDynamicTimeZoneInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetDynamicTimeZoneInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEndOfFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEndOfFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentStringsA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentStringsA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentStringsW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentStringsW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentVariableA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentVariableA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEnvironmentVariableW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEnvironmentVariableW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetErrorMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetErrorMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetEventWhenCallbackReturns -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetEventWhenCallbackReturns - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileApisToANSI -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileApisToANSI - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileApisToOEM -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileApisToOEM - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesTransactedA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesTransactedA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesTransactedW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesTransactedW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileAttributesW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileAttributesW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileBandwidthReservation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileBandwidthReservation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 68 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileCompletionNotificationModes -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileCompletionNotificationModes - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileInformationByHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileInformationByHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileIoOverlappedRange -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileIoOverlappedRange - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFilePointer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFilePointer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFilePointerEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFilePointerEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileShortNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileShortNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileShortNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileShortNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFileValidData -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFileValidData - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableExA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableExA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableExW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableExW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetFirmwareEnvironmentVariableW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetFirmwareEnvironmentVariableW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetHandleCount -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetHandleCount - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetHandleInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetHandleInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetInformationJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetInformationJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 70 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetIoRateControlInformationJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetIoRateControlInformationJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetIoRingCompletionEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetIoRingCompletionEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLastError -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLastError - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalPrimaryComputerNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalPrimaryComputerNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalPrimaryComputerNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalPrimaryComputerNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocalTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocalTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocaleInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocaleInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetLocaleInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetLocaleInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetMailslotInfo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetMailslotInfo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetMessageWaitingIndicator -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetMessageWaitingIndicator - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetNamedPipeAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetNamedPipeAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetNamedPipeHandleState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetNamedPipeHandleState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetPriorityClass -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetPriorityClass - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessAffinityMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessAffinityMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessAffinityUpdateMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessAffinityUpdateMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDEPPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDEPPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDefaultCpuSetMasks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDefaultCpuSetMasks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDefaultCpuSets -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDefaultCpuSets - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 72 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDynamicEHContinuationTargets -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDynamicEHContinuationTargets - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 78 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessDynamicEnforcedCetCompatibleRanges -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessDynamicEnforcedCetCompatibleRanges - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessMitigationPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessMitigationPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessPriorityBoost -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessPriorityBoost - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessShutdownParameters -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessShutdownParameters - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessWorkingSetSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessWorkingSetSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProcessWorkingSetSizeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProcessWorkingSetSizeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetProtectedPolicy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetProtectedPolicy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSearchPathMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSearchPathMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetStdHandle -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetStdHandle - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetStdHandleEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetStdHandleEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemFileCacheSize -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemFileCacheSize - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemPowerState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemPowerState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetSystemTimeAdjustment -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetSystemTimeAdjustment - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTapeParameters -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTapeParameters - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTapePosition -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTapePosition - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadAffinityMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadAffinityMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadDescription -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadDescription - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadErrorMode -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadErrorMode - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadExecutionState -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadExecutionState - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadGroupAffinity -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadGroupAffinity - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadIdealProcessor -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadIdealProcessor - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadIdealProcessorEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadIdealProcessorEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadLocale -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadLocale - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPreferredUILanguages -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPreferredUILanguages - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPriority -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPriority - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadPriorityBoost -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadPriorityBoost - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadSelectedCpuSetMasks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadSelectedCpuSetMasks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadSelectedCpuSets -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadSelectedCpuSets - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadStackGuarantee -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadStackGuarantee - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadUILanguage -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadUILanguage - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolStackInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolStackInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolThreadMaximum -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolThreadMaximum - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolThreadMinimum -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolThreadMinimum - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolTimerEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolTimerEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolWait -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolWait - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetThreadpoolWaitEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetThreadpoolWaitEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTimeZoneInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTimeZoneInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetTimerQueueTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetTimerQueueTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUmsThreadInformation -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUmsThreadInformation - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUnhandledExceptionFilter -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUnhandledExceptionFilter - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUserGeoID -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUserGeoID - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetUserGeoName -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetUserGeoName - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeLabelA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeLabelA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeLabelW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeLabelW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeMountPointA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeMountPointA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetVolumeMountPointW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetVolumeMountPointW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetWaitableTimer -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetWaitableTimer - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetWaitableTimerEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetWaitableTimerEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetXStateFeaturesMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetXStateFeaturesMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SetupComm -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SetupComm - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SignalObjectAndWait -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SignalObjectAndWait - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SizeofResource -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SizeofResource - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 39 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Sleep -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Sleep - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepConditionVariableCS -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepConditionVariableCS - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepConditionVariableSRW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepConditionVariableSRW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SleepEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SleepEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_StartThreadpoolIo -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 StartThreadpoolIo - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SubmitIoRing -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SubmitIoRing - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SubmitThreadpoolWork -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SubmitThreadpoolWork - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SuspendThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SuspendThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SwitchToFiber -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SwitchToFiber - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SwitchToThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SwitchToThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToFileTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToFileTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToTzSpecificLocalTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToTzSpecificLocalTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_SystemTimeToTzSpecificLocalTimeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 SystemTimeToTzSpecificLocalTimeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateJobObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateJobObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TerminateThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TerminateThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Thread32First -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Thread32First - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Thread32Next -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Thread32Next - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsGetValue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsGetValue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TlsSetValue -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TlsSetValue - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Toolhelp32ReadProcessMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Toolhelp32ReadProcessMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TransactNamedPipe -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TransactNamedPipe - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TransmitCommChar -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TransmitCommChar - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryAcquireSRWLockExclusive -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryAcquireSRWLockExclusive - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryAcquireSRWLockShared -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryAcquireSRWLockShared - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TryEnterCriticalSection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TryEnterCriticalSection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TrySubmitThreadpoolCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TrySubmitThreadpoolCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TzSpecificLocalTimeToSystemTime -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TzSpecificLocalTimeToSystemTime - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_TzSpecificLocalTimeToSystemTimeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 TzSpecificLocalTimeToSystemTimeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UmsThreadYield -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UmsThreadYield - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnhandledExceptionFilter -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnhandledExceptionFilter - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnlockFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnlockFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnlockFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnlockFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnmapViewOfFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnmapViewOfFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnmapViewOfFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnmapViewOfFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 71 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterApplicationRecoveryCallback -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterApplicationRecoveryCallback - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterApplicationRestart -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterApplicationRestart - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterBadMemoryNotification -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterBadMemoryNotification - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWait -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWait - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWaitEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWaitEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UnregisterWaitUntilOOBECompleted -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UnregisterWaitUntilOOBECompleted - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateProcThreadAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateProcThreadAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateResourceA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateResourceA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_UpdateResourceW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 UpdateResourceW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerLanguageNameA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerLanguageNameA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerLanguageNameW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerLanguageNameW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerSetConditionMask -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerSetConditionMask - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyScripts -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyScripts - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyVersionInfoA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyVersionInfoA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VerifyVersionInfoW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VerifyVersionInfoW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAlloc -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAlloc - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAllocEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAllocEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualAllocExNuma -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualAllocExNuma - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualFree -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualFree - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualFreeEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualFreeEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualLock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualLock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualProtect -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualProtect - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 50 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualProtectEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualProtectEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualQuery -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualQuery - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualQueryEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualQueryEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_VirtualUnlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 VirtualUnlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WTSGetActiveConsoleSessionId -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WTSGetActiveConsoleSessionId - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitCommEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitCommEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForDebugEvent -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForDebugEvent - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForDebugEventEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForDebugEventEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForMultipleObjects -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForMultipleObjects - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForMultipleObjectsEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForMultipleObjectsEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForSingleObject -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForSingleObject - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForSingleObjectEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForSingleObjectEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolIoCallbacks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolIoCallbacks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 65 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolTimerCallbacks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolTimerCallbacks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolWaitCallbacks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolWaitCallbacks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitForThreadpoolWorkCallbacks -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitForThreadpoolWorkCallbacks - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitNamedPipeA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitNamedPipeA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 48 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WaitNamedPipeW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WaitNamedPipeW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WakeAllConditionVariable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WakeAllConditionVariable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WakeConditionVariable -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WakeConditionVariable - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerGetFlags -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerGetFlags - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterAdditionalProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterAdditionalProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 57 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterAppLocalDump -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterAppLocalDump - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterCustomMetadata -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterCustomMetadata - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterExcludedMemoryBlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterExcludedMemoryBlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 56 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterMemoryBlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterMemoryBlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 67 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerRegisterRuntimeExceptionModule -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerRegisterRuntimeExceptionModule - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerSetFlags -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerSetFlags - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterAdditionalProcess -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterAdditionalProcess - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 59 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterAppLocalDump -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterAppLocalDump - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterCustomMetadata -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterCustomMetadata - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 66 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterExcludedMemoryBlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterExcludedMemoryBlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 51 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 58 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterMemoryBlock -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterMemoryBlock - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 69 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerUnregisterRuntimeExceptionModule -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerUnregisterRuntimeExceptionModule - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WerpInitiateRemoteRecovery -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WerpInitiateRemoteRecovery - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WideCharToMultiByte -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WideCharToMultiByte - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WinExec -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WinExec - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 64 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64DisableWow64FsRedirection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64DisableWow64FsRedirection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64EnableWow64FsRedirection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64EnableWow64FsRedirection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64GetThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64GetThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64GetThreadSelectorEntry -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64GetThreadSelectorEntry - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 63 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64RevertWow64FsRedirection -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64RevertWow64FsRedirection - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 55 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64SetThreadContext -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64SetThreadContext - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_Wow64SuspendThread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 Wow64SuspendThread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleInputA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleInputA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleInputW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleInputW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputAttribute -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputAttribute - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputCharacterA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputCharacterA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 62 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputCharacterW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputCharacterW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleOutputW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleOutputW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteConsoleW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteConsoleW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFile -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFile - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFileEx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFileEx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 49 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteFileGather -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteFileGather - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileSectionA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileSectionA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 61 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileSectionW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileSectionW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStructA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStructA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 60 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WritePrivateProfileStructW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WritePrivateProfileStructW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 52 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProcessMemory -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProcessMemory - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileSectionA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileSectionA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 54 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileSectionW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileSectionW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileStringA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileStringA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 53 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteProfileStringW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteProfileStringW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_WriteTapemark -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 WriteTapemark - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_ZombifyActCtx -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 ZombifyActCtx - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__hread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _hread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__hwrite -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _hwrite - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lclose -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lclose - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lcreat -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lcreat - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__llseek -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _llseek - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lopen -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lopen - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 40 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lread -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lread - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp__lwrite -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 _lwrite - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcat -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcat - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcatA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcatA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcatW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcatW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmp -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmp - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpi -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpi - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpiA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpiA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcmpiW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcmpiW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpyn -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpyn - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpynA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpynA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 43 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrcpynW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrcpynW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 41 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlen -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlen - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlenA -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlenA - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 42 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_lstrlenW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 lstrlenW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrcmpW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrcmpW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 47 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrcmpiW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrcmpiW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 46 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_lstrlenW -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_lstrlenW - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcschr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcschr - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcscpy -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcscpy - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcsicmp -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcsicmp - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 44 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcslen -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcslen - -C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64/kernel32.Lib(KERNEL32.dll): file format COFF-import-file - ---------- 0/0 45 (date: "-1" contains non-decimal chars) KERNEL32.dll -[ 0](sec 0)(fl 0x00)(ty 0)(scl 0) (nx 0) 0x00000000 __imp_uaw_wcsrchr -[ 1](sec 0)(fl 0x00)(ty 20)(scl 0) (nx 0) 0x00000000 uaw_wcsrchr diff --git a/windows/wlibwild/Cargo.toml b/windows/wlibwild/Cargo.toml deleted file mode 100644 index 8333a3a2f..000000000 --- a/windows/wlibwild/Cargo.toml +++ /dev/null @@ -1,39 +0,0 @@ -[package] -name = "wlibwild" -repository.workspace = true -license.workspace = true -version.workspace = true -rust-version.workspace = true -edition.workspace = true - -[dependencies] -anyhow = { workspace = true } -bytemuck = { workspace = true } -bytesize = { workspace = true } -colored = { workspace = true } -indexmap = { workspace = true } -itertools = { workspace = true } -rayon = { workspace = true } -tracing = { workspace = true } -object = { workspace = true } -tracing-subscriber = { workspace = true, features = ["ansi"] } -walkdir = "2" - - -[target.'cfg(target_os = "windows")'.dependencies] -phnt = { workspace = true } - -[target.'cfg(target_os = "windows")'.dependencies.windows-sys] -workspace = true -features = [ - "Win32_System_Threading", - "Win32_System_Console", - "Win32_System_Pipes", - "Win32_Security", - "Win32_Storage_FileSystem", - "Win32_System_IO", -] - - -[lints] -workspace = true diff --git a/windows/wlibwild/done.txzt b/windows/wlibwild/done.txzt deleted file mode 100644 index e7eec290e..000000000 --- a/windows/wlibwild/done.txzt +++ /dev/null @@ -1,3 +0,0 @@ -Linker has finished running at SystemTime { - intervals: 134000631526992380, -} \ No newline at end of file diff --git a/windows/wlibwild/example-linkerflags-rust.txt b/windows/wlibwild/example-linkerflags-rust.txt deleted file mode 100644 index cd3aabdf7..000000000 --- a/windows/wlibwild/example-linkerflags-rust.txt +++ /dev/null @@ -1,35 +0,0 @@ -"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\link.exe" -"/NOLOGO" -"C:\\Users\\Samuel\\AppData\\Local\\Temp\\rustc7RL5Io\\symbols.o" -"dummy.dummy.6cfbe55db138f4b-cgu.0.rcgu.o" -"dummy.3wxfnlvokcqcl6j45c8xeicgz.rcgu.o" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-efa6c7783284bd31.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-43468c47cff21662.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libwindows_targets-3935b75a1bd1c449.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-cc0fa0adec36251f.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-22f2c46a93af1174.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-c835068eb56f6efb.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-abe24411cb8f5bd4.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-b5e24931eb1ae1bd.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-8dc64876e32b9d07.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-214bcacef209824d.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-3e14ad51a3206bab.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-a55e6b132b0b5f5d.rlib" -"C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-b994e165f6ecc9e9.rlib" -"kernel32.lib" -"kernel32.lib" -"kernel32.lib" -"ntdll.lib" -"userenv.lib" -"ws2_32.lib" -"dbghelp.lib" -"/defaultlib:msvcrt" -"/NXCOMPAT" -"/OUT:dummy.exe" -"/OPT:REF,NOICF" -"/DEBUG" -"/PDBALTPATH:%_PDB%" -"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" -"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" -"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" -"/NATVIS:C:\\Users\\Samuel\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis" \ No newline at end of file diff --git a/windows/wlibwild/src/bin/main.rs b/windows/wlibwild/src/bin/main.rs deleted file mode 100644 index f5764a5c5..000000000 --- a/windows/wlibwild/src/bin/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - unsafe { wlibwild::run_in_subprocess() } -} diff --git a/windows/wlibwild/src/lib.rs b/windows/wlibwild/src/lib.rs deleted file mode 100644 index 3a3e9d015..000000000 --- a/windows/wlibwild/src/lib.rs +++ /dev/null @@ -1,201 +0,0 @@ -use object::LittleEndian as LE; -use object::coff::CoffHeader; -use object::coff::SectionTable; -use object::coff::SymbolTable; -use object::pe::ImageFileHeader; -use std::io::Write; -use std::path::PathBuf; -use tracing::debug; -use tracing::info; -use tracing::warn; -mod subprocess; -use tracing_subscriber::{ - Layer as _, fmt::format::FmtSpan, layer::SubscriberExt as _, util::SubscriberInitExt, -}; -mod paths; - -pub fn setup_logging() { - tracing_subscriber::registry() - .with( - tracing_subscriber::fmt::layer() - .with_line_number(true) - .with_file(true) - .with_span_events(FmtSpan::CLOSE) - .with_filter( - tracing_subscriber::EnvFilter::try_from_default_env() - .unwrap_or("wlibwild=info,warn".into()), - ), - ) - .init(); -} - -pub struct Linker; - -impl Linker { - pub fn new() -> Self { - Linker - } - - pub fn run(&self) -> anyhow::Result { - // This is where the linking logic would go - info!("Linker is running"); - let files = vec![ - PathBuf::from("basic_objs/function.o"), - PathBuf::from("basic_objs/main.o"), - ]; - link_files(files).unwrap(); - - Ok(LinkerDrop) - } -} - -pub struct LinkerDrop; - -impl Drop for LinkerDrop { - fn drop(&mut self) { - info!("Linker has finished running"); - std::thread::sleep(std::time::Duration::from_secs(5)); - std::fs::write( - "./done.txzt", - format!( - "Linker has finished running at {:#?}", - std::time::SystemTime::now() - ), - ) - .expect("Failed to write done file"); - } -} - -pub use subprocess::run_in_subprocess; - -pub fn run() -> Result<(), anyhow::Error> { - let linker = Linker::new(); - - linker.run()?; - Ok(()) -} - -fn link_files(files: Vec) -> anyhow::Result<()> { - info!("Starting to link files: {:?}", files); - for file in files { - let debug_output = std::fs::File::create(file.with_extension("debug"))?; - let mut writer = std::io::BufWriter::new(debug_output); - let data = std::fs::read(file)?; - parse_object(&mut writer, &data)?; - } - - Ok(()) -} - -fn parse_object(debug_output: &mut impl Write, data: &[u8]) -> anyhow::Result<()> { - let kind = object::FileKind::parse(data)?; - - match kind { - object::FileKind::Coff => { - debug!("COFF file detected"); - writeln!(debug_output, "COFF file detected")?; - print_coff(debug_output, data)?; - } - object::FileKind::Pe32 => { - info!("PE32 file detected"); - } - object::FileKind::Pe64 => { - info!("PE64 file detected"); - } - kind => { - warn!("Unsupported file kind: {:?}", kind); - return Err(anyhow::anyhow!("Unsupported file kind: {:?}", kind)); - } - } - - // If parsing is successful - Ok(()) -} - -pub fn print_coff(debug_output: &mut impl Write, data: &[u8]) -> anyhow::Result<()> { - let mut offset = 0; - let header = ImageFileHeader::parse(data, &mut offset)?; - - let sections = header.sections(data, offset)?; - - let symbols = header.symbols(data); - print_sections( - debug_output, - data, - header.machine.get(LE), - symbols.as_ref().ok(), - §ions, - )?; - let symbols = symbols?; - // print_symbols(p, sections.as_ref(), symbols); - - Ok(()) -} - -fn print_sections<'data, Coff: CoffHeader>( - debug_output: &mut impl Write, - data: &[u8], - machine: u16, - symbols: Option<&SymbolTable<'data, &'data [u8], Coff>>, - sections: &SectionTable, -) -> anyhow::Result<()> { - for (index, section) in sections.iter().enumerate() { - if let Some(name) = symbols.and_then(|symbols| section.name(symbols.strings()).ok()) { - writeln!( - debug_output, - "Section {}: {}", - index, - str::from_utf8(name).unwrap_or(&format!("{:x?}", name)) - )?; - } else { - writeln!(debug_output, "Section {}: {:?}", index, section.raw_name())?; - } - writeln!( - debug_output, - " Virtual Size: {:#x}", - section.virtual_size.get(LE) - )?; - writeln!( - debug_output, - " Virtual Address: {:#x}", - section.virtual_address.get(LE) - )?; - writeln!( - debug_output, - " Size Of Raw Data: {:#x}", - section.size_of_raw_data.get(LE) - )?; - writeln!( - debug_output, - " Pointer To Raw Data: {:#x}", - section.pointer_to_raw_data.get(LE) - )?; - writeln!( - debug_output, - " Pointer To Relocations: {:#x}", - section.pointer_to_relocations.get(LE) - )?; - writeln!( - debug_output, - " Pointer To Linenumbers: {:#x}", - section.pointer_to_linenumbers.get(LE) - )?; - writeln!( - debug_output, - " Number Of Relocations: {}", - section.number_of_relocations.get(LE) - )?; - writeln!( - debug_output, - " Number Of Linenumbers: {}", - section.number_of_linenumbers.get(LE) - )?; - writeln!( - debug_output, - " Characteristics: {:#x}", - section.characteristics.get(LE) - )?; - } - - Ok(()) -} diff --git a/windows/wlibwild/src/paths.rs b/windows/wlibwild/src/paths.rs deleted file mode 100644 index 84a14c1c8..000000000 --- a/windows/wlibwild/src/paths.rs +++ /dev/null @@ -1,204 +0,0 @@ -//! A robust, self-contained module to find Windows and MSVC library paths. -//! -//! It combines two discovery methods for maximum reliability: -//! 1. **Primary:** Uses `vswhere.exe` and `vcvarsall.bat` to get the exact library -//! paths configured for the Visual Studio C++ environment. -//! 2. **Fallback:** Manually scans the standard `Windows Kits` directory. -//! -//! The results are cached in a `LazyLock` static for efficient, repeated lookups. - -use std::collections::HashMap; -use std::env; -use std::fs; -use std::path::{Path, PathBuf}; -use std::process::Command; -use std::sync::LazyLock; - -use anyhow::Context; -use rayon::iter::IntoParallelIterator; -use rayon::iter::ParallelIterator; -use walkdir::WalkDir; - -/// The lazily-initialized, thread-safe cache of library paths. -/// The closure inside is executed only once, the first time this static is accessed. -static LIBRARY_CACHE: LazyLock> = LazyLock::new(|| { - let mut all_search_paths = Vec::new(); - - // --- Primary Method: Use vswhere and vcvarsall.bat --- - // This is the most accurate way to get all MSVC and SDK paths. - match get_vc_lib_paths() { - Ok(paths) => all_search_paths.extend(paths), - Err(e) => { - eprintln!("Warning: Failed to get VC lib paths: {:?}", e); - } - }; - - // --- Fallback Method: Manually scan the Windows Kits directory --- - // This is a great backup if vswhere fails or the installation is unusual. - match get_manual_sdk_paths() { - Ok(paths) => all_search_paths.extend(paths), - Err(e) => { - eprintln!("Warning: Failed to get manual SDK paths: {:?}", e); - } - }; - - // Remove duplicate search paths to avoid scanning the same directory twice. - all_search_paths.sort(); - all_search_paths.dedup(); - - // --- Populate the cache by scanning all discovered directories --- - let cache = all_search_paths - .into_par_iter() - .fold( - || HashMap::new(), - |mut acc, search_dir| { - for entry in WalkDir::new(search_dir) - .into_iter() - .filter_map(Result::ok) - .filter(|e| { - e.file_type().is_file() && { - if let Some(name) = e.file_name().to_str() { - name.ends_with(".lib") || name.ends_with(".Lib") - } else { - false - } - } - }) - { - let path = entry.into_path(); - let file_name = path.file_name().unwrap().to_str().unwrap().to_lowercase(); - acc.insert(file_name, path); - } - - acc - }, - ) - .reduce_with(|mut acc, map| { - acc.extend(map); - acc - }) - .unwrap_or_default(); - - cache -}); - -// --- Public API --- - -/// Finds the absolute path for a given library filename. -/// -/// The first time this function is called, it will use `vswhere` and other -/// methods to discover all relevant MSVC and Windows SDK library directories, -/// scan them, and build a static, in-memory cache. All subsequent calls are -/// fast, case-insensitive lookups. -/// -/// # Returns -/// An `Option` containing a static reference to the absolute `Path`. -pub fn find_lib(lib_name: &str) -> Option<&'static Path> { - LIBRARY_CACHE - .get(&lib_name.to_lowercase()) - .map(|p| p.as_path()) -} - -// --- Private Helper Functions --- - -/// Gets library search paths by running `vcvarsall.bat` from a VS installation. -fn get_vc_lib_paths() -> anyhow::Result> { - let vcvars_path = vs_path()? - .join("VC") - .join("Auxiliary") - .join("Build") - .join("vcvarsall.bat"); - - if !vcvars_path.exists() { - anyhow::bail!( - "vcvarsall.bat not found at expected path: {}", - vcvars_path.display() - ); - } - - // The trick: run the batch script, and then immediately run the `set` command - // in the same command prompt process. This prints all environment variables. - let output = Command::new("cmd") - .arg("/C") - .arg(&vcvars_path) - .arg("x64") - .arg("&&") - .arg("set") - .output()?; - - if !output.status.success() { - anyhow::bail!( - "Failed to run vcvarsall.bat {}: {}", - output.status, - String::from_utf8_lossy(&output.stderr) - ); - } - - let env_output = String::from_utf8(output.stdout)?; - - for line in env_output.lines() { - if line.starts_with("LIB=") { - let lib_line = &line[4..]; - return Ok(env::split_paths(lib_line).collect()); - } - } - anyhow::bail!("LIB environment variable not found after running vcvarsall.bat"); -} - -fn vs_where() -> Command { - Command::new("C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe") -} -/// Finds the Visual Studio installation path using a hardcoded `vswhere` path. -fn vs_path() -> anyhow::Result { - let output = vs_where() - .args(&[ - "-latest", - "-property", - "installationPath", - "-requires", - "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", - ]) - .output()?; - - let path = String::from_utf8_lossy(&output.stdout); - let path = path - .lines() - .next() - .context("Failed to find VS installation path")? - .trim(); - Ok(PathBuf::from(path)) -} - -/// Gets SDK search paths by manually scanning the `Windows Kits` directory. -fn get_manual_sdk_paths() -> anyhow::Result> { - let prog_files = - env::var("ProgramFiles(x86)").context("Failed to get ProgramFiles(x86) path")?; - let sdk_lib_path = PathBuf::from(prog_files).join("Windows Kits/10/Lib"); - - let latest_version = fs::read_dir(&sdk_lib_path) - .context("Failed to read SDK lib directory")? - .filter_map(Result::ok) - .map(|entry| entry.path()) - .filter(|path| path.is_dir()) - .max() - .ok_or_else(|| { - anyhow::anyhow!( - "No SDK version directories found in {}", - sdk_lib_path.display() - ) - })?; // max() on PathBufs works lexicographically. - - Ok(vec![ - latest_version.join("um/x64"), // User-Mode libraries - latest_version.join("ucrt/x64"), // Universal C Runtime - ]) -} - -#[test] -fn find_kernel32() { - let lib = "kernel32.lib"; - match find_lib(lib) { - Some(path) => println!("Found {} at {}", lib, path.display()), - None => println!("{} not found", lib), - } -} diff --git a/windows/wlibwild/src/subprocess.rs b/windows/wlibwild/src/subprocess.rs deleted file mode 100644 index a94b098a8..000000000 --- a/windows/wlibwild/src/subprocess.rs +++ /dev/null @@ -1,179 +0,0 @@ -use phnt::ffi::HANDLE; -use phnt::ffi::NtClose; -use phnt::ffi::NtCreateUserProcess; -use phnt::ffi::NtTerminateProcess; -use phnt::ffi::NtWaitForSingleObject; -use phnt::ffi::PROCESS_CREATE_FLAGS_INHERIT_HANDLES; -use phnt::ffi::PS_CREATE_INFO; -use std::ptr; -use windows_sys::Win32::Foundation::CloseHandle; -use windows_sys::Win32::Foundation::FALSE; -use windows_sys::Win32::Foundation::STATUS_PROCESS_CLONED; -use windows_sys::Win32::Foundation::TRUE; -use windows_sys::Win32::Security::SECURITY_ATTRIBUTES; -use windows_sys::Win32::Storage::FileSystem::ReadFile; -use windows_sys::Win32::Storage::FileSystem::WriteFile; -use windows_sys::Win32::System::Console::ATTACH_PARENT_PROCESS; -use windows_sys::Win32::System::Console::AttachConsole; -use windows_sys::Win32::System::Console::FreeConsole; -use windows_sys::Win32::System::Pipes::CreatePipe; -use windows_sys::Win32::System::Threading::PROCESS_ALL_ACCESS; -use windows_sys::Win32::System::Threading::THREAD_ALL_ACCESS; - -use crate::setup_logging; - -type Result = std::result::Result>; - -/// Runs the linker, in a subprocess if possible, prints any errors, then exits. -/// -/// This is done by forking a sub-process which runs the linker and waits for communication back -/// from the sub-process (via a pipe) when the main link task is done (the output file has been -/// written, but some shutdown tasks remain. -/// -/// Don't call `setup_tracing` or `setup_thread_pool` if using this function, these will be called -/// for you in the subprocess. -/// -/// # Safety -/// Must not be called once threads have been spawned. Calling this function from main is generally -/// the best way to ensure this. -pub unsafe fn run_in_subprocess() -> ! { - let exit_code = match subprocess_result() { - Ok(code) => code, - Err(error) => { - eprintln!("{}", error.to_string()); - 1 - } - }; - std::process::exit(exit_code); -} - -#[allow(non_upper_case_globals)] -pub const NtCurrentProcess: HANDLE = -1isize as *mut std::ffi::c_void; - -fn subprocess_result() -> Result { - let (read_end, write_end) = make_pipe()?; - - let mut hprocess: HANDLE = std::ptr::null_mut(); - let mut hthread: HANDLE = std::ptr::null_mut(); - - match unsafe { fork(&mut hprocess, &mut hthread) } { - STATUS_PROCESS_CLONED => { - // executing inside the clone - - // re attach to the parent's console to be able to write to it - unsafe { - FreeConsole(); - AttachConsole(ATTACH_PARENT_PROCESS); - }; - - { - setup_logging(); - let linker = crate::Linker::new(); - let _outputs = linker.run()?; - println!("Linker has finished running, notifying parent..."); - inform_parent_done(write_end); - } - unsafe { NtTerminateProcess(NtCurrentProcess, STATUS_PROCESS_CLONED) }; - Ok(0) - } - 0 => { - println!("Waiting for child to finish..."); - let exit_status = wait_for_child_done(read_end, hprocess, hthread); - Ok(exit_status) - } - _ => { - eprintln!("Fork failure in the parent - Fallback to running linker in this process"); - // Fork failure in the parent - Fallback to running linker in this process - crate::run()?; - Ok(0) - } - } -} - -fn inform_parent_done(write_end: HANDLE) { - let mut bytes_written = 0; - - unsafe { - WriteFile( - write_end, - "X".as_ptr(), - 1, - &mut bytes_written, - std::ptr::null_mut(), - ); - println!("Parent informed that the linker has finished."); - CloseHandle(write_end); - println!("Closing write end of the pipe."); - // FreeConsole(); - } -} - -fn wait_for_child_done(read_end: HANDLE, hprocess: HANDLE, hthread: HANDLE) -> i32 { - let mut response: [u8; 1] = [0u8; 1]; - let mut bytes_read = 0; - match unsafe { - ReadFile( - read_end, - response.as_mut_ptr(), - 1, - &mut bytes_read, - std::ptr::null_mut(), - ) - } { - TRUE => { - println!( - "Child sent a byte, which indicates that it succeeded and is now shutting down in the background." - ); - // Child sent a byte, which indicates that it succeeded and is now shutting down in - // the background. - 0 - } - _ => { - eprintln!("Child closed pipe without sending a byte - getting process exit status"); - // Child closed pipe without sending a byte - get the process exit_status - let status = unsafe { NtWaitForSingleObject(hprocess, FALSE as _, ptr::null_mut()) }; - unsafe { - NtClose(hprocess); - NtClose(hthread); - }; - status - } - } -} - -unsafe fn fork(hprocess: &mut HANDLE, hthread: &mut HANDLE) -> i32 { - let mut create_info: PS_CREATE_INFO = unsafe { std::mem::zeroed() }; - create_info.Size = std::mem::size_of::() as _; - - unsafe { - NtCreateUserProcess( - hprocess, - hthread, - PROCESS_ALL_ACCESS, - THREAD_ALL_ACCESS, - std::ptr::null_mut(), - std::ptr::null_mut(), - PROCESS_CREATE_FLAGS_INHERIT_HANDLES, - 0, - std::ptr::null_mut(), - &mut create_info, - std::ptr::null_mut(), - ) - } -} - -fn make_pipe() -> Result<(HANDLE, HANDLE)> { - let mut read_end: HANDLE = std::ptr::null_mut(); - let mut write_end: HANDLE = std::ptr::null_mut(); - - let security_attributes = SECURITY_ATTRIBUTES { - nLength: std::mem::size_of::() as u32, - lpSecurityDescriptor: std::ptr::null_mut(), - bInheritHandle: TRUE, // The crucial part! - }; - - match unsafe { CreatePipe(&mut read_end, &mut write_end, &security_attributes, 0) } { - TRUE => Ok((read_end, write_end)), - _ => Err(Box::new(std::io::Error::last_os_error())), - } -} diff --git a/windows/wlibwild/w.just b/windows/wlibwild/w.just deleted file mode 100644 index 3ca2f9af8..000000000 --- a/windows/wlibwild/w.just +++ /dev/null @@ -1,23 +0,0 @@ -link: - cargo run -p wlibwild --bin main - -build-wild: - cargo build -p wild-linker --bin wild -r - -build-objs: - clang -c basic_objs/main.c -o basic_objs/main.o - clang -c basic_objs/function.c -o basic_objs/function.o - clang -c basic_objs/basic.c -o basic_objs/basic.o - -link-lld: - nu -c "lld-link basic_objs/main.o basic_objs/function.o /SUBSYSTEM:CONSOLE /entry:main /nodefaultlib kernel32.lib /OUT:myprogram.exe" - -wild-link: build-wild - nu -c "../../target/release/wild.exe basic_objs/main.o basic_objs/function.o /SUBSYSTEM:CONSOLE /entry:main /nodefaultlib kernel32.lib /OUT:myprogram.exe" - - -dump-exe: - @llvm-objdump --demangle --syms -C -D myprogram.exe - -run-myprogram: - nu -c "myprogram.exe" \ No newline at end of file From ddc01032da92c7bc30069ffe84ff9877c27b6354 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Sat, 7 Mar 2026 17:35:08 +1300 Subject: [PATCH 10/10] rename ArgsType to Args --- libwild/src/args.rs | 3350 +++++++++++++-------------- libwild/src/coff.rs | 2 +- libwild/src/diagnostics.rs | 550 ++--- libwild/src/elf.rs | 12 +- libwild/src/input_data.rs | 1930 ++++++++-------- libwild/src/layout.rs | 16 +- libwild/src/lib.rs | 888 ++++---- libwild/src/parsing.rs | 636 +++--- libwild/src/platform.rs | 24 +- libwild/src/resolution.rs | 3050 ++++++++++++------------- libwild/src/symbol_db.rs | 4390 ++++++++++++++++++------------------ 11 files changed, 7424 insertions(+), 7424 deletions(-) diff --git a/libwild/src/args.rs b/libwild/src/args.rs index 55557c093..5858ab37a 100644 --- a/libwild/src/args.rs +++ b/libwild/src/args.rs @@ -1,1675 +1,1675 @@ -//! A handwritten parser for our arguments. -//! -//! We don't currently use a 3rd party library like clap for a few reasons. Firstly, we need to -//! support flags like `--push-state` and `--pop-state`. These need to push and pop a state stack -//! when they're parsed. Some of the other flags then need to manipulate the state of the top of the -//! stack. Positional arguments like input files and libraries to link, then need to have the -//! current state of the stack attached to that file. -//! -//! Secondly, long arguments need to also be accepted with a single '-' in addition to the more -//! common double-dash. -//! -//! Basically, we need to be able to parse arguments in the same way as the other linkers on the -//! platform that we're targeting. - -pub(crate) mod consts; -pub(crate) mod linux; -pub(crate) mod windows; - -pub(crate) use consts::*; - -use crate::alignment::Alignment; -use crate::arch::Architecture; -use crate::bail; -use crate::error::Context as _; -use crate::error::Result; -use crate::input_data::FileId; -use crate::save_dir::SaveDir; -use crate::target_os::Os; -use hashbrown::HashMap; -use hashbrown::HashSet; -use jobserver::Client; -use std::fmt::Display; -use std::num::NonZeroUsize; -use std::path::Path; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::atomic::AtomicI64; -use target_lexicon::Triple; - -// ── Shared type definitions (format-agnostic) ──────────────────────────────── - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum VersionMode { - /// Don't print version - None, - /// Print version and continue linking (-v) - Verbose, - /// Print version and exit immediately (--version) - ExitAfterPrint, -} - -#[derive(Debug)] -pub(crate) enum DefsymValue { - /// A numeric value (address) - Value(u64), - /// Reference to another symbol with an optional offset - SymbolWithOffset(String, i64), -} - -#[derive(Debug)] -pub(crate) enum Strip { - Nothing, - Debug, - All, - Retain(HashSet>), -} - -#[derive(Debug, Clone, Copy)] -pub enum CounterKind { - Cycles, - Instructions, - CacheMisses, - BranchMisses, - PageFaults, - PageFaultsMinor, - PageFaultsMajor, - L1dRead, - L1dMiss, -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocations { - Allowed, - Disallowed(CopyRelocationsDisabledReason), -} - -#[derive(Debug, Clone, Copy)] -pub(crate) enum CopyRelocationsDisabledReason { - Flag, - SharedObject, -} - -impl Display for CopyRelocationsDisabledReason { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let reason = match self { - CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", - CopyRelocationsDisabledReason::SharedObject => "output is a shared object", - }; - Display::fmt(&reason, f) - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum RelocationModel { - NonRelocatable, - Relocatable, -} - -#[derive(Debug, Copy, Clone)] -pub(crate) enum Experiment { - /// How much parallelism to allow when splitting string-merge sections. - MergeStringSplitParallelism = 0, - - /// Number of bytes of string-merge sections before we'll break to a new group. - MergeStringMinGroupBytes = 1, - - GroupsPerThread = 2, - - MinGroups = 3, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum FileWriteMode { - /// The existing output file, if any, will be unlinked (deleted) and a new file with the same - /// name put in its place. Any hard links to the file will not be affected. - UnlinkAndReplace, - - /// The existing output file, if any, will be edited in-place. Any hard links to the file will - /// update accordingly. If the file is locked due to currently being executed, then our write - /// will fail. - UpdateInPlace, - - /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to - /// unlinking and replacing. - UpdateInPlaceWithFallback, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub(crate) enum BSymbolicKind { - None, - All, - Functions, - NonWeakFunctions, - NonWeak, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum UnresolvedSymbols { - /// Report all unresolved symbols. - ReportAll, - - /// Ignore unresolved symbols in shared libraries. - IgnoreInSharedLibs, - - /// Ignore unresolved symbols in object files. - IgnoreInObjectFiles, - - /// Ignore all unresolved symbols. - IgnoreAll, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum ExcludeLibs { - None, - All, - Some(HashSet>), -} - -impl ExcludeLibs { - pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { - match self { - ExcludeLibs::None => false, - ExcludeLibs::All => true, - ExcludeLibs::Some(libs) => { - let lib_path_str = String::from_utf8_lossy(lib_path); - let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); - - libs.contains(lib_name) - } - } - } -} - -#[derive(Debug, Eq, PartialEq, Clone, Copy)] -pub struct Modifiers { - /// Whether shared objects should only be linked if they're referenced. - pub(crate) as_needed: bool, - - /// Whether we're currently allowed to link against shared libraries. - pub(crate) allow_shared: bool, - - /// Whether object files in archives should be linked even if they do not contain symbols that - /// are referenced. - pub(crate) whole_archive: bool, - - /// Whether archive semantics should be applied even for regular objects. - pub(crate) archive_semantics: bool, - - /// Whether the file is known to be a temporary file that will be deleted when the linker - /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is - /// stored in the layout file if written so that linker-diff knows not to error if the file - /// is missing. - pub(crate) temporary: bool, -} - -impl Default for Modifiers { - fn default() -> Self { - Self { - as_needed: false, - allow_shared: true, - whole_archive: false, - archive_semantics: false, - temporary: false, - } - } -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) struct Input { - pub(crate) spec: InputSpec, - /// A directory to search first. Only present when the input came from a linker script, in - /// which case this is the directory containing the linker script. - pub(crate) search_first: Option, - pub(crate) modifiers: Modifiers, -} - -#[derive(Debug, Eq, PartialEq)] -pub(crate) enum InputSpec { - /// Path (possibly just a filename) to the file. - File(Box), - /// Name of the library, without prefix and suffix. - Lib(Box), - /// Name of the library, including prefix and suffix. - Search(Box), -} - -// ── End shared type definitions ────────────────────────────────────────────── - -// ── Argument parser infrastructure ─────────────────────────────────────────── - -pub(crate) struct ArgumentParser { - options: HashMap<&'static str, OptionHandler>, - short_options: HashMap<&'static str, OptionHandler>, - prefix_options: HashMap<&'static str, PrefixOptionHandler>, - case_insensitive: bool, - has_option_prefix: fn(&str) -> bool, - strip_option: for<'a> fn(&'a str) -> Option<&'a str>, - find_separator: fn(&str) -> Option, -} - -struct OptionHandler { - help_text: &'static str, - handler: OptionHandlerFn, - short_names: Vec<&'static str>, -} - -impl Clone for OptionHandler { - fn clone(&self) -> Self { - Self { - help_text: self.help_text, - handler: self.handler, - short_names: self.short_names.clone(), - } - } -} - -struct PrefixOptionHandler { - help_text: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, - sub_options: HashMap<&'static str, SubOption>, -} - -#[allow(clippy::enum_variant_names)] -enum OptionHandlerFn { - NoParam(fn(&mut Args, &mut Vec) -> Result<()>), - WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), - OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), -} - -impl Clone for OptionHandlerFn { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for OptionHandlerFn {} - -impl OptionHandlerFn { - fn help_suffix_long(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => "=", - OptionHandlerFn::OptionalParam(_) => "[=]", - } - } - - fn help_suffix_short(&self) -> &'static str { - match self { - OptionHandlerFn::NoParam(_) => "", - OptionHandlerFn::WithParam(_) => " ", - OptionHandlerFn::OptionalParam(_) => " []", - } - } -} - -pub(crate) struct OptionDeclaration<'a, T, S> { - parser: &'a mut ArgumentParser, - long_names: Vec<&'static str>, - short_names: Vec<&'static str>, - prefixes: Vec<&'static str>, - sub_options: HashMap<&'static str, SubOption>, - help_text: &'static str, - _phantom: std::marker::PhantomData, -} - -pub struct NoParam; -pub struct WithParam; -pub struct WithOptionalParam; - -enum SubOptionHandler { - /// Handler without value parameter (exact match) - NoValue(fn(&mut Args, &mut Vec) -> Result<()>), - /// Handler with value parameter (prefix match) - WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), -} - -impl Clone for SubOptionHandler { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOptionHandler {} - -struct SubOption { - help: &'static str, - handler: SubOptionHandler, -} - -impl Clone for SubOption { - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SubOption {} - -impl SubOption { - fn with_value(&self) -> bool { - matches!(self.handler, SubOptionHandler::WithValue(_)) - } -} - -impl Default for ArgumentParser { - fn default() -> Self { - Self::new() - } -} - -impl ArgumentParser { - #[must_use] - pub fn new() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: false, - has_option_prefix: |arg| arg.starts_with('-'), - strip_option: |arg| arg.strip_prefix("--").or(arg.strip_prefix('-')), - find_separator: |stripped| stripped.find('='), - } - } - - #[must_use] - pub fn new_case_insensitive() -> Self { - Self { - options: HashMap::new(), - short_options: HashMap::new(), - prefix_options: HashMap::new(), - case_insensitive: true, - has_option_prefix: |arg| arg.starts_with('/') || arg.starts_with('-'), - strip_option: |arg| arg.strip_prefix('/').or(arg.strip_prefix('-')), - find_separator: |stripped| stripped.find(':'), - } - } - - pub fn declare(&mut self) -> OptionDeclaration<'_, T, NoParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, T, WithParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - pub fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, T, WithOptionalParam> { - OptionDeclaration { - parser: self, - long_names: Vec::new(), - short_names: Vec::new(), - prefixes: Vec::new(), - sub_options: HashMap::new(), - help_text: "", - _phantom: std::marker::PhantomData, - } - } - - fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { - if self.case_insensitive { - if let Some(handler) = self.options.get(option_name) { - return Some(handler); - } - for (key, handler) in &self.options { - if key.eq_ignore_ascii_case(option_name) { - return Some(handler); - } - } - None - } else { - self.options.get(option_name) - } - } - - pub(crate) fn handle_argument, I: Iterator>( - &self, - args: &mut Args, - modifier_stack: &mut Vec, - arg: &str, - input: &mut I, - ) -> Result<()> { - // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. - // Handle `@file`option (recursively) - merging in the options contained in the file - if let Some(path) = arg.strip_prefix('@') { - let file_args = read_args_from_file(Path::new(path))?; - let mut file_arg_iter = file_args.iter(); - while let Some(file_arg) = file_arg_iter.next() { - self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; - } - return Ok(()); - } - - if let Some(stripped) = (self.strip_option)(arg) { - // Check for option with separator syntax - if let Some(eq_pos) = (self.find_separator)(stripped) { - let option_name = &stripped[..eq_pos]; - let value = &stripped[eq_pos + 1..]; - - if let Some(handler) = self.get_option_handler(option_name) { - match &handler.handler { - OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, - OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, - OptionHandlerFn::NoParam(_) => return Ok(()), - } - return Ok(()); - } - } else { - if stripped == "build-id" - && let Some(handler) = self.get_option_handler(stripped) - && let OptionHandlerFn::WithParam(f) = &handler.handler - { - f(args, modifier_stack, "fast")?; - return Ok(()); - } - - if let Some(handler) = self.get_option_handler(stripped) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - } - - if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { - let option_name = &arg[1..]; - if let Some(handler) = self.short_options.get(option_name) { - match &handler.handler { - OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, - OptionHandlerFn::WithParam(f) => { - let next_arg = - input.next().context(format!("Missing argument to {arg}"))?; - f(args, modifier_stack, next_arg.as_ref())?; - } - OptionHandlerFn::OptionalParam(f) => { - f(args, modifier_stack, None)?; - } - } - return Ok(()); - } - } - - // Prefix options. These should be handled after processing long and short options, - // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. - for (prefix, handler) in &self.prefix_options { - if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { - let value = if rest.is_empty() { - let next_arg = input - .next() - .context(format!("Missing argument to -{prefix}"))?; - next_arg.as_ref().to_owned() - } else { - rest.to_owned() - }; - - if let Some((key, param_value)) = value.split_once('=') { - // Value has '=', look up key with trailing '=' - if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { - match sub.handler { - SubOptionHandler::NoValue(_) => { - (handler.handler)(args, modifier_stack, &value)?; - } - SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } else { - // No '=' in value, look up exact match - if let Some(sub) = handler.sub_options.get(value.as_str()) { - match sub.handler { - SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, - SubOptionHandler::WithValue(_) => { - bail!("Option -{prefix} {value} requires a value"); - } - } - } else { - // Fall back to the main handler - (handler.handler)(args, modifier_stack, &value)?; - } - } - return Ok(()); - } - } - - if (self.has_option_prefix)(arg) { - if let Some(stripped) = (self.strip_option)(arg) - && IGNORED_FLAGS.contains(&stripped) - { - warn_unsupported(arg)?; - return Ok(()); - } - - args.unrecognized_options.push(arg.to_owned()); - return Ok(()); - } - - args.save_dir.handle_file(arg); - args.inputs.push(Input { - spec: InputSpec::File(Box::from(Path::new(arg))), - search_first: None, - modifiers: *modifier_stack.last().unwrap(), - }); - - Ok(()) - } - - #[must_use] - fn generate_help(&self) -> String { - let mut help = String::new(); - help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); - - let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); - prefix_options.sort_by_key(|(prefix, _)| *prefix); - - // TODO: This is ad-hoc - help.push_str(&format!( - " {:<31} Read options from a file\n", - format!("@"), - )); - - let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); - let mut processed_short_options: HashSet<&str> = HashSet::new(); - - // Collect all long options and their associated short options - for (long_name, handler) in &self.options { - if !handler.help_text.is_empty() { - let long_suffix = handler.handler.help_suffix_long(); - let mut option_names = vec![format!("--{long_name}{long_suffix}")]; - - // Add associated short options - let short_suffix = handler.handler.help_suffix_short(); - for short_char in &handler.short_names { - option_names.push(format!("-{short_char}{short_suffix}")); - } - - help_to_options - .entry(handler.help_text) - .or_default() - .extend(option_names); - } - - // Mark short options of help-less handlers as processed - for short_name in &handler.short_names { - processed_short_options.insert(short_name); - } - } - - for (prefix, handler) in prefix_options { - if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { - help.push_str(&format!( - " -{:<30} {}\n", - format!("{prefix} "), - handler.help_text - )); - - // Add sub-options if they exist - let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); - sub_options.sort_by_key(|(name, _)| *name); - - for (sub_name, sub) in sub_options { - let display_name = if sub.with_value() && sub_name.ends_with('=') { - // sub_name ends with '=' (e.g., "max-page-size="), so add - format!("{sub_name}") - } else { - sub_name.to_string() - }; - help.push_str(&format!( - " -{prefix} {display_name:<30} {sub_help}\n", - sub_help = sub.help - )); - } - } - } - - // Add short-only options - for (short_char, handler) in &self.short_options { - if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { - let short_suffix = handler.handler.help_suffix_short(); - help_to_options - .entry(handler.help_text) - .or_default() - .push(format!("-{short_char}{short_suffix}")); - } - } - - let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); - sorted_help_groups.sort_by_key(|(_, option_names)| { - option_names.iter().min().unwrap_or(&String::new()).clone() - }); - - for (help_text, mut option_names) in sorted_help_groups { - option_names.sort_by(|a, b| { - let a_is_short = a.len() == 2 && a.starts_with('-'); - let b_is_short = b.len() == 2 && b.starts_with('-'); - match (a_is_short, b_is_short) { - (true, false) => std::cmp::Ordering::Less, // short options first - (false, true) => std::cmp::Ordering::Greater, // long options after - _ => a.cmp(b), // same type, alphabetical - } - }); - - let option_names_str = option_names.join(", "); - help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); - } - - help - } -} - -impl<'a, T, S> OptionDeclaration<'a, T, S> { - #[must_use] - pub fn long(mut self, name: &'static str) -> Self { - self.long_names.push(name); - self - } - - #[must_use] - pub fn short(mut self, option: &'static str) -> Self { - self.short_names.push(option); - self - } - - #[must_use] - pub fn help(mut self, text: &'static str) -> Self { - self.help_text = text; - self - } - - pub fn prefix(mut self, prefix: &'static str) -> Self { - self.prefixes.push(prefix); - self - } - - #[must_use] - pub fn sub_option( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut Args, &mut Vec) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::NoValue(handler), - }, - ); - self - } - - #[must_use] - pub fn sub_option_with_value( - mut self, - name: &'static str, - help: &'static str, - handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, - ) -> Self { - self.sub_options.insert( - name, - SubOption { - help, - handler: SubOptionHandler::WithValue(handler), - }, - ); - self - } -} - -impl<'a, T> OptionDeclaration<'a, T, NoParam> { - pub fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::NoParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} - -impl<'a, T> OptionDeclaration<'a, T, WithParam> { - pub fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { - let mut short_names = self.short_names.clone(); - short_names.extend_from_slice(&self.prefixes); - - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::WithParam(handler), - short_names, - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - - for prefix in self.prefixes { - let prefix_handler = PrefixOptionHandler { - help_text: self.help_text, - sub_options: self.sub_options.clone(), - handler, - }; - - self.parser.prefix_options.insert(prefix, prefix_handler); - } - } -} - -impl<'a, T> OptionDeclaration<'a, T, WithOptionalParam> { - pub fn execute( - self, - handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>, - ) { - let option_handler = OptionHandler { - help_text: self.help_text, - handler: OptionHandlerFn::OptionalParam(handler), - short_names: self.short_names.clone(), - }; - - for name in self.long_names { - self.parser.options.insert(name, option_handler.clone()); - } - - for option in self.short_names { - self.parser - .short_options - .insert(option, option_handler.clone()); - } - } -} - -// ── End argument parser infrastructure ─────────────────────────────────────── - -pub(crate) fn add_silently_ignored_flags(parser: &mut ArgumentParser) { - fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { - Ok(()) - } - for flag in SILENTLY_IGNORED_FLAGS { - parser.declare().long(flag).execute(noop); - } - for flag in SILENTLY_IGNORED_SHORT_FLAGS { - parser.declare().short(flag).execute(noop); - } -} - -pub(crate) fn add_default_flags(parser: &mut ArgumentParser) { - fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { - Ok(()) - } - for flag in DEFAULT_FLAGS { - parser.declare().long(flag).execute(noop); - } - for flag in DEFAULT_SHORT_FLAGS { - parser.declare().short(flag).execute(noop); - } -} - -pub(crate) fn read_args_from_file(path: &Path) -> Result> { - let contents = std::fs::read_to_string(path) - .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; - arguments_from_string(&contents) -} - -/// Parses arguments from a string, handling quoting, escapes etc. -/// All arguments must be surrounded by a white space. -pub(crate) fn arguments_from_string(input: &str) -> Result> { - const QUOTES: [char; 2] = ['\'', '"']; - - let mut out = Vec::new(); - let mut chars = input.chars(); - let mut heap = None; - let mut quote = None; - let mut expect_whitespace = false; - - loop { - let Some(mut ch) = chars.next() else { - if let Some(quote) = quote.take() { - bail!("Missing closing '{quote}'"); - } - if let Some(arg) = heap.take() { - out.push(arg); - } - break; - }; - - crate::ensure!( - !expect_whitespace || ch.is_whitespace(), - "Expected white space after quoted argument" - ); - expect_whitespace = false; - - if QUOTES.contains(&ch) { - if let Some(qchr) = quote { - if qchr == ch { - // close the argument - if let Some(arg) = heap.take() { - out.push(arg); - } - quote = None; - expect_whitespace = true; - } else { - // accept the other quoting character as normal char - heap.get_or_insert(String::new()).push(ch); - } - } else { - // beginning of a new argument - crate::ensure!(heap.is_none(), "Missing opening quote '{ch}'"); - quote = Some(ch); - } - } else if ch.is_whitespace() { - if quote.is_none() { - if let Some(arg) = heap.take() { - out.push(arg); - } - } else { - heap.get_or_insert(String::new()).push(ch); - } - } else { - if ch == '\\' && (quote.is_some() || !cfg!(target_os = "windows")) { - ch = chars.next().context("Invalid escape")?; - } - heap.get_or_insert(String::new()).push(ch); - } - } - - Ok(out) -} - -pub(super) fn warn_unsupported(opt: &str) -> Result { - match std::env::var(WILD_UNSUPPORTED_ENV) - .unwrap_or_default() - .as_str() - { - "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), - "ignore" => {} - "error" => bail!("{opt} is not yet supported"), - other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), - } - Ok(()) -} - -/// The output binary format. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum OutputFormat { - Elf, - Pe, -} - -impl Default for OutputFormat { - fn default() -> Self { - match Os::DEFAULT { - Os::Linux => OutputFormat::Elf, - Os::Windows => OutputFormat::Pe, - Os::MacOS => todo!("macOS linking not yet supported"), - } - } -} - -/// Result of pre-scanning args for target-determining flags. -#[derive(Debug)] -pub(crate) struct DetectedTarget { - pub format: OutputFormat, - /// Architecture from `--target` triple. `None` if no `--target` was given. - pub arch: Option, -} - -/// Known `-m` emulation values that imply ELF output. -const ELF_EMULATIONS: &[&str] = &[ - "elf_x86_64", - "elf_x86_64_sol2", - "aarch64elf", - "aarch64linux", - "elf64lriscv", - "elf64loongarch", -]; - -/// Map `target_lexicon::Architecture` to Wild's `Architecture`. -fn map_triple_arch(arch: target_lexicon::Architecture) -> Result { - use target_lexicon::Architecture as TL; - match arch { - TL::X86_64 | TL::X86_64h => Ok(Architecture::X86_64), - TL::Aarch64(_) => Ok(Architecture::AArch64), - TL::Riscv64(_) => Ok(Architecture::RISCV64), - TL::LoongArch64 => Ok(Architecture::LoongArch64), - other => bail!("unsupported architecture in target triple: {other}"), - } -} - -/// Map `target_lexicon::BinaryFormat` to `OutputFormat`. -fn map_binary_format(fmt: target_lexicon::BinaryFormat) -> Result { - match fmt { - target_lexicon::BinaryFormat::Elf => Ok(OutputFormat::Elf), - target_lexicon::BinaryFormat::Coff => Ok(OutputFormat::Pe), - other => bail!("unsupported binary format: {other}"), - } -} - -/// Extract the target triple value from a flag, handling all prefix styles. -/// Returns `(Some(value), consumed_next)` if the arg is a target flag. -fn extract_target_value<'a>(arg: &'a str, next_arg: Option<&'a str>) -> (Option<&'a str>, bool) { - // Combined forms: --target=VAL, -target=VAL, /TARGET:VAL - if let Some(val) = arg - .strip_prefix("--target=") - .or_else(|| arg.strip_prefix("-target=")) - .or_else(|| arg.strip_prefix("/TARGET:")) - .or_else(|| arg.strip_prefix("/target:")) - { - return (Some(val), false); - } - // Space-separated: --target VAL, -target VAL, /TARGET VAL - if matches!(arg, "--target" | "-target" | "/TARGET" | "/target") { - if let Some(val) = next_arg { - return (Some(val), true); - } - } - (None, false) -} - -/// Pre-scan CLI arguments to determine the output format and architecture. -/// -/// Recognizes: -/// - `--target=` / `-target=` / `/TARGET:` — primary (parsed by target-lexicon) -/// - `-m ` — overrides format to ELF when present -/// -/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only. -pub(crate) fn detect_target(args: &[String]) -> Result { - let mut from_triple: Option<(OutputFormat, Architecture)> = None; - let mut m_implies_elf = false; - - let mut i = 0; - while i < args.len() { - let next = if i + 1 < args.len() { - Some(args[i + 1].as_str()) - } else { - None - }; - let (target_val, consumed_next) = extract_target_value(&args[i], next); - - if let Some(val) = target_val { - let triple: Triple = val - .parse() - .map_err(|e| anyhow::anyhow!("invalid target triple '{val}': {e}"))?; - let format = map_binary_format(triple.binary_format)?; - let arch = map_triple_arch(triple.architecture)?; - from_triple = Some((format, arch)); - if consumed_next { - i += 1; - } - } - // Check for -m (implies ELF) - else if args[i] == "-m" || args[i] == "--m" { - if let Some(next_val) = next { - if ELF_EMULATIONS.contains(&next_val) { - m_implies_elf = true; - } - i += 1; - } - } else if let Some(emu) = args[i].strip_prefix("-m") { - if ELF_EMULATIONS.contains(&emu) { - m_implies_elf = true; - } - } - - i += 1; - } - - match (from_triple, m_implies_elf) { - (Some((_, arch)), true) => { - // -m overrides format to ELF; arch from triple preserved - Ok(DetectedTarget { - format: OutputFormat::Elf, - arch: Some(arch), - }) - } - (Some((format, arch)), false) => Ok(DetectedTarget { - format, - arch: Some(arch), - }), - (None, true) => Ok(DetectedTarget { - format: OutputFormat::Elf, - arch: None, - }), - (None, false) => Ok(DetectedTarget { - format: OutputFormat::default(), - arch: None, - }), - } -} - -/// Map Wild `Architecture` to the GNU ld `-m` emulation name. -fn arch_to_elf_emulation(arch: Architecture) -> &'static str { - match arch { - Architecture::X86_64 => "elf_x86_64", - Architecture::AArch64 => "aarch64linux", - Architecture::RISCV64 => "elf64lriscv", - Architecture::LoongArch64 => "elf64loongarch", - } -} - -/// Map Wild `Architecture` to the MSVC `/MACHINE:` value. -fn arch_to_machine_value(arch: Architecture) -> &'static str { - match arch { - Architecture::X86_64 => "X64", - Architecture::AArch64 => "ARM64", - Architecture::RISCV64 => "X64", - Architecture::LoongArch64 => "X64", - } -} - -/// Strip `--target`/`-target`/`/TARGET` flags and inject a synthetic `-m` or `/MACHINE:` flag -/// from the detected architecture so the format-specific parser picks it up. -/// -/// The user's explicit `-m` or `/MACHINE:` flags are preserved and will override the injected one -/// since they appear later in the argument list. -pub(crate) fn filter_and_inject_target_flags( - args: &[String], - format: OutputFormat, - arch: Option, -) -> Vec { - let mut result = Vec::with_capacity(args.len() + 2); - - // Inject synthetic arch flag at the front (user's explicit flags override later) - if let Some(arch) = arch { - match format { - OutputFormat::Elf => { - result.push("-m".to_string()); - result.push(arch_to_elf_emulation(arch).to_string()); - } - OutputFormat::Pe => { - result.push(format!("/MACHINE:{}", arch_to_machine_value(arch))); - } - } - } - - // Strip --target flags, keep everything else - let mut i = 0; - while i < args.len() { - let arg = &args[i]; - if arg.starts_with("--target=") - || arg.starts_with("-target=") - || arg.starts_with("/TARGET:") - || arg.starts_with("/target:") - { - // Skip this combined arg - } else if matches!(arg.as_str(), "--target" | "-target" | "/TARGET" | "/target") { - i += 1; // skip value too - } else { - result.push(arg.clone()); - } - i += 1; - } - result -} - -/// Format-specific parsed arguments. -pub enum TargetArgs { - Elf(linux::ElfArgs), - #[allow(dead_code)] - Pe(windows::PeArgs), -} - -impl std::fmt::Debug for TargetArgs { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TargetArgs::Elf(e) => e.fmt(f), - TargetArgs::Pe(p) => p.fmt(f), - } - } -} - -/// Parsed linker arguments. Common fields are directly accessible. -/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target_args`. -/// -/// `T` defaults to `TargetArgs` (the enum). During parsing, `T` is set to the -/// concrete format type (e.g. `ElfArgs` or `PeArgs`). -#[derive(Debug)] -pub struct Args { - // ── Infrastructure ─────────────────────────────────────────────────────── - pub should_fork: bool, - pub(crate) output: Arc, - pub(crate) arch: Architecture, - pub(crate) inputs: Vec, - pub(crate) lib_search_path: Vec>, - pub num_threads: Option, - pub(crate) available_threads: NonZeroUsize, - pub(crate) save_dir: SaveDir, - pub(crate) unrecognized_options: Vec, - pub(crate) files_per_group: Option, - pub(crate) write_layout: bool, - pub(crate) write_trace: bool, - pub(crate) jobserver_client: Option, - - // ── Core linker behavior ───────────────────────────────────────────────── - pub(crate) strip: Strip, - pub(crate) gc_sections: bool, - pub(crate) merge_sections: bool, - pub(crate) relax: bool, - pub(crate) demangle: bool, - pub(crate) no_undefined: bool, - pub(crate) allow_shlib_undefined: bool, - pub(crate) error_unresolved_symbols: bool, - pub(crate) allow_multiple_definitions: bool, - pub(crate) unresolved_symbols: UnresolvedSymbols, - pub(crate) undefined: Vec, - pub(crate) copy_relocations: CopyRelocations, - pub(crate) sysroot: Option>, - pub(crate) dynamic_linker: Option>, - pub(crate) entry: Option, - pub(crate) wrap: Vec, - pub(crate) exclude_libs: ExcludeLibs, - pub(crate) b_symbolic: BSymbolicKind, - pub(crate) export_list: Vec, - pub(crate) defsym: Vec<(String, DefsymValue)>, - pub(crate) section_start: HashMap, - pub(crate) max_page_size: Option, - pub(crate) execstack: bool, - pub(crate) version_mode: VersionMode, - pub(crate) relocation_model: RelocationModel, - pub(crate) should_output_executable: bool, - pub(crate) export_all_dynamic_symbols: bool, - pub(crate) version_script_path: Option, - pub(crate) export_list_path: Option, - - // ── Output/writing ─────────────────────────────────────────────────────── - pub(crate) mmap_output_file: bool, - pub(crate) file_write_mode: Option, - pub(crate) prepopulate_maps: bool, - pub(crate) should_write_linker_identity: bool, - - // ── Debug/diagnostic ───────────────────────────────────────────────────── - pub(crate) debug_fuel: Option, - pub(crate) validate_output: bool, - pub(crate) sym_info: Option, - pub(crate) debug_address: Option, - pub(crate) print_allocations: Option, - pub(crate) verify_allocation_consistency: bool, - pub(crate) time_phase_options: Option>, - pub(crate) numeric_experiments: Vec>, - pub(crate) write_gc_stats: Option, - pub(crate) gc_stats_ignore: Vec, - pub(crate) verbose_gc_stats: bool, - pub(crate) dependency_file: Option, - - // ── Format-specific ────────────────────────────────────────────────────── - pub target_args: T, -} - -impl Default for Args { - fn default() -> Self { - Args { - // Infrastructure - should_fork: true, - arch: Architecture::DEFAULT, - unrecognized_options: Vec::new(), - lib_search_path: Vec::new(), - inputs: Vec::new(), - output: Arc::from(Path::new("a.out")), - num_threads: None, - write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), - write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), - files_per_group: None, - save_dir: Default::default(), - jobserver_client: None, - available_threads: NonZeroUsize::new(1).unwrap(), - // Core linker behavior - strip: Strip::Nothing, - gc_sections: true, - merge_sections: true, - relax: true, - demangle: true, - no_undefined: false, - allow_shlib_undefined: false, - error_unresolved_symbols: true, - allow_multiple_definitions: false, - unresolved_symbols: UnresolvedSymbols::ReportAll, - undefined: Vec::new(), - copy_relocations: CopyRelocations::Allowed, - sysroot: None, - dynamic_linker: None, - entry: None, - wrap: Vec::new(), - exclude_libs: ExcludeLibs::None, - b_symbolic: BSymbolicKind::None, - export_list: Vec::new(), - defsym: Vec::new(), - section_start: HashMap::new(), - max_page_size: None, - execstack: false, - version_mode: VersionMode::None, - relocation_model: RelocationModel::NonRelocatable, - should_output_executable: true, - export_all_dynamic_symbols: false, - version_script_path: None, - export_list_path: None, - // Output/writing - mmap_output_file: true, - file_write_mode: None, - prepopulate_maps: false, - should_write_linker_identity: true, - // Debug/diagnostic - debug_fuel: None, - validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), - sym_info: None, - debug_address: None, - print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") - .ok() - .and_then(|s| s.parse().ok()) - .map(FileId::from_encoded), - verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) - .is_ok_and(|v| v == "1"), - time_phase_options: None, - numeric_experiments: Vec::new(), - write_gc_stats: None, - gc_stats_ignore: Vec::new(), - verbose_gc_stats: false, - dependency_file: None, - // Format-specific - target_args: T::default(), - } - } -} - -impl std::ops::Deref for Args { - type Target = T; - fn deref(&self) -> &T { - &self.target_args - } -} - -impl std::ops::DerefMut for Args { - fn deref_mut(&mut self) -> &mut T { - &mut self.target_args - } -} - -impl Args { - /// Transform the target-specific part while preserving common fields. - pub fn map_target(self, f: impl FnOnce(T) -> U) -> Args { - Args { - // Infrastructure - should_fork: self.should_fork, - output: self.output, - arch: self.arch, - inputs: self.inputs, - lib_search_path: self.lib_search_path, - num_threads: self.num_threads, - available_threads: self.available_threads, - save_dir: self.save_dir, - unrecognized_options: self.unrecognized_options, - files_per_group: self.files_per_group, - write_layout: self.write_layout, - write_trace: self.write_trace, - jobserver_client: self.jobserver_client, - // Core linker behavior - strip: self.strip, - gc_sections: self.gc_sections, - merge_sections: self.merge_sections, - relax: self.relax, - demangle: self.demangle, - no_undefined: self.no_undefined, - allow_shlib_undefined: self.allow_shlib_undefined, - error_unresolved_symbols: self.error_unresolved_symbols, - allow_multiple_definitions: self.allow_multiple_definitions, - unresolved_symbols: self.unresolved_symbols, - undefined: self.undefined, - copy_relocations: self.copy_relocations, - sysroot: self.sysroot, - dynamic_linker: self.dynamic_linker, - entry: self.entry, - wrap: self.wrap, - exclude_libs: self.exclude_libs, - b_symbolic: self.b_symbolic, - export_list: self.export_list, - defsym: self.defsym, - section_start: self.section_start, - max_page_size: self.max_page_size, - execstack: self.execstack, - version_mode: self.version_mode, - relocation_model: self.relocation_model, - should_output_executable: self.should_output_executable, - export_all_dynamic_symbols: self.export_all_dynamic_symbols, - version_script_path: self.version_script_path, - export_list_path: self.export_list_path, - // Output/writing - mmap_output_file: self.mmap_output_file, - file_write_mode: self.file_write_mode, - prepopulate_maps: self.prepopulate_maps, - should_write_linker_identity: self.should_write_linker_identity, - // Debug/diagnostic - debug_fuel: self.debug_fuel, - validate_output: self.validate_output, - sym_info: self.sym_info, - debug_address: self.debug_address, - print_allocations: self.print_allocations, - verify_allocation_consistency: self.verify_allocation_consistency, - time_phase_options: self.time_phase_options, - numeric_experiments: self.numeric_experiments, - write_gc_stats: self.write_gc_stats, - gc_stats_ignore: self.gc_stats_ignore, - verbose_gc_stats: self.verbose_gc_stats, - dependency_file: self.dependency_file, - // Format-specific - target_args: f(self.target_args), - } - } - - pub fn map_ref_target(&self, f: impl FnOnce(&T) -> U) -> U { - f(&self.target_args) - } - - /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when - /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the - /// caller should take a different branch depending on whether the value is still positive. You - /// can then do a binary search. - pub(crate) fn use_debug_fuel(&self) -> i64 { - let Some(fuel) = self.debug_fuel.as_ref() else { - return i64::MAX; - }; - fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 - } - - /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls - /// `last_cb`. - #[allow(unused)] - pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { - match self.use_debug_fuel() { - 1.. => true, - 0 => { - last_cb(); - true - } - _ => false, - } - } - - pub(crate) fn trace_span_for_file( - &self, - file_id: FileId, - ) -> Option { - let should_trace = self.print_allocations == Some(file_id); - should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) - } - - pub fn should_fork(&self) -> bool { - self.should_fork - } - - pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { - self.numeric_experiments - .get(exp as usize) - .copied() - .flatten() - .unwrap_or(default) - } - - pub(crate) fn loadable_segment_alignment(&self) -> Alignment { - if let Some(max_page_size) = self.max_page_size { - return max_page_size; - } - - match self.arch { - Architecture::X86_64 => Alignment { exponent: 12 }, - Architecture::AArch64 => Alignment { exponent: 16 }, - Architecture::RISCV64 => Alignment { exponent: 12 }, - Architecture::LoongArch64 => Alignment { exponent: 16 }, - } - } - - pub(crate) fn strip_all(&self) -> bool { - matches!(self.strip, Strip::All) - } - - pub(crate) fn strip_debug(&self) -> bool { - matches!(self.strip, Strip::All | Strip::Debug) - } -} - -/// Linker args with an activated thread pool. Holds jobserver tokens for the -/// duration of the link to keep the threads available. -pub struct ActivatedArgs { - pub args: Args, - _jobserver_tokens: Vec, -} - -impl ActivatedArgs { - pub fn map_target(self, f: impl FnOnce(T) -> U) -> ActivatedArgs { - ActivatedArgs { - args: self.args.map_target(f), - _jobserver_tokens: self._jobserver_tokens, - } - } -} - -impl Args { - /// Sets up the thread pool, using the explicit number of threads if specified, - /// or falling back to the jobserver protocol if available. - /// - /// - pub fn activate_thread_pool(mut self) -> Result> { - crate::timing_phase!("Activate thread pool"); - - let mut tokens = Vec::new(); - self.available_threads = self.num_threads.unwrap_or_else(|| { - if let Some(client) = &self.jobserver_client { - while let Ok(Some(acquired)) = client.try_acquire() { - tokens.push(acquired); - } - tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); - // Our parent "holds" one jobserver token, add it. - NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() - } else { - std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) - } - }); - - // The pool might be already initialized, suppress the error intentionally. - let _ = rayon::ThreadPoolBuilder::new() - .num_threads(self.available_threads.get()) - .build_global(); - - Ok(ActivatedArgs { - args: self, - _jobserver_tokens: tokens, - }) - } -} - -impl Args { - /// Parse CLI arguments. Detects target format from `--target=`, `-m`, - /// or host default, then routes to the format-specific parser. - pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { - let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); - let detected = detect_target(&all_args)?; - let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); - - match detected.format { - OutputFormat::Elf => { - let elf_args = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; - Ok(elf_args.map_target(TargetArgs::Elf)) - } - OutputFormat::Pe => { - let pe_args = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; - Ok(pe_args.map_target(TargetArgs::Pe)) - } - } - } -} - -/// Top-level parse function. -pub fn parse I, S: AsRef, I: Iterator>( - input: F, -) -> Result> { - Args::parse(input) -} - -#[cfg(test)] -mod tests { - use super::*; - - fn to_strings(args: &[&str]) -> Vec { - args.iter().map(|s| s.to_string()).collect() - } - - // ---- detect_target tests ---- - - #[test] - fn test_detect_format_from_triple_linux_x86() { - let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::X86_64)); - } - - #[test] - fn test_detect_format_from_triple_windows() { - let args = to_strings(&["-target=x86_64-pc-windows-msvc", "/OUT:foo.exe"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Pe); - assert_eq!(result.arch, Some(Architecture::X86_64)); - } - - #[test] - fn test_detect_format_from_slash_target() { - let args = to_strings(&["/TARGET:aarch64-pc-windows-msvc", "foo.obj"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Pe); - assert_eq!(result.arch, Some(Architecture::AArch64)); - } - - #[test] - fn test_detect_format_space_separated() { - let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::AArch64)); - } - - #[test] - fn test_detect_format_from_m_flag() { - let args = to_strings(&["-m", "elf_x86_64", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, None); - } - - #[test] - fn test_m_flag_overrides_target_format() { - let args = to_strings(&["--target=x86_64-pc-windows-msvc", "-m", "elf_x86_64"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - } - - #[test] - fn test_detect_format_default_no_flags() { - let args = to_strings(&["-o", "out", "foo.o"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::default()); - assert_eq!(result.arch, None); - } - - #[test] - fn test_detect_format_riscv_triple() { - let args = to_strings(&["--target=riscv64gc-unknown-linux-gnu", "-o", "out"]); - let result = detect_target(&args).unwrap(); - assert_eq!(result.format, OutputFormat::Elf); - assert_eq!(result.arch, Some(Architecture::RISCV64)); - } - - // ---- filter_and_inject_target_flags tests ---- - - #[test] - fn test_filter_strips_target_equals() { - let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "elf_x86_64"); - assert_eq!(filtered[2], "-o"); - assert!(!filtered.iter().any(|a| a.contains("--target"))); - } - - #[test] - fn test_filter_strips_target_space() { - let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "aarch64linux"); - assert!( - !filtered - .iter() - .any(|a| a == "--target" || a.contains("linux-gnu")) - ); - } - - #[test] - fn test_filter_strips_slash_target() { - let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "/MACHINE:X64"); - assert_eq!(filtered[1], "/OUT:foo.exe"); - } - - #[test] - fn test_filter_preserves_m_flag() { - let args = to_strings(&[ - "--target=x86_64-unknown-linux-gnu", - "-m", - "aarch64linux", - "-o", - "out", - ]); - let filtered = - filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); - assert_eq!(filtered[0], "-m"); - assert_eq!(filtered[1], "elf_x86_64"); - assert!(filtered.contains(&"-m".to_string())); - assert!(filtered.contains(&"aarch64linux".to_string())); - } - - #[test] - fn test_filter_no_target_no_inject() { - let args = to_strings(&["-o", "out", "foo.o"]); - let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, None); - assert_eq!(filtered, args); - } -} +//! A handwritten parser for our arguments. +//! +//! We don't currently use a 3rd party library like clap for a few reasons. Firstly, we need to +//! support flags like `--push-state` and `--pop-state`. These need to push and pop a state stack +//! when they're parsed. Some of the other flags then need to manipulate the state of the top of the +//! stack. Positional arguments like input files and libraries to link, then need to have the +//! current state of the stack attached to that file. +//! +//! Secondly, long arguments need to also be accepted with a single '-' in addition to the more +//! common double-dash. +//! +//! Basically, we need to be able to parse arguments in the same way as the other linkers on the +//! platform that we're targeting. + +pub(crate) mod consts; +pub(crate) mod linux; +pub(crate) mod windows; + +pub(crate) use consts::*; + +use crate::alignment::Alignment; +use crate::arch::Architecture; +use crate::bail; +use crate::error::Context as _; +use crate::error::Result; +use crate::input_data::FileId; +use crate::save_dir::SaveDir; +use crate::target_os::Os; +use hashbrown::HashMap; +use hashbrown::HashSet; +use jobserver::Client; +use std::fmt::Display; +use std::num::NonZeroUsize; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::atomic::AtomicI64; +use target_lexicon::Triple; + +// ── Shared type definitions (format-agnostic) ──────────────────────────────── + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum VersionMode { + /// Don't print version + None, + /// Print version and continue linking (-v) + Verbose, + /// Print version and exit immediately (--version) + ExitAfterPrint, +} + +#[derive(Debug)] +pub(crate) enum DefsymValue { + /// A numeric value (address) + Value(u64), + /// Reference to another symbol with an optional offset + SymbolWithOffset(String, i64), +} + +#[derive(Debug)] +pub(crate) enum Strip { + Nothing, + Debug, + All, + Retain(HashSet>), +} + +#[derive(Debug, Clone, Copy)] +pub enum CounterKind { + Cycles, + Instructions, + CacheMisses, + BranchMisses, + PageFaults, + PageFaultsMinor, + PageFaultsMajor, + L1dRead, + L1dMiss, +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocations { + Allowed, + Disallowed(CopyRelocationsDisabledReason), +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum CopyRelocationsDisabledReason { + Flag, + SharedObject, +} + +impl Display for CopyRelocationsDisabledReason { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let reason = match self { + CopyRelocationsDisabledReason::Flag => "the flag -z nocopyreloc was supplied", + CopyRelocationsDisabledReason::SharedObject => "output is a shared object", + }; + Display::fmt(&reason, f) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum RelocationModel { + NonRelocatable, + Relocatable, +} + +#[derive(Debug, Copy, Clone)] +pub(crate) enum Experiment { + /// How much parallelism to allow when splitting string-merge sections. + MergeStringSplitParallelism = 0, + + /// Number of bytes of string-merge sections before we'll break to a new group. + MergeStringMinGroupBytes = 1, + + GroupsPerThread = 2, + + MinGroups = 3, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum FileWriteMode { + /// The existing output file, if any, will be unlinked (deleted) and a new file with the same + /// name put in its place. Any hard links to the file will not be affected. + UnlinkAndReplace, + + /// The existing output file, if any, will be edited in-place. Any hard links to the file will + /// update accordingly. If the file is locked due to currently being executed, then our write + /// will fail. + UpdateInPlace, + + /// As for `UpdateInPlace`, but if we get an error opening the file for write, fallback to + /// unlinking and replacing. + UpdateInPlaceWithFallback, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub(crate) enum BSymbolicKind { + None, + All, + Functions, + NonWeakFunctions, + NonWeak, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum UnresolvedSymbols { + /// Report all unresolved symbols. + ReportAll, + + /// Ignore unresolved symbols in shared libraries. + IgnoreInSharedLibs, + + /// Ignore unresolved symbols in object files. + IgnoreInObjectFiles, + + /// Ignore all unresolved symbols. + IgnoreAll, +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum ExcludeLibs { + None, + All, + Some(HashSet>), +} + +impl ExcludeLibs { + pub(crate) fn should_exclude(&self, lib_path: &[u8]) -> bool { + match self { + ExcludeLibs::None => false, + ExcludeLibs::All => true, + ExcludeLibs::Some(libs) => { + let lib_path_str = String::from_utf8_lossy(lib_path); + let lib_name = lib_path_str.rsplit('/').next().unwrap_or(&lib_path_str); + + libs.contains(lib_name) + } + } + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub struct Modifiers { + /// Whether shared objects should only be linked if they're referenced. + pub(crate) as_needed: bool, + + /// Whether we're currently allowed to link against shared libraries. + pub(crate) allow_shared: bool, + + /// Whether object files in archives should be linked even if they do not contain symbols that + /// are referenced. + pub(crate) whole_archive: bool, + + /// Whether archive semantics should be applied even for regular objects. + pub(crate) archive_semantics: bool, + + /// Whether the file is known to be a temporary file that will be deleted when the linker + /// exits, e.g. an output file from a linker plugin. This doesn't affect linking, but is + /// stored in the layout file if written so that linker-diff knows not to error if the file + /// is missing. + pub(crate) temporary: bool, +} + +impl Default for Modifiers { + fn default() -> Self { + Self { + as_needed: false, + allow_shared: true, + whole_archive: false, + archive_semantics: false, + temporary: false, + } + } +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) struct Input { + pub(crate) spec: InputSpec, + /// A directory to search first. Only present when the input came from a linker script, in + /// which case this is the directory containing the linker script. + pub(crate) search_first: Option, + pub(crate) modifiers: Modifiers, +} + +#[derive(Debug, Eq, PartialEq)] +pub(crate) enum InputSpec { + /// Path (possibly just a filename) to the file. + File(Box), + /// Name of the library, without prefix and suffix. + Lib(Box), + /// Name of the library, including prefix and suffix. + Search(Box), +} + +// ── End shared type definitions ────────────────────────────────────────────── + +// ── Argument parser infrastructure ─────────────────────────────────────────── + +pub(crate) struct ArgumentParser { + options: HashMap<&'static str, OptionHandler>, + short_options: HashMap<&'static str, OptionHandler>, + prefix_options: HashMap<&'static str, PrefixOptionHandler>, + case_insensitive: bool, + has_option_prefix: fn(&str) -> bool, + strip_option: for<'a> fn(&'a str) -> Option<&'a str>, + find_separator: fn(&str) -> Option, +} + +struct OptionHandler { + help_text: &'static str, + handler: OptionHandlerFn, + short_names: Vec<&'static str>, +} + +impl Clone for OptionHandler { + fn clone(&self) -> Self { + Self { + help_text: self.help_text, + handler: self.handler, + short_names: self.short_names.clone(), + } + } +} + +struct PrefixOptionHandler { + help_text: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + sub_options: HashMap<&'static str, SubOption>, +} + +#[allow(clippy::enum_variant_names)] +enum OptionHandlerFn { + NoParam(fn(&mut Args, &mut Vec) -> Result<()>), + WithParam(fn(&mut Args, &mut Vec, &str) -> Result<()>), + OptionalParam(fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>), +} + +impl Clone for OptionHandlerFn { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for OptionHandlerFn {} + +impl OptionHandlerFn { + fn help_suffix_long(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => "=", + OptionHandlerFn::OptionalParam(_) => "[=]", + } + } + + fn help_suffix_short(&self) -> &'static str { + match self { + OptionHandlerFn::NoParam(_) => "", + OptionHandlerFn::WithParam(_) => " ", + OptionHandlerFn::OptionalParam(_) => " []", + } + } +} + +pub(crate) struct OptionDeclaration<'a, T, S> { + parser: &'a mut ArgumentParser, + long_names: Vec<&'static str>, + short_names: Vec<&'static str>, + prefixes: Vec<&'static str>, + sub_options: HashMap<&'static str, SubOption>, + help_text: &'static str, + _phantom: std::marker::PhantomData, +} + +pub struct NoParam; +pub struct WithParam; +pub struct WithOptionalParam; + +enum SubOptionHandler { + /// Handler without value parameter (exact match) + NoValue(fn(&mut Args, &mut Vec) -> Result<()>), + /// Handler with value parameter (prefix match) + WithValue(fn(&mut Args, &mut Vec, &str) -> Result<()>), +} + +impl Clone for SubOptionHandler { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOptionHandler {} + +struct SubOption { + help: &'static str, + handler: SubOptionHandler, +} + +impl Clone for SubOption { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for SubOption {} + +impl SubOption { + fn with_value(&self) -> bool { + matches!(self.handler, SubOptionHandler::WithValue(_)) + } +} + +impl Default for ArgumentParser { + fn default() -> Self { + Self::new() + } +} + +impl ArgumentParser { + #[must_use] + pub fn new() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: false, + has_option_prefix: |arg| arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix("--").or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find('='), + } + } + + #[must_use] + pub fn new_case_insensitive() -> Self { + Self { + options: HashMap::new(), + short_options: HashMap::new(), + prefix_options: HashMap::new(), + case_insensitive: true, + has_option_prefix: |arg| arg.starts_with('/') || arg.starts_with('-'), + strip_option: |arg| arg.strip_prefix('/').or(arg.strip_prefix('-')), + find_separator: |stripped| stripped.find(':'), + } + } + + pub fn declare(&mut self) -> OptionDeclaration<'_, T, NoParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_param(&mut self) -> OptionDeclaration<'_, T, WithParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + pub fn declare_with_optional_param(&mut self) -> OptionDeclaration<'_, T, WithOptionalParam> { + OptionDeclaration { + parser: self, + long_names: Vec::new(), + short_names: Vec::new(), + prefixes: Vec::new(), + sub_options: HashMap::new(), + help_text: "", + _phantom: std::marker::PhantomData, + } + } + + fn get_option_handler(&self, option_name: &str) -> Option<&OptionHandler> { + if self.case_insensitive { + if let Some(handler) = self.options.get(option_name) { + return Some(handler); + } + for (key, handler) in &self.options { + if key.eq_ignore_ascii_case(option_name) { + return Some(handler); + } + } + None + } else { + self.options.get(option_name) + } + } + + pub(crate) fn handle_argument, I: Iterator>( + &self, + args: &mut Args, + modifier_stack: &mut Vec, + arg: &str, + input: &mut I, + ) -> Result<()> { + // TODO @lapla-cogito standardize the interface. @file doesn't use a leading hyphen. + // Handle `@file`option (recursively) - merging in the options contained in the file + if let Some(path) = arg.strip_prefix('@') { + let file_args = read_args_from_file(Path::new(path))?; + let mut file_arg_iter = file_args.iter(); + while let Some(file_arg) = file_arg_iter.next() { + self.handle_argument(args, modifier_stack, file_arg, &mut file_arg_iter)?; + } + return Ok(()); + } + + if let Some(stripped) = (self.strip_option)(arg) { + // Check for option with separator syntax + if let Some(eq_pos) = (self.find_separator)(stripped) { + let option_name = &stripped[..eq_pos]; + let value = &stripped[eq_pos + 1..]; + + if let Some(handler) = self.get_option_handler(option_name) { + match &handler.handler { + OptionHandlerFn::WithParam(f) => f(args, modifier_stack, value)?, + OptionHandlerFn::OptionalParam(f) => f(args, modifier_stack, Some(value))?, + OptionHandlerFn::NoParam(_) => return Ok(()), + } + return Ok(()); + } + } else { + if stripped == "build-id" + && let Some(handler) = self.get_option_handler(stripped) + && let OptionHandlerFn::WithParam(f) = &handler.handler + { + f(args, modifier_stack, "fast")?; + return Ok(()); + } + + if let Some(handler) = self.get_option_handler(stripped) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + } + + if arg.starts_with('-') && !arg.starts_with("--") && arg.len() > 1 { + let option_name = &arg[1..]; + if let Some(handler) = self.short_options.get(option_name) { + match &handler.handler { + OptionHandlerFn::NoParam(f) => f(args, modifier_stack)?, + OptionHandlerFn::WithParam(f) => { + let next_arg = + input.next().context(format!("Missing argument to {arg}"))?; + f(args, modifier_stack, next_arg.as_ref())?; + } + OptionHandlerFn::OptionalParam(f) => { + f(args, modifier_stack, None)?; + } + } + return Ok(()); + } + } + + // Prefix options. These should be handled after processing long and short options, + // because some options (like `-hashstyle=gnu`) can be misinterpreted as prefix options. + for (prefix, handler) in &self.prefix_options { + if let Some(rest) = arg.strip_prefix(&format!("-{prefix}")) { + let value = if rest.is_empty() { + let next_arg = input + .next() + .context(format!("Missing argument to -{prefix}"))?; + next_arg.as_ref().to_owned() + } else { + rest.to_owned() + }; + + if let Some((key, param_value)) = value.split_once('=') { + // Value has '=', look up key with trailing '=' + if let Some(sub) = handler.sub_options.get(format!("{key}=").as_str()) { + match sub.handler { + SubOptionHandler::NoValue(_) => { + (handler.handler)(args, modifier_stack, &value)?; + } + SubOptionHandler::WithValue(f) => f(args, modifier_stack, param_value)?, + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } else { + // No '=' in value, look up exact match + if let Some(sub) = handler.sub_options.get(value.as_str()) { + match sub.handler { + SubOptionHandler::NoValue(f) => f(args, modifier_stack)?, + SubOptionHandler::WithValue(_) => { + bail!("Option -{prefix} {value} requires a value"); + } + } + } else { + // Fall back to the main handler + (handler.handler)(args, modifier_stack, &value)?; + } + } + return Ok(()); + } + } + + if (self.has_option_prefix)(arg) { + if let Some(stripped) = (self.strip_option)(arg) + && IGNORED_FLAGS.contains(&stripped) + { + warn_unsupported(arg)?; + return Ok(()); + } + + args.unrecognized_options.push(arg.to_owned()); + return Ok(()); + } + + args.save_dir.handle_file(arg); + args.inputs.push(Input { + spec: InputSpec::File(Box::from(Path::new(arg))), + search_first: None, + modifiers: *modifier_stack.last().unwrap(), + }); + + Ok(()) + } + + #[must_use] + fn generate_help(&self) -> String { + let mut help = String::new(); + help.push_str("USAGE:\n wild [OPTIONS] [FILES...]\n\nOPTIONS:\n"); + + let mut prefix_options: Vec<_> = self.prefix_options.iter().collect(); + prefix_options.sort_by_key(|(prefix, _)| *prefix); + + // TODO: This is ad-hoc + help.push_str(&format!( + " {:<31} Read options from a file\n", + format!("@"), + )); + + let mut help_to_options: HashMap<&str, Vec> = HashMap::new(); + let mut processed_short_options: HashSet<&str> = HashSet::new(); + + // Collect all long options and their associated short options + for (long_name, handler) in &self.options { + if !handler.help_text.is_empty() { + let long_suffix = handler.handler.help_suffix_long(); + let mut option_names = vec![format!("--{long_name}{long_suffix}")]; + + // Add associated short options + let short_suffix = handler.handler.help_suffix_short(); + for short_char in &handler.short_names { + option_names.push(format!("-{short_char}{short_suffix}")); + } + + help_to_options + .entry(handler.help_text) + .or_default() + .extend(option_names); + } + + // Mark short options of help-less handlers as processed + for short_name in &handler.short_names { + processed_short_options.insert(short_name); + } + } + + for (prefix, handler) in prefix_options { + if !processed_short_options.contains(prefix) && !handler.help_text.is_empty() { + help.push_str(&format!( + " -{:<30} {}\n", + format!("{prefix} "), + handler.help_text + )); + + // Add sub-options if they exist + let mut sub_options: Vec<_> = handler.sub_options.iter().collect(); + sub_options.sort_by_key(|(name, _)| *name); + + for (sub_name, sub) in sub_options { + let display_name = if sub.with_value() && sub_name.ends_with('=') { + // sub_name ends with '=' (e.g., "max-page-size="), so add + format!("{sub_name}") + } else { + sub_name.to_string() + }; + help.push_str(&format!( + " -{prefix} {display_name:<30} {sub_help}\n", + sub_help = sub.help + )); + } + } + } + + // Add short-only options + for (short_char, handler) in &self.short_options { + if !processed_short_options.contains(short_char) && !handler.help_text.is_empty() { + let short_suffix = handler.handler.help_suffix_short(); + help_to_options + .entry(handler.help_text) + .or_default() + .push(format!("-{short_char}{short_suffix}")); + } + } + + let mut sorted_help_groups: Vec<_> = help_to_options.into_iter().collect(); + sorted_help_groups.sort_by_key(|(_, option_names)| { + option_names.iter().min().unwrap_or(&String::new()).clone() + }); + + for (help_text, mut option_names) in sorted_help_groups { + option_names.sort_by(|a, b| { + let a_is_short = a.len() == 2 && a.starts_with('-'); + let b_is_short = b.len() == 2 && b.starts_with('-'); + match (a_is_short, b_is_short) { + (true, false) => std::cmp::Ordering::Less, // short options first + (false, true) => std::cmp::Ordering::Greater, // long options after + _ => a.cmp(b), // same type, alphabetical + } + }); + + let option_names_str = option_names.join(", "); + help.push_str(&format!(" {option_names_str:<30} {help_text}\n")); + } + + help + } +} + +impl<'a, T, S> OptionDeclaration<'a, T, S> { + #[must_use] + pub fn long(mut self, name: &'static str) -> Self { + self.long_names.push(name); + self + } + + #[must_use] + pub fn short(mut self, option: &'static str) -> Self { + self.short_names.push(option); + self + } + + #[must_use] + pub fn help(mut self, text: &'static str) -> Self { + self.help_text = text; + self + } + + pub fn prefix(mut self, prefix: &'static str) -> Self { + self.prefixes.push(prefix); + self + } + + #[must_use] + pub fn sub_option( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::NoValue(handler), + }, + ); + self + } + + #[must_use] + pub fn sub_option_with_value( + mut self, + name: &'static str, + help: &'static str, + handler: fn(&mut Args, &mut Vec, &str) -> Result<()>, + ) -> Self { + self.sub_options.insert( + name, + SubOption { + help, + handler: SubOptionHandler::WithValue(handler), + }, + ); + self + } +} + +impl<'a, T> OptionDeclaration<'a, T, NoParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec) -> Result<()>) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::NoParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithParam> { + pub fn execute(self, handler: fn(&mut Args, &mut Vec, &str) -> Result<()>) { + let mut short_names = self.short_names.clone(); + short_names.extend_from_slice(&self.prefixes); + + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::WithParam(handler), + short_names, + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + + for prefix in self.prefixes { + let prefix_handler = PrefixOptionHandler { + help_text: self.help_text, + sub_options: self.sub_options.clone(), + handler, + }; + + self.parser.prefix_options.insert(prefix, prefix_handler); + } + } +} + +impl<'a, T> OptionDeclaration<'a, T, WithOptionalParam> { + pub fn execute( + self, + handler: fn(&mut Args, &mut Vec, Option<&str>) -> Result<()>, + ) { + let option_handler = OptionHandler { + help_text: self.help_text, + handler: OptionHandlerFn::OptionalParam(handler), + short_names: self.short_names.clone(), + }; + + for name in self.long_names { + self.parser.options.insert(name, option_handler.clone()); + } + + for option in self.short_names { + self.parser + .short_options + .insert(option, option_handler.clone()); + } + } +} + +// ── End argument parser infrastructure ─────────────────────────────────────── + +pub(crate) fn add_silently_ignored_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in SILENTLY_IGNORED_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in SILENTLY_IGNORED_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +pub(crate) fn add_default_flags(parser: &mut ArgumentParser) { + fn noop(_args: &mut Args, _modifier_stack: &mut Vec) -> Result<()> { + Ok(()) + } + for flag in DEFAULT_FLAGS { + parser.declare().long(flag).execute(noop); + } + for flag in DEFAULT_SHORT_FLAGS { + parser.declare().short(flag).execute(noop); + } +} + +pub(crate) fn read_args_from_file(path: &Path) -> Result> { + let contents = std::fs::read_to_string(path) + .with_context(|| format!("Failed to read arguments from file `{}`", path.display()))?; + arguments_from_string(&contents) +} + +/// Parses arguments from a string, handling quoting, escapes etc. +/// All arguments must be surrounded by a white space. +pub(crate) fn arguments_from_string(input: &str) -> Result> { + const QUOTES: [char; 2] = ['\'', '"']; + + let mut out = Vec::new(); + let mut chars = input.chars(); + let mut heap = None; + let mut quote = None; + let mut expect_whitespace = false; + + loop { + let Some(mut ch) = chars.next() else { + if let Some(quote) = quote.take() { + bail!("Missing closing '{quote}'"); + } + if let Some(arg) = heap.take() { + out.push(arg); + } + break; + }; + + crate::ensure!( + !expect_whitespace || ch.is_whitespace(), + "Expected white space after quoted argument" + ); + expect_whitespace = false; + + if QUOTES.contains(&ch) { + if let Some(qchr) = quote { + if qchr == ch { + // close the argument + if let Some(arg) = heap.take() { + out.push(arg); + } + quote = None; + expect_whitespace = true; + } else { + // accept the other quoting character as normal char + heap.get_or_insert(String::new()).push(ch); + } + } else { + // beginning of a new argument + crate::ensure!(heap.is_none(), "Missing opening quote '{ch}'"); + quote = Some(ch); + } + } else if ch.is_whitespace() { + if quote.is_none() { + if let Some(arg) = heap.take() { + out.push(arg); + } + } else { + heap.get_or_insert(String::new()).push(ch); + } + } else { + if ch == '\\' && (quote.is_some() || !cfg!(target_os = "windows")) { + ch = chars.next().context("Invalid escape")?; + } + heap.get_or_insert(String::new()).push(ch); + } + } + + Ok(out) +} + +pub(super) fn warn_unsupported(opt: &str) -> Result { + match std::env::var(WILD_UNSUPPORTED_ENV) + .unwrap_or_default() + .as_str() + { + "warn" | "" => crate::error::warning(&format!("{opt} is not yet supported")), + "ignore" => {} + "error" => bail!("{opt} is not yet supported"), + other => bail!("Unsupported value for {WILD_UNSUPPORTED_ENV}={other}"), + } + Ok(()) +} + +/// The output binary format. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum OutputFormat { + Elf, + Pe, +} + +impl Default for OutputFormat { + fn default() -> Self { + match Os::DEFAULT { + Os::Linux => OutputFormat::Elf, + Os::Windows => OutputFormat::Pe, + Os::MacOS => todo!("macOS linking not yet supported"), + } + } +} + +/// Result of pre-scanning args for target-determining flags. +#[derive(Debug)] +pub(crate) struct DetectedTarget { + pub format: OutputFormat, + /// Architecture from `--target` triple. `None` if no `--target` was given. + pub arch: Option, +} + +/// Known `-m` emulation values that imply ELF output. +const ELF_EMULATIONS: &[&str] = &[ + "elf_x86_64", + "elf_x86_64_sol2", + "aarch64elf", + "aarch64linux", + "elf64lriscv", + "elf64loongarch", +]; + +/// Map `target_lexicon::Architecture` to Wild's `Architecture`. +fn map_triple_arch(arch: target_lexicon::Architecture) -> Result { + use target_lexicon::Architecture as TL; + match arch { + TL::X86_64 | TL::X86_64h => Ok(Architecture::X86_64), + TL::Aarch64(_) => Ok(Architecture::AArch64), + TL::Riscv64(_) => Ok(Architecture::RISCV64), + TL::LoongArch64 => Ok(Architecture::LoongArch64), + other => bail!("unsupported architecture in target triple: {other}"), + } +} + +/// Map `target_lexicon::BinaryFormat` to `OutputFormat`. +fn map_binary_format(fmt: target_lexicon::BinaryFormat) -> Result { + match fmt { + target_lexicon::BinaryFormat::Elf => Ok(OutputFormat::Elf), + target_lexicon::BinaryFormat::Coff => Ok(OutputFormat::Pe), + other => bail!("unsupported binary format: {other}"), + } +} + +/// Extract the target triple value from a flag, handling all prefix styles. +/// Returns `(Some(value), consumed_next)` if the arg is a target flag. +fn extract_target_value<'a>(arg: &'a str, next_arg: Option<&'a str>) -> (Option<&'a str>, bool) { + // Combined forms: --target=VAL, -target=VAL, /TARGET:VAL + if let Some(val) = arg + .strip_prefix("--target=") + .or_else(|| arg.strip_prefix("-target=")) + .or_else(|| arg.strip_prefix("/TARGET:")) + .or_else(|| arg.strip_prefix("/target:")) + { + return (Some(val), false); + } + // Space-separated: --target VAL, -target VAL, /TARGET VAL + if matches!(arg, "--target" | "-target" | "/TARGET" | "/target") { + if let Some(val) = next_arg { + return (Some(val), true); + } + } + (None, false) +} + +/// Pre-scan CLI arguments to determine the output format and architecture. +/// +/// Recognizes: +/// - `--target=` / `-target=` / `/TARGET:` — primary (parsed by target-lexicon) +/// - `-m ` — overrides format to ELF when present +/// +/// Priority: `-m` overrides format from `--target`. Architecture comes from `--target` only. +pub(crate) fn detect_target(args: &[String]) -> Result { + let mut from_triple: Option<(OutputFormat, Architecture)> = None; + let mut m_implies_elf = false; + + let mut i = 0; + while i < args.len() { + let next = if i + 1 < args.len() { + Some(args[i + 1].as_str()) + } else { + None + }; + let (target_val, consumed_next) = extract_target_value(&args[i], next); + + if let Some(val) = target_val { + let triple: Triple = val + .parse() + .map_err(|e| anyhow::anyhow!("invalid target triple '{val}': {e}"))?; + let format = map_binary_format(triple.binary_format)?; + let arch = map_triple_arch(triple.architecture)?; + from_triple = Some((format, arch)); + if consumed_next { + i += 1; + } + } + // Check for -m (implies ELF) + else if args[i] == "-m" || args[i] == "--m" { + if let Some(next_val) = next { + if ELF_EMULATIONS.contains(&next_val) { + m_implies_elf = true; + } + i += 1; + } + } else if let Some(emu) = args[i].strip_prefix("-m") { + if ELF_EMULATIONS.contains(&emu) { + m_implies_elf = true; + } + } + + i += 1; + } + + match (from_triple, m_implies_elf) { + (Some((_, arch)), true) => { + // -m overrides format to ELF; arch from triple preserved + Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: Some(arch), + }) + } + (Some((format, arch)), false) => Ok(DetectedTarget { + format, + arch: Some(arch), + }), + (None, true) => Ok(DetectedTarget { + format: OutputFormat::Elf, + arch: None, + }), + (None, false) => Ok(DetectedTarget { + format: OutputFormat::default(), + arch: None, + }), + } +} + +/// Map Wild `Architecture` to the GNU ld `-m` emulation name. +fn arch_to_elf_emulation(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "elf_x86_64", + Architecture::AArch64 => "aarch64linux", + Architecture::RISCV64 => "elf64lriscv", + Architecture::LoongArch64 => "elf64loongarch", + } +} + +/// Map Wild `Architecture` to the MSVC `/MACHINE:` value. +fn arch_to_machine_value(arch: Architecture) -> &'static str { + match arch { + Architecture::X86_64 => "X64", + Architecture::AArch64 => "ARM64", + Architecture::RISCV64 => "X64", + Architecture::LoongArch64 => "X64", + } +} + +/// Strip `--target`/`-target`/`/TARGET` flags and inject a synthetic `-m` or `/MACHINE:` flag +/// from the detected architecture so the format-specific parser picks it up. +/// +/// The user's explicit `-m` or `/MACHINE:` flags are preserved and will override the injected one +/// since they appear later in the argument list. +pub(crate) fn filter_and_inject_target_flags( + args: &[String], + format: OutputFormat, + arch: Option, +) -> Vec { + let mut result = Vec::with_capacity(args.len() + 2); + + // Inject synthetic arch flag at the front (user's explicit flags override later) + if let Some(arch) = arch { + match format { + OutputFormat::Elf => { + result.push("-m".to_string()); + result.push(arch_to_elf_emulation(arch).to_string()); + } + OutputFormat::Pe => { + result.push(format!("/MACHINE:{}", arch_to_machine_value(arch))); + } + } + } + + // Strip --target flags, keep everything else + let mut i = 0; + while i < args.len() { + let arg = &args[i]; + if arg.starts_with("--target=") + || arg.starts_with("-target=") + || arg.starts_with("/TARGET:") + || arg.starts_with("/target:") + { + // Skip this combined arg + } else if matches!(arg.as_str(), "--target" | "-target" | "/TARGET" | "/target") { + i += 1; // skip value too + } else { + result.push(arg.clone()); + } + i += 1; + } + result +} + +/// Format-specific parsed arguments. +pub enum TargetArgs { + Elf(linux::ElfArgs), + #[allow(dead_code)] + Pe(windows::PeArgs), +} + +impl std::fmt::Debug for TargetArgs { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TargetArgs::Elf(e) => e.fmt(f), + TargetArgs::Pe(p) => p.fmt(f), + } + } +} + +/// Parsed linker arguments. Common fields are directly accessible. +/// Format-specific fields are accessible via `Deref`/`DerefMut` through `target_args`. +/// +/// `T` defaults to `TargetArgs` (the enum). During parsing, `T` is set to the +/// concrete format type (e.g. `ElfArgs` or `PeArgs`). +#[derive(Debug)] +pub struct Args { + // ── Infrastructure ─────────────────────────────────────────────────────── + pub should_fork: bool, + pub(crate) output: Arc, + pub(crate) arch: Architecture, + pub(crate) inputs: Vec, + pub(crate) lib_search_path: Vec>, + pub num_threads: Option, + pub(crate) available_threads: NonZeroUsize, + pub(crate) save_dir: SaveDir, + pub(crate) unrecognized_options: Vec, + pub(crate) files_per_group: Option, + pub(crate) write_layout: bool, + pub(crate) write_trace: bool, + pub(crate) jobserver_client: Option, + + // ── Core linker behavior ───────────────────────────────────────────────── + pub(crate) strip: Strip, + pub(crate) gc_sections: bool, + pub(crate) merge_sections: bool, + pub(crate) relax: bool, + pub(crate) demangle: bool, + pub(crate) no_undefined: bool, + pub(crate) allow_shlib_undefined: bool, + pub(crate) error_unresolved_symbols: bool, + pub(crate) allow_multiple_definitions: bool, + pub(crate) unresolved_symbols: UnresolvedSymbols, + pub(crate) undefined: Vec, + pub(crate) copy_relocations: CopyRelocations, + pub(crate) sysroot: Option>, + pub(crate) dynamic_linker: Option>, + pub(crate) entry: Option, + pub(crate) wrap: Vec, + pub(crate) exclude_libs: ExcludeLibs, + pub(crate) b_symbolic: BSymbolicKind, + pub(crate) export_list: Vec, + pub(crate) defsym: Vec<(String, DefsymValue)>, + pub(crate) section_start: HashMap, + pub(crate) max_page_size: Option, + pub(crate) execstack: bool, + pub(crate) version_mode: VersionMode, + pub(crate) relocation_model: RelocationModel, + pub(crate) should_output_executable: bool, + pub(crate) export_all_dynamic_symbols: bool, + pub(crate) version_script_path: Option, + pub(crate) export_list_path: Option, + + // ── Output/writing ─────────────────────────────────────────────────────── + pub(crate) mmap_output_file: bool, + pub(crate) file_write_mode: Option, + pub(crate) prepopulate_maps: bool, + pub(crate) should_write_linker_identity: bool, + + // ── Debug/diagnostic ───────────────────────────────────────────────────── + pub(crate) debug_fuel: Option, + pub(crate) validate_output: bool, + pub(crate) sym_info: Option, + pub(crate) debug_address: Option, + pub(crate) print_allocations: Option, + pub(crate) verify_allocation_consistency: bool, + pub(crate) time_phase_options: Option>, + pub(crate) numeric_experiments: Vec>, + pub(crate) write_gc_stats: Option, + pub(crate) gc_stats_ignore: Vec, + pub(crate) verbose_gc_stats: bool, + pub(crate) dependency_file: Option, + + // ── Format-specific ────────────────────────────────────────────────────── + pub target_args: T, +} + +impl Default for Args { + fn default() -> Self { + Args { + // Infrastructure + should_fork: true, + arch: Architecture::DEFAULT, + unrecognized_options: Vec::new(), + lib_search_path: Vec::new(), + inputs: Vec::new(), + output: Arc::from(Path::new("a.out")), + num_threads: None, + write_layout: std::env::var(WRITE_LAYOUT_ENV).is_ok_and(|v| v == "1"), + write_trace: std::env::var(WRITE_TRACE_ENV).is_ok_and(|v| v == "1"), + files_per_group: None, + save_dir: Default::default(), + jobserver_client: None, + available_threads: NonZeroUsize::new(1).unwrap(), + // Core linker behavior + strip: Strip::Nothing, + gc_sections: true, + merge_sections: true, + relax: true, + demangle: true, + no_undefined: false, + allow_shlib_undefined: false, + error_unresolved_symbols: true, + allow_multiple_definitions: false, + unresolved_symbols: UnresolvedSymbols::ReportAll, + undefined: Vec::new(), + copy_relocations: CopyRelocations::Allowed, + sysroot: None, + dynamic_linker: None, + entry: None, + wrap: Vec::new(), + exclude_libs: ExcludeLibs::None, + b_symbolic: BSymbolicKind::None, + export_list: Vec::new(), + defsym: Vec::new(), + section_start: HashMap::new(), + max_page_size: None, + execstack: false, + version_mode: VersionMode::None, + relocation_model: RelocationModel::NonRelocatable, + should_output_executable: true, + export_all_dynamic_symbols: false, + version_script_path: None, + export_list_path: None, + // Output/writing + mmap_output_file: true, + file_write_mode: None, + prepopulate_maps: false, + should_write_linker_identity: true, + // Debug/diagnostic + debug_fuel: None, + validate_output: std::env::var(VALIDATE_ENV).is_ok_and(|v| v == "1"), + sym_info: None, + debug_address: None, + print_allocations: std::env::var("WILD_PRINT_ALLOCATIONS") + .ok() + .and_then(|s| s.parse().ok()) + .map(FileId::from_encoded), + verify_allocation_consistency: std::env::var(WRITE_VERIFY_ALLOCATIONS_ENV) + .is_ok_and(|v| v == "1"), + time_phase_options: None, + numeric_experiments: Vec::new(), + write_gc_stats: None, + gc_stats_ignore: Vec::new(), + verbose_gc_stats: false, + dependency_file: None, + // Format-specific + target_args: T::default(), + } + } +} + +impl std::ops::Deref for Args { + type Target = T; + fn deref(&self) -> &T { + &self.target_args + } +} + +impl std::ops::DerefMut for Args { + fn deref_mut(&mut self) -> &mut T { + &mut self.target_args + } +} + +impl Args { + /// Transform the target-specific part while preserving common fields. + pub fn map_target(self, f: impl FnOnce(T) -> U) -> Args { + Args { + // Infrastructure + should_fork: self.should_fork, + output: self.output, + arch: self.arch, + inputs: self.inputs, + lib_search_path: self.lib_search_path, + num_threads: self.num_threads, + available_threads: self.available_threads, + save_dir: self.save_dir, + unrecognized_options: self.unrecognized_options, + files_per_group: self.files_per_group, + write_layout: self.write_layout, + write_trace: self.write_trace, + jobserver_client: self.jobserver_client, + // Core linker behavior + strip: self.strip, + gc_sections: self.gc_sections, + merge_sections: self.merge_sections, + relax: self.relax, + demangle: self.demangle, + no_undefined: self.no_undefined, + allow_shlib_undefined: self.allow_shlib_undefined, + error_unresolved_symbols: self.error_unresolved_symbols, + allow_multiple_definitions: self.allow_multiple_definitions, + unresolved_symbols: self.unresolved_symbols, + undefined: self.undefined, + copy_relocations: self.copy_relocations, + sysroot: self.sysroot, + dynamic_linker: self.dynamic_linker, + entry: self.entry, + wrap: self.wrap, + exclude_libs: self.exclude_libs, + b_symbolic: self.b_symbolic, + export_list: self.export_list, + defsym: self.defsym, + section_start: self.section_start, + max_page_size: self.max_page_size, + execstack: self.execstack, + version_mode: self.version_mode, + relocation_model: self.relocation_model, + should_output_executable: self.should_output_executable, + export_all_dynamic_symbols: self.export_all_dynamic_symbols, + version_script_path: self.version_script_path, + export_list_path: self.export_list_path, + // Output/writing + mmap_output_file: self.mmap_output_file, + file_write_mode: self.file_write_mode, + prepopulate_maps: self.prepopulate_maps, + should_write_linker_identity: self.should_write_linker_identity, + // Debug/diagnostic + debug_fuel: self.debug_fuel, + validate_output: self.validate_output, + sym_info: self.sym_info, + debug_address: self.debug_address, + print_allocations: self.print_allocations, + verify_allocation_consistency: self.verify_allocation_consistency, + time_phase_options: self.time_phase_options, + numeric_experiments: self.numeric_experiments, + write_gc_stats: self.write_gc_stats, + gc_stats_ignore: self.gc_stats_ignore, + verbose_gc_stats: self.verbose_gc_stats, + dependency_file: self.dependency_file, + // Format-specific + target_args: f(self.target_args), + } + } + + pub fn map_ref_target(&self, f: impl FnOnce(&T) -> U) -> U { + f(&self.target_args) + } + + /// Uses 1 debug fuel, returning how much fuel remains. Debug fuel is intended to be used when + /// debugging certain kinds of bugs, so this function isn't normally referenced. To use it, the + /// caller should take a different branch depending on whether the value is still positive. You + /// can then do a binary search. + pub(crate) fn use_debug_fuel(&self) -> i64 { + let Some(fuel) = self.debug_fuel.as_ref() else { + return i64::MAX; + }; + fuel.fetch_sub(1, std::sync::atomic::Ordering::AcqRel) - 1 + } + + /// Returns whether there was sufficient fuel. If the last bit of fuel was used, then calls + /// `last_cb`. + #[allow(unused)] + pub(crate) fn use_debug_fuel_on_last(&self, last_cb: impl FnOnce()) -> bool { + match self.use_debug_fuel() { + 1.. => true, + 0 => { + last_cb(); + true + } + _ => false, + } + } + + pub(crate) fn trace_span_for_file( + &self, + file_id: FileId, + ) -> Option { + let should_trace = self.print_allocations == Some(file_id); + should_trace.then(|| tracing::trace_span!(crate::debug_trace::TRACE_SPAN_NAME).entered()) + } + + pub fn should_fork(&self) -> bool { + self.should_fork + } + + pub(crate) fn numeric_experiment(&self, exp: Experiment, default: u64) -> u64 { + self.numeric_experiments + .get(exp as usize) + .copied() + .flatten() + .unwrap_or(default) + } + + pub(crate) fn loadable_segment_alignment(&self) -> Alignment { + if let Some(max_page_size) = self.max_page_size { + return max_page_size; + } + + match self.arch { + Architecture::X86_64 => Alignment { exponent: 12 }, + Architecture::AArch64 => Alignment { exponent: 16 }, + Architecture::RISCV64 => Alignment { exponent: 12 }, + Architecture::LoongArch64 => Alignment { exponent: 16 }, + } + } + + pub(crate) fn strip_all(&self) -> bool { + matches!(self.strip, Strip::All) + } + + pub(crate) fn strip_debug(&self) -> bool { + matches!(self.strip, Strip::All | Strip::Debug) + } +} + +/// Linker args with an activated thread pool. Holds jobserver tokens for the +/// duration of the link to keep the threads available. +pub struct ActivatedArgs { + pub args: Args, + _jobserver_tokens: Vec, +} + +impl ActivatedArgs { + pub fn map_target(self, f: impl FnOnce(T) -> U) -> ActivatedArgs { + ActivatedArgs { + args: self.args.map_target(f), + _jobserver_tokens: self._jobserver_tokens, + } + } +} + +impl Args { + /// Sets up the thread pool, using the explicit number of threads if specified, + /// or falling back to the jobserver protocol if available. + /// + /// + pub fn activate_thread_pool(mut self) -> Result> { + crate::timing_phase!("Activate thread pool"); + + let mut tokens = Vec::new(); + self.available_threads = self.num_threads.unwrap_or_else(|| { + if let Some(client) = &self.jobserver_client { + while let Ok(Some(acquired)) = client.try_acquire() { + tokens.push(acquired); + } + tracing::trace!(count = tokens.len(), "Acquired jobserver tokens"); + // Our parent "holds" one jobserver token, add it. + NonZeroUsize::new((tokens.len() + 1).max(1)).unwrap() + } else { + std::thread::available_parallelism().unwrap_or(NonZeroUsize::new(1).unwrap()) + } + }); + + // The pool might be already initialized, suppress the error intentionally. + let _ = rayon::ThreadPoolBuilder::new() + .num_threads(self.available_threads.get()) + .build_global(); + + Ok(ActivatedArgs { + args: self, + _jobserver_tokens: tokens, + }) + } +} + +impl Args { + /// Parse CLI arguments. Detects target format from `--target=`, `-m`, + /// or host default, then routes to the format-specific parser. + pub fn parse I, S: AsRef, I: Iterator>(input: F) -> Result { + let all_args: Vec = input().map(|s| s.as_ref().to_owned()).collect(); + let detected = detect_target(&all_args)?; + let filtered = filter_and_inject_target_flags(&all_args, detected.format, detected.arch); + + match detected.format { + OutputFormat::Elf => { + let elf_args = linux::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(elf_args.map_target(TargetArgs::Elf)) + } + OutputFormat::Pe => { + let pe_args = windows::parse(|| filtered.iter().map(|s| s.as_str()))?; + Ok(pe_args.map_target(TargetArgs::Pe)) + } + } + } +} + +/// Top-level parse function. +pub fn parse I, S: AsRef, I: Iterator>( + input: F, +) -> Result> { + Args::parse(input) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn to_strings(args: &[&str]) -> Vec { + args.iter().map(|s| s.to_string()).collect() + } + + // ---- detect_target tests ---- + + #[test] + fn test_detect_format_from_triple_linux_x86() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_triple_windows() { + let args = to_strings(&["-target=x86_64-pc-windows-msvc", "/OUT:foo.exe"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::X86_64)); + } + + #[test] + fn test_detect_format_from_slash_target() { + let args = to_strings(&["/TARGET:aarch64-pc-windows-msvc", "foo.obj"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Pe); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_space_separated() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::AArch64)); + } + + #[test] + fn test_detect_format_from_m_flag() { + let args = to_strings(&["-m", "elf_x86_64", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, None); + } + + #[test] + fn test_m_flag_overrides_target_format() { + let args = to_strings(&["--target=x86_64-pc-windows-msvc", "-m", "elf_x86_64"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + } + + #[test] + fn test_detect_format_default_no_flags() { + let args = to_strings(&["-o", "out", "foo.o"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::default()); + assert_eq!(result.arch, None); + } + + #[test] + fn test_detect_format_riscv_triple() { + let args = to_strings(&["--target=riscv64gc-unknown-linux-gnu", "-o", "out"]); + let result = detect_target(&args).unwrap(); + assert_eq!(result.format, OutputFormat::Elf); + assert_eq!(result.arch, Some(Architecture::RISCV64)); + } + + // ---- filter_and_inject_target_flags tests ---- + + #[test] + fn test_filter_strips_target_equals() { + let args = to_strings(&["--target=x86_64-unknown-linux-gnu", "-o", "out", "foo.o"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert_eq!(filtered[2], "-o"); + assert!(!filtered.iter().any(|a| a.contains("--target"))); + } + + #[test] + fn test_filter_strips_target_space() { + let args = to_strings(&["--target", "aarch64-unknown-linux-gnu", "-o", "out"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::AArch64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "aarch64linux"); + assert!( + !filtered + .iter() + .any(|a| a == "--target" || a.contains("linux-gnu")) + ); + } + + #[test] + fn test_filter_strips_slash_target() { + let args = to_strings(&["/TARGET:x86_64-pc-windows-msvc", "/OUT:foo.exe", "bar.obj"]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Pe, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "/MACHINE:X64"); + assert_eq!(filtered[1], "/OUT:foo.exe"); + } + + #[test] + fn test_filter_preserves_m_flag() { + let args = to_strings(&[ + "--target=x86_64-unknown-linux-gnu", + "-m", + "aarch64linux", + "-o", + "out", + ]); + let filtered = + filter_and_inject_target_flags(&args, OutputFormat::Elf, Some(Architecture::X86_64)); + assert_eq!(filtered[0], "-m"); + assert_eq!(filtered[1], "elf_x86_64"); + assert!(filtered.contains(&"-m".to_string())); + assert!(filtered.contains(&"aarch64linux".to_string())); + } + + #[test] + fn test_filter_no_target_no_inject() { + let args = to_strings(&["-o", "out", "foo.o"]); + let filtered = filter_and_inject_target_flags(&args, OutputFormat::Elf, None); + assert_eq!(filtered, args); + } +} diff --git a/libwild/src/coff.rs b/libwild/src/coff.rs index c7c559bdc..53ed27402 100644 --- a/libwild/src/coff.rs +++ b/libwild/src/coff.rs @@ -626,7 +626,7 @@ impl platform::NonAddressableIndexes for () { // ── ObjectFile trait implementation ───────────────────────────────────────── impl<'data> platform::ObjectFile<'data> for CoffObjectFile<'data> { - type ArgsType = PeArgs; + type Args = PeArgs; type Symbol = CoffSymbol; type SectionHeader = pe::ImageSectionHeader; type SectionIterator = core::slice::Iter<'data, pe::ImageSectionHeader>; diff --git a/libwild/src/diagnostics.rs b/libwild/src/diagnostics.rs index 4863c2dd3..e443167e8 100644 --- a/libwild/src/diagnostics.rs +++ b/libwild/src/diagnostics.rs @@ -1,275 +1,275 @@ -use crate::Args; -use crate::elf::RawSymbolName; -use crate::grouping::SequencedInput; -use crate::input_data::FileId; -use crate::input_data::PRELUDE_FILE_ID; -use crate::platform::ObjectFile; -use crate::platform::RawSymbolName as _; -use crate::platform::Symbol as _; -use crate::resolution::ResolvedFile; -use crate::resolution::ResolvedGroup; -use crate::symbol::PreHashedSymbolName; -use crate::symbol_db::SymbolDb; -use crate::symbol_db::SymbolId; -use crate::value_flags::AtomicPerSymbolFlags; -use crate::value_flags::FlagsForSymbol as _; -use std::fmt::Write as _; - -/// Prints information about a symbol when dropped. We do this when dropped so that we can print -/// either after resolution flags have been computed, or, if layout gets an error, then before we -/// unwind. -pub(crate) enum SymbolInfoPrinter { - Disabled, - Enabled(Box), -} - -pub(crate) struct State { - loaded_file_ids: hashbrown::HashSet, - name: String, - - /// Our output the last time `update` was called. This is what will be printed when dropped - /// unless `update` is called again. - output: String, -} - -impl Drop for SymbolInfoPrinter { - fn drop(&mut self) { - self.print(); - } -} - -impl SymbolInfoPrinter { - pub(crate) fn new<'data2, O: ObjectFile<'data2>>( - args: &Args, - groups: &[ResolvedGroup<'data2, O>], - ) -> Self { - let Some(name) = args.sym_info.as_ref() else { - return Self::Disabled; - }; - - let loaded_file_ids = groups - .iter() - .flat_map(|group| { - group.files.iter().filter_map(|file| match file { - ResolvedFile::NotLoaded(_) => None, - ResolvedFile::Prelude(_) => Some(PRELUDE_FILE_ID), - ResolvedFile::Object(obj) => Some(obj.common.file_id), - ResolvedFile::Dynamic(obj) => Some(obj.common.file_id), - ResolvedFile::LinkerScript(obj) => Some(obj.file_id), - ResolvedFile::SyntheticSymbols(obj) => Some(obj.file_id), - #[cfg(feature = "plugins")] - ResolvedFile::LtoInput(obj) => Some(obj.file_id), - }) - }) - .collect(); - - Self::Enabled(Box::new(State { - loaded_file_ids, - name: name.to_owned(), - output: "SymbolInfoPrinter::update never called, so can't print symbol info".into(), - })) - } - - pub(crate) fn update<'data, O: ObjectFile<'data>>( - &mut self, - symbol_db: &SymbolDb<'data, O>, - per_symbol_flags: &AtomicPerSymbolFlags<'_>, - ) { - let Self::Enabled(state) = self else { - return; - }; - - let mut out = String::new(); - let name = symbol_db - .find_mangled_name(&state.name) - .unwrap_or_else(|| state.name.clone()); - - let matcher = NameMatcher::new(&name); - let mut target_ids = Vec::new(); - target_ids.extend(name.parse().ok().map(SymbolId::from_usize)); - - let symbol_id = symbol_db.get( - &PreHashedSymbolName::from_raw(&RawSymbolName::parse(name.as_bytes())), - true, - ); - let _ = writeln!(&mut out, "Global name `{name}` refers to: {symbol_id:?}"); - - target_ids.extend(symbol_id); - - let _ = writeln!(&mut out, "Definitions / references with name `{name}`:"); - for i in 0..symbol_db.num_symbols() { - let symbol_id = SymbolId::from_usize(i); - let canonical = symbol_db.definition(symbol_id); - let file_id = symbol_db.file_id_for_symbol(symbol_id); - let flags = per_symbol_flags.flags_for_symbol(symbol_id); - - let file_state = if state.loaded_file_ids.contains(&file_id) { - "LOADED" - } else { - "NOT LOADED" - }; - - let Ok(sym_name) = symbol_db.symbol_name(symbol_id) else { - continue; - }; - - let is_name_match = matcher.matches(sym_name.bytes(), symbol_id, symbol_db); - - let is_id_match = target_ids.contains(&symbol_id); - - if is_name_match || is_id_match { - if symbol_id != canonical { - // Show info about the canonical symbol too. Generally the canonical symbol will - // have the same name, so this won't do anything. Note, this only works if the - // related symbol is later. Fixing that would require restructuring this - // function. - target_ids.push(canonical); - } - - let file = symbol_db.file(file_id); - let local_index = symbol_id.to_input(file.symbol_id_range()); - - let sym_debug; - let input; - - match file { - SequencedInput::Prelude(_) => { - input = " ".to_owned(); - sym_debug = "Prelude symbol".to_owned(); - } - SequencedInput::Object(o) => match o.parsed.object.symbol(local_index) { - Ok(sym) => { - sym_debug = sym.debug_string(); - input = o.parsed.input.to_string(); - } - Err(e) => { - let _ = writeln!( - &mut out, - " Corrupted input (file_id #{file_id}) {}: {}", - o.parsed.input, - e.to_string() - ); - continue; - } - }, - SequencedInput::LinkerScript(s) => { - sym_debug = "Linker script symbol".to_owned(); - input = s.parsed.input.to_string(); - } - SequencedInput::SyntheticSymbols(_) => { - input = " ".to_owned(); - sym_debug = "Synthetic symbol".to_owned(); - } - #[cfg(feature = "plugins")] - SequencedInput::LtoInput(o) => { - input = o.to_string(); - sym_debug = o.symbol_properties_display(symbol_id).to_string(); - } - } - - // Versions can be either literally within the symbol name or in separate version - // tables. It's useful to know which we've got, so if we get a version from a - // separate table, we separate it visually from the rest of the name. - let version_str = symbol_db - .symbol_version_debug(symbol_id) - .map_or_else(String::new, |v| format!(" version `{v}`")); - - let canon = if symbol_id == canonical { - "".to_owned() - } else { - format!(" -> {canonical}") - }; - - let _ = writeln!( - &mut out, - " {symbol_id}{canon}: {sym_debug}: {flags} \ - \n {sym_name}{version_str}\n \ - #{local_index} in File #{file_id} {input} ({file_state})" - ); - } - } - } - - fn print(&self) { - match self { - SymbolInfoPrinter::Disabled => {} - SymbolInfoPrinter::Enabled(state) => { - println!("{}", &state.output); - } - } - } -} - -#[derive(Debug)] -struct NameMatcher { - name: String, - version: VersionMatcher, -} - -#[derive(Debug)] -enum VersionMatcher { - None, - Exact(String), - Any, -} - -impl NameMatcher { - fn new(pattern: &str) -> Self { - if let Some((n, v)) = pattern.split_once('@') { - Self { - name: n.to_owned(), - version: VersionMatcher::new(v), - } - } else { - Self { - name: pattern.to_owned(), - version: VersionMatcher::None, - } - } - } - - fn matches<'data, O: ObjectFile<'data>>( - &self, - name: &[u8], - symbol_id: SymbolId, - symbol_db: &SymbolDb<'data, O>, - ) -> bool { - if let Some(i) = name.iter().position(|b| *b == b'@') { - let (name, version) = name.split_at(i); - return name == self.name.as_bytes() && self.version.matches_at_prefixed(version); - } - - if name != self.name.as_bytes() { - return false; - } - - self.version.matches_at_prefixed( - symbol_db - .symbol_version_debug(symbol_id) - .unwrap_or_default() - .as_bytes(), - ) - } -} - -impl VersionMatcher { - fn new(n: &str) -> Self { - if n == "*" { - VersionMatcher::Any - } else { - VersionMatcher::Exact(n.to_owned()) - } - } - - fn matches_at_prefixed(&self, mut version: &[u8]) -> bool { - let is_default = version.starts_with(b"@@"); - while let Some(rest) = version.strip_prefix(b"@") { - version = rest; - } - match self { - VersionMatcher::Any => true, - VersionMatcher::Exact(v) => version == v.as_bytes(), - VersionMatcher::None => is_default || version.is_empty(), - } - } -} +use crate::Args; +use crate::elf::RawSymbolName; +use crate::grouping::SequencedInput; +use crate::input_data::FileId; +use crate::input_data::PRELUDE_FILE_ID; +use crate::platform::ObjectFile; +use crate::platform::RawSymbolName as _; +use crate::platform::Symbol as _; +use crate::resolution::ResolvedFile; +use crate::resolution::ResolvedGroup; +use crate::symbol::PreHashedSymbolName; +use crate::symbol_db::SymbolDb; +use crate::symbol_db::SymbolId; +use crate::value_flags::AtomicPerSymbolFlags; +use crate::value_flags::FlagsForSymbol as _; +use std::fmt::Write as _; + +/// Prints information about a symbol when dropped. We do this when dropped so that we can print +/// either after resolution flags have been computed, or, if layout gets an error, then before we +/// unwind. +pub(crate) enum SymbolInfoPrinter { + Disabled, + Enabled(Box), +} + +pub(crate) struct State { + loaded_file_ids: hashbrown::HashSet, + name: String, + + /// Our output the last time `update` was called. This is what will be printed when dropped + /// unless `update` is called again. + output: String, +} + +impl Drop for SymbolInfoPrinter { + fn drop(&mut self) { + self.print(); + } +} + +impl SymbolInfoPrinter { + pub(crate) fn new<'data2, O: ObjectFile<'data2>>( + args: &Args, + groups: &[ResolvedGroup<'data2, O>], + ) -> Self { + let Some(name) = args.sym_info.as_ref() else { + return Self::Disabled; + }; + + let loaded_file_ids = groups + .iter() + .flat_map(|group| { + group.files.iter().filter_map(|file| match file { + ResolvedFile::NotLoaded(_) => None, + ResolvedFile::Prelude(_) => Some(PRELUDE_FILE_ID), + ResolvedFile::Object(obj) => Some(obj.common.file_id), + ResolvedFile::Dynamic(obj) => Some(obj.common.file_id), + ResolvedFile::LinkerScript(obj) => Some(obj.file_id), + ResolvedFile::SyntheticSymbols(obj) => Some(obj.file_id), + #[cfg(feature = "plugins")] + ResolvedFile::LtoInput(obj) => Some(obj.file_id), + }) + }) + .collect(); + + Self::Enabled(Box::new(State { + loaded_file_ids, + name: name.to_owned(), + output: "SymbolInfoPrinter::update never called, so can't print symbol info".into(), + })) + } + + pub(crate) fn update<'data, O: ObjectFile<'data>>( + &mut self, + symbol_db: &SymbolDb<'data, O>, + per_symbol_flags: &AtomicPerSymbolFlags<'_>, + ) { + let Self::Enabled(state) = self else { + return; + }; + + let mut out = String::new(); + let name = symbol_db + .find_mangled_name(&state.name) + .unwrap_or_else(|| state.name.clone()); + + let matcher = NameMatcher::new(&name); + let mut target_ids = Vec::new(); + target_ids.extend(name.parse().ok().map(SymbolId::from_usize)); + + let symbol_id = symbol_db.get( + &PreHashedSymbolName::from_raw(&RawSymbolName::parse(name.as_bytes())), + true, + ); + let _ = writeln!(&mut out, "Global name `{name}` refers to: {symbol_id:?}"); + + target_ids.extend(symbol_id); + + let _ = writeln!(&mut out, "Definitions / references with name `{name}`:"); + for i in 0..symbol_db.num_symbols() { + let symbol_id = SymbolId::from_usize(i); + let canonical = symbol_db.definition(symbol_id); + let file_id = symbol_db.file_id_for_symbol(symbol_id); + let flags = per_symbol_flags.flags_for_symbol(symbol_id); + + let file_state = if state.loaded_file_ids.contains(&file_id) { + "LOADED" + } else { + "NOT LOADED" + }; + + let Ok(sym_name) = symbol_db.symbol_name(symbol_id) else { + continue; + }; + + let is_name_match = matcher.matches(sym_name.bytes(), symbol_id, symbol_db); + + let is_id_match = target_ids.contains(&symbol_id); + + if is_name_match || is_id_match { + if symbol_id != canonical { + // Show info about the canonical symbol too. Generally the canonical symbol will + // have the same name, so this won't do anything. Note, this only works if the + // related symbol is later. Fixing that would require restructuring this + // function. + target_ids.push(canonical); + } + + let file = symbol_db.file(file_id); + let local_index = symbol_id.to_input(file.symbol_id_range()); + + let sym_debug; + let input; + + match file { + SequencedInput::Prelude(_) => { + input = " ".to_owned(); + sym_debug = "Prelude symbol".to_owned(); + } + SequencedInput::Object(o) => match o.parsed.object.symbol(local_index) { + Ok(sym) => { + sym_debug = sym.debug_string(); + input = o.parsed.input.to_string(); + } + Err(e) => { + let _ = writeln!( + &mut out, + " Corrupted input (file_id #{file_id}) {}: {}", + o.parsed.input, + e.to_string() + ); + continue; + } + }, + SequencedInput::LinkerScript(s) => { + sym_debug = "Linker script symbol".to_owned(); + input = s.parsed.input.to_string(); + } + SequencedInput::SyntheticSymbols(_) => { + input = " ".to_owned(); + sym_debug = "Synthetic symbol".to_owned(); + } + #[cfg(feature = "plugins")] + SequencedInput::LtoInput(o) => { + input = o.to_string(); + sym_debug = o.symbol_properties_display(symbol_id).to_string(); + } + } + + // Versions can be either literally within the symbol name or in separate version + // tables. It's useful to know which we've got, so if we get a version from a + // separate table, we separate it visually from the rest of the name. + let version_str = symbol_db + .symbol_version_debug(symbol_id) + .map_or_else(String::new, |v| format!(" version `{v}`")); + + let canon = if symbol_id == canonical { + "".to_owned() + } else { + format!(" -> {canonical}") + }; + + let _ = writeln!( + &mut out, + " {symbol_id}{canon}: {sym_debug}: {flags} \ + \n {sym_name}{version_str}\n \ + #{local_index} in File #{file_id} {input} ({file_state})" + ); + } + } + } + + fn print(&self) { + match self { + SymbolInfoPrinter::Disabled => {} + SymbolInfoPrinter::Enabled(state) => { + println!("{}", &state.output); + } + } + } +} + +#[derive(Debug)] +struct NameMatcher { + name: String, + version: VersionMatcher, +} + +#[derive(Debug)] +enum VersionMatcher { + None, + Exact(String), + Any, +} + +impl NameMatcher { + fn new(pattern: &str) -> Self { + if let Some((n, v)) = pattern.split_once('@') { + Self { + name: n.to_owned(), + version: VersionMatcher::new(v), + } + } else { + Self { + name: pattern.to_owned(), + version: VersionMatcher::None, + } + } + } + + fn matches<'data, O: ObjectFile<'data>>( + &self, + name: &[u8], + symbol_id: SymbolId, + symbol_db: &SymbolDb<'data, O>, + ) -> bool { + if let Some(i) = name.iter().position(|b| *b == b'@') { + let (name, version) = name.split_at(i); + return name == self.name.as_bytes() && self.version.matches_at_prefixed(version); + } + + if name != self.name.as_bytes() { + return false; + } + + self.version.matches_at_prefixed( + symbol_db + .symbol_version_debug(symbol_id) + .unwrap_or_default() + .as_bytes(), + ) + } +} + +impl VersionMatcher { + fn new(n: &str) -> Self { + if n == "*" { + VersionMatcher::Any + } else { + VersionMatcher::Exact(n.to_owned()) + } + } + + fn matches_at_prefixed(&self, mut version: &[u8]) -> bool { + let is_default = version.starts_with(b"@@"); + while let Some(rest) = version.strip_prefix(b"@") { + version = rest; + } + match self { + VersionMatcher::Any => true, + VersionMatcher::Exact(v) => version == v.as_bytes(), + VersionMatcher::None => is_default || version.is_empty(), + } + } +} diff --git a/libwild/src/elf.rs b/libwild/src/elf.rs index 4afad3ef8..6868d15d6 100644 --- a/libwild/src/elf.rs +++ b/libwild/src/elf.rs @@ -268,9 +268,9 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { type CommonGroupStateExt = CommonGroupStateExt; type LayoutResourcesExt = LayoutResourcesExt<'data>; type ProgramSegmentDef = ProgramSegmentDef; - type ArgsType = crate::args::linux::ElfArgs; + type Args = crate::args::linux::ElfArgs; - fn parse(input: &InputBytes<'data>, args: &Args) -> Result { + fn parse(input: &InputBytes<'data>, args: &Args) -> Result { let is_dynamic = input.kind == FileKind::ElfDynamic; let file = Self::parse_bytes(input.data, is_dynamic)?; @@ -679,7 +679,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, + args: &Args, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -848,7 +848,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { } fn new_epilogue_layout( - args: &Args, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout { @@ -1178,7 +1178,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { fn pre_finalise_sizes_prelude( common: &mut layout::CommonGroupState<'data, File<'data>>, - args: &Args, + args: &Args, ) { if args.should_write_eh_frame_hdr { common.allocate(part_id::EH_FRAME_HDR, size_of::() as u64); @@ -1421,7 +1421,7 @@ impl<'data> platform::ObjectFile<'data> for File<'data> { fn update_segment_keep_list( program_segments: &ProgramSegments, keep_segments: &mut [bool], - args: &Args, + args: &Args, ) { // If relro is disabled, then discard the relro segment. if !args.relro { diff --git a/libwild/src/input_data.rs b/libwild/src/input_data.rs index 7fd858025..1f7ef2d3c 100644 --- a/libwild/src/input_data.rs +++ b/libwild/src/input_data.rs @@ -1,965 +1,965 @@ -//! Code for figuring out what input files we need to read then mapping them into memory. - -use crate::archive; -use crate::archive::ArchiveEntry; -use crate::archive::ArchiveIterator; -use crate::archive::EntryMeta; -use crate::args::Args; -use crate::args::Input; -use crate::args::InputSpec; -use crate::args::Modifiers; -use crate::bail; -use crate::error::Context as _; -use crate::error::Error; -use crate::error::Result; -use crate::file_kind::FileKind; -use crate::linker_plugins::LinkerPlugin; -use crate::linker_plugins::LtoInputInfo; -use crate::linker_script::LinkerScript; -use crate::parsing::ParsedInputObject; -use crate::platform::ObjectFile; -use crate::timing_phase; -use crate::verbose_timing_phase; -use colosseum::sync::Arena; -use crossbeam_queue::SegQueue; -use hashbrown::HashMap; -use memmap2::Mmap; -use rayon::Scope; -use rayon::iter::IntoParallelIterator; -use rayon::iter::IntoParallelRefIterator; -use rayon::iter::ParallelIterator; -use std::fmt::Display; -use std::ops::Deref; -use std::path::Path; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::Mutex; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; - -pub(crate) struct FileLoader<'data> { - /// The files that we've loaded so far. - pub(crate) loaded_files: Vec<&'data InputFile>, - - /// Whether we have at least one input file that is a dynamic object. - pub(crate) has_dynamic: bool, - - inputs_arena: &'data Arena, -} - -#[derive(Default)] -pub(crate) struct LoadedInputs<'data, O: ObjectFile<'data>> { - /// The results of parsing all the input files and archive entries. We defer checking for - /// success until later, since otherwise a parse error would mean that the save-dir mechanism - /// wouldn't capture all the input files. - pub(crate) objects: Vec>>>, - - pub(crate) linker_scripts: Vec>, - - pub(crate) lto_objects: Vec>>>, -} - -pub(crate) struct InputBytes<'data> { - pub(crate) input: InputRef<'data>, - pub(crate) kind: FileKind, - pub(crate) data: &'data [u8], - pub(crate) modifiers: Modifiers, -} - -#[derive(Clone, Copy)] -pub(crate) struct ScriptData<'data> { - pub(crate) raw: &'data [u8], -} - -/// Identifies an input file. IDs start from 0 which is reserved for our prelude file. -#[derive(derive_more::Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[debug("file-{_0}")] -pub(crate) struct FileId(u32); - -pub(crate) const PRELUDE_FILE_ID: FileId = FileId::new(0, 0); - -#[derive(Debug)] -pub(crate) struct InputFile { - pub(crate) filename: PathBuf, - - /// The filename prior to path search. If this is absolute, then `filename` will be the same. - pub(crate) original_filename: PathBuf, - - pub(crate) modifiers: Modifiers, - - pub(crate) data: Option, -} - -#[derive(Debug)] -pub(crate) struct FileData { - bytes: Mmap, - - /// The modification timestamp of the input file just before we opened it. We expect our input - /// files not to change while we're running. - modification_time: std::time::SystemTime, -} - -/// Identifies an input object that may not be a regular file on disk, or may be an entry in an -/// archive. -#[derive(Clone, Copy)] -pub(crate) struct InputRef<'data> { - pub(crate) file: &'data InputFile, - pub(crate) entry: Option>, -} - -impl InputFile { - pub(crate) fn data(&self) -> &[u8] { - self.data.as_deref().unwrap_or_default() - } -} - -#[derive(Debug)] -struct InputPath { - /// An absolute path to the file. - absolute: PathBuf, - - /// The file as specified on the command line. In the case of an argument like -lfoo, this will - /// be "libfoo.so". - original: PathBuf, -} - -#[derive(Debug)] -pub(crate) struct InputLinkerScript<'data> { - pub(crate) script: LinkerScript<'data>, - pub(crate) input_file: &'data InputFile, -} - -struct TemporaryState<'data, O: ObjectFile<'data>> { - args: &'data Args, - - /// Mapping from paths to the index in `files` at which we'll place the result. - path_to_load_index: Mutex>, - - next_file_load_index: AtomicUsize, - - files: SegQueue>, - - inputs_arena: &'data Arena, -} - -struct LoadedFile<'data, O: ObjectFile<'data>> { - index: FileLoadIndex, - state: LoadedFileState<'data, O>, -} - -enum LoadedFileState<'data, O: ObjectFile<'data>> { - Loaded(&'data InputFile, InputRecord<'data, O>), - Archive(&'data InputFile, Vec>), - ThinArchive(Vec<&'data InputFile>, Vec>), - LinkerScript(LoadedLinkerScriptState<'data>), - Error(Error), -} - -enum InputRecord<'data, O: ObjectFile<'data>> { - Object(Result>>), - LtoInput(Box>), -} - -struct UnclaimedLtoInput<'data> { - input_ref: InputRef<'data>, - file: Arc, - kind: FileKind, -} - -struct LoadedLinkerScriptState<'data> { - /// The indexes of the files requested by the linker script. Some of these indexes may turn out - /// to have been claimed earlier in the command-line, so we'll only load those that haven't. - file_indexes: Vec, - - /// The parsed linker script. - script: InputLinkerScript<'data>, -} - -/// A temporary ID for files that we loaded. Files specified on the command-line will have -/// deterministic values. Other files, e.g. those referenced by thin archives or linker scripts will -/// have non-deterministic values. -#[derive(Clone, Copy)] -struct FileLoadIndex(usize); - -/// A request for a worker to open the specified input, mmap its contents and identify what type of -/// file it is. If it turns out to be a thin archive, then the referenced files are also loaded. -struct OpenFileRequest { - file_index: FileLoadIndex, - paths: InputPath, - modifiers: Modifiers, - - /// The file that requested this file be opened. e.g. a linker script. In theory, we could have - /// a chain of files where linker scripts reference linker scripts, but for simplicity, we only - /// report the last file in the chain. - referenced_by: Option, -} - -struct LoadedLinkerScript<'data> { - script: InputLinkerScript<'data>, - extra_inputs: Vec, -} - -pub(crate) struct AuxiliaryFiles<'data> { - pub(crate) version_script_data: Option>, - pub(crate) export_list_data: Option>, -} - -impl<'data> AuxiliaryFiles<'data> { - pub(crate) fn new(args: &'data Args, inputs_arena: &'data Arena) -> Result { - let resolve_script_path = |path: &Path| -> PathBuf { - if path.exists() { - path.to_owned() - } else if let Some(found) = search_for_file(&args.lib_search_path, None, path) { - found - } else { - path.to_owned() - } - }; - - Ok(Self { - version_script_data: args - .version_script_path - .as_ref() - .map(|path| read_script_data(&resolve_script_path(path), inputs_arena)) - .transpose()?, - export_list_data: args - .export_list_path - .as_ref() - .map(|path| read_script_data(&resolve_script_path(path), inputs_arena)) - .transpose()?, - }) - } -} - -impl<'data> FileLoader<'data> { - pub(crate) fn new(inputs_arena: &'data Arena) -> Self { - Self { - loaded_files: Vec::new(), - inputs_arena, - has_dynamic: false, - } - } - - pub(crate) fn load_inputs>( - &mut self, - inputs: &[Input], - args: &'data Args, - plugin: &mut Option>, - ) -> Result> { - timing_phase!("Open input files"); - - let mut path_to_load_index = HashMap::new(); - - let mut initial_work = Vec::with_capacity(inputs.len()); - for input in inputs { - let path = input.path(args)?; - path_to_load_index - .entry(path.absolute.clone()) - .or_insert_with(|| { - let file_index = FileLoadIndex(initial_work.len()); - - initial_work.push(OpenFileRequest { - file_index, - paths: path, - modifiers: input.modifiers, - referenced_by: None, - }); - - file_index - }); - } - - let temporary_state = TemporaryState { - args, - path_to_load_index: Mutex::new(path_to_load_index), - next_file_load_index: AtomicUsize::new(initial_work.len()), - files: SegQueue::new(), - inputs_arena: self.inputs_arena, - }; - - // Open files, mmap them and identify their type from separate threads. - rayon::scope(|scope| { - initial_work.into_par_iter().for_each(|request| { - temporary_state.process_and_record_open_file_request(request, scope); - }); - }); - - verbose_timing_phase!("Finalise open input files"); - - // Put files into a deterministic order. That order will the order we'd find them if we just - // processed command-line arguments in order, recursively processing any files that those - // files pulled in. - let mut files_by_index = Vec::new(); - files_by_index.resize_with(temporary_state.files.len(), || None); - for file in temporary_state.files.into_iter() { - let entry = &mut files_by_index[file.index.0]; - assert!( - entry.is_none(), - "Internal error: Multiple files with the same index" - ); - *entry = Some(file.state); - } - self.extract_all(&mut files_by_index, plugin) - } - - /// Checks that the modification timestamp on all our input files hasn't changed since we opened - /// them. If they were modified while we were running, then we may fail with a SIGBUS if we try - /// to access part of the file that's no longer there, however if we don't, then we may have - /// read inconsistent data from the changed object, so we want to fail the link. - pub(crate) fn verify_inputs_unchanged(&self) -> Result { - timing_phase!("Verify inputs unchanged"); - - self.loaded_files.par_iter().try_for_each(|file| { - let Some(file_data) = &file.data else { - return Ok(()); - }; - - let metadata = std::fs::metadata(&file.filename).with_context(|| { - format!("Failed to read metadata for `{}`", file.filename.display()) - })?; - - let new_modified = metadata.modified().with_context(|| { - format!( - "Failed to get modification time for `{}`", - file.filename.display() - ) - })?; - - if file_data.modification_time != new_modified { - bail!( - "The file `{}` was changed while we were running", - file.filename.display() - ); - } - - Ok(()) - }) - } - - /// Extract all files and linker scripts from `files`. Extraction order is the same as the order - /// on the original command-line. This is roughly FileLoadIndex order, except that (a) if a file - /// is loaded multiple times, it will only appear the first time it's encountered and (b) when a - /// linker script is loaded, its files appear at the point at which the linker script appeared - /// on the command-line, even though the FileLoadIndex for files loaded by linker scripts is - /// later. - fn extract_all>( - &mut self, - files: &mut [Option>], - plugin: &mut Option>, - ) -> Result> { - let mut loaded = LoadedInputs { - objects: Vec::with_capacity(files.len()), - linker_scripts: Vec::new(), - lto_objects: Vec::new(), - }; - - for i in 0..files.len() { - self.extract_file(FileLoadIndex(i), files, &mut loaded, plugin)?; - } - - Ok(loaded) - } - - fn extract_file>( - &mut self, - index: FileLoadIndex, - files: &mut [Option>], - loaded: &mut LoadedInputs<'data, O>, - plugin: &mut Option>, - ) -> Result { - match core::mem::take(&mut files[index.0]) { - None => {} - Some(LoadedFileState::Loaded(input_file, parse_result)) => { - if parse_result.is_dynamic_object() { - self.has_dynamic = true; - } - loaded.add_record(parse_result, plugin); - self.loaded_files.push(input_file); - } - Some(LoadedFileState::Archive(input_file, parsed_parts)) => { - loaded.add_records(parsed_parts, plugin); - self.loaded_files.push(input_file); - } - Some(LoadedFileState::ThinArchive(mut input_files, parsed_parts)) => { - loaded.add_records(parsed_parts, plugin); - self.loaded_files.append(&mut input_files); - } - Some(LoadedFileState::LinkerScript(loaded_linker_script_state)) => { - self.loaded_files - .push(loaded_linker_script_state.script.input_file); - - loaded - .linker_scripts - .push(loaded_linker_script_state.script); - - for i in loaded_linker_script_state.file_indexes { - self.extract_file(i, files, loaded, plugin)?; - } - } - Some(LoadedFileState::Error(error)) => { - // For now, we just report the first error that we come to. - return Err(error); - } - } - - Ok(()) - } -} - -fn process_linker_script<'data, T>( - input_file: &'data InputFile, - args: &Args, -) -> Result> { - let bytes = input_file.data(); - let script = LinkerScript::parse(bytes, &input_file.filename)?; - - let script_path = std::fs::canonicalize(&input_file.filename)?; - let directory = script_path.parent().expect("expected an absolute path"); - - let mut extra_inputs = Vec::new(); - - script.foreach_input(input_file.modifiers, |mut input| { - input.search_first = Some(directory.to_owned()); - - if let (Some(sysroot), InputSpec::File(file)) = (args.sysroot.as_ref(), &mut input.spec) - && let Some(new_file) = - crate::linker_script::maybe_apply_sysroot(&script_path, file, sysroot) - { - *file = new_file; - } - - extra_inputs.push(input); - - Ok(()) - })?; - - Ok(LoadedLinkerScript { - script: InputLinkerScript { script, input_file }, - extra_inputs, - }) -} - -fn process_archive<'data, O: ObjectFile<'data>>( - input_file: &'data InputFile, - file: &Arc, - state: &TemporaryState<'data, O>, -) -> Result> { - let mut outputs = Vec::new(); - - for entry in ArchiveIterator::from_archive_bytes(input_file.data())? { - let entry = entry?; - match entry { - ArchiveEntry::Regular(archive_entry) => { - let input_ref = InputRef { - file: input_file, - entry: Some(EntryMeta { - identifier: archive_entry.ident, - start_offset: archive_entry.data_offset, - end_offset: archive_entry.data_offset + archive_entry.entry_data.len(), - }), - }; - - let kind = FileKind::identify_bytes(input_ref.data()) - .with_context(|| format!("Failed process input `{input_ref}`"))?; - - outputs.push(state.process_input(input_ref, file, kind)?); - } - ArchiveEntry::Thin(_) => unreachable!(), - } - } - - Ok(LoadedFileState::Archive(input_file, outputs)) -} - -fn process_thin_archive<'data, O: ObjectFile<'data>>( - input_file: &InputFile, - state: &TemporaryState<'data, O>, -) -> Result> { - let absolute_path = &input_file.filename; - let parent_path = absolute_path.parent().unwrap(); - let mut files = Vec::new(); - let mut parsed_files = Vec::new(); - - for entry in ArchiveIterator::from_archive_bytes(input_file.data())? { - match entry? { - ArchiveEntry::Thin(entry) => { - let path = entry.ident.as_path(); - let entry_path = parent_path.join(path); - - let (file_data, file) = FileData::open(&entry_path, state.args.prepopulate_maps) - .with_context(|| { - format!( - "Failed to open file referenced by thin archive `{}`", - input_file.filename.display() - ) - })?; - - let input_file = InputFile { - filename: entry_path.clone(), - original_filename: entry_path, - modifiers: Modifiers { - archive_semantics: true, - ..input_file.modifiers - }, - data: Some(file_data), - }; - - let input_file = &*state.inputs_arena.alloc(input_file); - - let input_ref = InputRef { - file: input_file, - entry: None, - }; - - let kind = FileKind::identify_bytes(input_ref.data()) - .with_context(|| format!("Failed process input `{input_ref}`"))?; - - parsed_files.push(state.process_input(input_ref, &Arc::new(file), kind)?); - files.push(input_file); - } - ArchiveEntry::Regular(_) => {} - } - } - - Ok(LoadedFileState::ThinArchive(files, parsed_files)) -} - -impl<'data, O: ObjectFile<'data>> TemporaryState<'data, O> { - fn process_and_record_open_file_request<'scope>( - &'scope self, - request: OpenFileRequest, - scope: &Scope<'scope>, - ) { - let file_index = request.file_index; - let loaded_state = self - .process_open_file_request(request, scope) - .unwrap_or_else(LoadedFileState::Error); - self.files.push(LoadedFile { - index: file_index, - state: loaded_state, - }); - } - - fn process_open_file_request<'scope>( - &'scope self, - request: OpenFileRequest, - scope: &Scope<'scope>, - ) -> Result> { - verbose_timing_phase!("Open file"); - - let absolute_path = &request.paths.absolute; - let result = FileData::open(absolute_path.as_path(), self.args.prepopulate_maps); - let (data, file) = match request.referenced_by.as_ref() { - Some(referenced_by) => { - result.with_context(|| format!("Failed to process `{}`", referenced_by.display())) - } - None => result, - }?; - - let input_file = self.inputs_arena.alloc(InputFile { - filename: absolute_path.to_owned(), - original_filename: request.paths.original, - modifiers: request.modifiers, - data: Some(data), - }); - - let input_ref = InputRef { - file: input_file, - entry: None, - }; - - let data = input_ref.file.data.as_ref().unwrap(); - let kind = FileKind::identify_bytes(&data.bytes)?; - - match kind { - FileKind::Archive => process_archive(input_file, &Arc::new(file), self), - FileKind::ThinArchive => process_thin_archive(input_file, self), - FileKind::Text => { - let script = process_linker_script(input_file, self.args)?; - - let file_indexes = script - .extra_inputs - .into_iter() - .map(|input| { - self.load_input( - &input, - scope, - Some(script.script.input_file.filename.clone()), - ) - }) - .collect::>>()?; - - Ok(LoadedFileState::LinkerScript(LoadedLinkerScriptState { - file_indexes, - script: script.script, - })) - } - _ => { - let parsed = self.process_input(input_ref, &Arc::new(file), kind)?; - Ok(LoadedFileState::Loaded(input_file, parsed)) - } - } - } - - /// Sends a request to load `input` unless it has already been requested. In either case, return - /// the index for `input` in our files Vec. - fn load_input<'scope>( - &'scope self, - input: &Input, - scope: &Scope<'scope>, - referenced_by: Option, - ) -> Result { - let paths = input.path(self.args)?; - - let mut path_to_load_index = self.path_to_load_index.lock().unwrap(); - - let index = match path_to_load_index.entry(paths.absolute.clone()) { - hashbrown::hash_map::Entry::Occupied(e) => *e.get(), - hashbrown::hash_map::Entry::Vacant(e) => { - let new_index = - FileLoadIndex(self.next_file_load_index.fetch_add(1, Ordering::Relaxed)); - e.insert(new_index); - - drop(path_to_load_index); - - let request = OpenFileRequest { - file_index: new_index, - paths, - modifiers: input.modifiers, - referenced_by, - }; - - scope.spawn(|scope| { - self.process_and_record_open_file_request(request, scope); - }); - - new_index - } - }; - - Ok(index) - } - - fn process_input( - &self, - input_ref: InputRef<'data>, - file: &Arc, - kind: FileKind, - ) -> Result> { - let data = input_ref.data(); - - // The plugin API docs say to pass files to the plugin before the linker tries to identify - // the them. Unfortunately the plugin API doesn't provide a fast way to identify files. The - // plugin API doesn't say anything about thread-safety and although the GCC plugin appears - // to be threadsafe, the clang plugin definitely isn't. This means that using the API to - // identify files is much too slow, so we do our own file identification and only pass files - // to the plugin if we think it can handle them. We can't rely on a plugin only being - // supplied when actually needed, since GCC seems to pretty much always pass a plugin to the - // linker. - if kind.is_compiler_ir() { - return Ok(InputRecord::LtoInput(Box::new(UnclaimedLtoInput { - input_ref, - file: Arc::clone(file), - kind, - }))); - } - - if input_ref.is_archive_entry() - && kind != FileKind::ElfObject - && kind != FileKind::CoffObject - && kind != FileKind::CoffImport - { - bail!("Unexpected archive member of kind {kind:?}: {input_ref}"); - } - - let input_bytes = InputBytes { - kind, - input: input_ref, - data, - modifiers: input_ref.file.modifiers, - }; - - let object = ParsedInputObject::new(&input_bytes, self.args); - - Ok(InputRecord::Object(object)) - } -} - -fn read_script_data<'data>( - path: &Path, - inputs_arena: &'data Arena, -) -> Result> { - let data = FileData::new(path, false).context("Failed to read script")?; - - let file = inputs_arena.alloc(InputFile { - filename: path.to_owned(), - original_filename: path.to_owned(), - modifiers: Default::default(), - data: Some(data), - }); - - Ok(ScriptData { raw: file.data() }) -} - -impl Input { - fn path(&self, args: &Args) -> Result { - match &self.spec { - InputSpec::File(p) => { - if self.search_first.is_some() - && let Some(path) = search_for_file( - &args.lib_search_path, - self.search_first.as_ref(), - p.as_ref(), - ) - { - return Ok(InputPath { - absolute: std::path::absolute(path)?, - original: p.as_ref().to_owned(), - }); - } - Ok(InputPath { - absolute: p.as_ref().to_owned(), - original: p.as_ref().to_owned(), - }) - } - InputSpec::Lib(lib_name) => { - if self.modifiers.allow_shared { - let filename = format!("lib{lib_name}.so"); - if let Some(path) = search_for_file( - &args.lib_search_path, - self.search_first.as_ref(), - &filename, - ) { - return Ok(InputPath { - absolute: std::path::absolute(&path)?, - original: PathBuf::from(filename), - }); - } - } - let filename = format!("lib{lib_name}.a"); - if let Some(path) = - search_for_file(&args.lib_search_path, self.search_first.as_ref(), &filename) - { - return Ok(InputPath { - absolute: std::path::absolute(&path)?, - original: PathBuf::from(filename), - }); - } - bail!("Couldn't find library `{lib_name}` on library search path"); - } - InputSpec::Search(filename) => { - if let Some(path) = search_for_file( - &args.lib_search_path, - self.search_first.as_ref(), - filename.as_ref(), - ) { - return Ok(InputPath { - absolute: std::path::absolute(&path)?, - original: PathBuf::from(filename.as_ref()), - }); - } - bail!("Couldn't find library `{filename}` on library search path"); - } - } - } -} - -impl FileData { - pub(crate) fn new(path: &Path, prepopulate_maps: bool) -> Result { - Self::open(path, prepopulate_maps).map(|(file_data, _file)| file_data) - } - - fn open(path: &Path, prepopulate_maps: bool) -> Result<(Self, std::fs::File)> { - let file = std::fs::File::open(path) - .with_context(|| format!("Failed to open input file `{}`", path.display()))?; - - let modification_time = std::fs::metadata(path) - .and_then(|meta| meta.modified()) - .with_context(|| { - format!("Failed to read file modification time `{}`", path.display()) - })?; - - // Safety: Unfortunately, this is a bit of a compromise. Basically this is only safe if our - // users manage to avoid editing the input files while we've got them mapped. It'd be great - // if there were a way to protect against unsoundness when the input files were modified - // externally, but there isn't - at least on Linux. Not only could the bytes change without - // notice, but the mapped file could be truncated causing any access to result in a SIGBUS. - // - // For our use case, mmap just has too many advantages. There are likely large parts of our - // input files that we don't need to read, so reading all our input files up front isn't - // really an option. Reading just the parts we need might be an option, but would add - // substantial complexity. Also, using mmap means that if the system needs to reclaim - // memory, it can just release some of our pages. - - let mut mmap_options = memmap2::MmapOptions::new(); - - // Prepopulating maps generally slows things down, so is off by default, however it's useful - // when profiling, since it means that you don't see false positive slowness in the parts of - // the code that first read a bit of memory. - if prepopulate_maps { - mmap_options.populate(); - } - - let bytes = unsafe { mmap_options.map(&file) } - .with_context(|| format!("Failed to mmap input file `{}`", path.display()))?; - - Ok(( - FileData { - bytes, - modification_time, - }, - file, - )) - } -} - -fn search_for_file( - lib_search_path: &[Box], - search_first: Option<&PathBuf>, - filename: impl AsRef, -) -> Option { - let filename = filename.as_ref(); - if let Some(search_first) = search_first { - let path = search_first.join(filename); - if path.exists() { - return Some(path); - } - } - for dir in lib_search_path { - let path = dir.join(filename); - if path.exists() { - return Some(path); - } - } - None -} - -impl Deref for FileData { - type Target = [u8]; - - fn deref(&self) -> &Self::Target { - &self.bytes - } -} - -const FILE_INDEX_BITS: u32 = 8; -pub(crate) const MAX_FILES_PER_GROUP: u32 = 1 << FILE_INDEX_BITS; - -impl FileId { - pub(crate) const fn new(group: u32, file: u32) -> Self { - Self((group << FILE_INDEX_BITS) | file) - } - - pub(crate) const fn from_encoded(v: u32) -> Self { - Self(v) - } - - pub(crate) fn group(self) -> usize { - self.0 as usize >> FILE_INDEX_BITS - } - - pub(crate) fn file(self) -> usize { - self.0 as usize & ((1 << FILE_INDEX_BITS) - 1) - } - - pub(crate) fn as_u32(self) -> u32 { - self.0 - } -} - -impl std::fmt::Display for InputRef<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.file.filename.display(), f)?; - if let Some(entry) = &self.entry { - std::fmt::Display::fmt(" @ ", f)?; - std::fmt::Display::fmt(&String::from_utf8_lossy(entry.identifier.as_slice()), f)?; - } - Ok(()) - } -} - -impl std::fmt::Debug for InputRef<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self, f) - } -} - -impl std::fmt::Display for FileId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} ({}/{})", self.0, self.group(), self.file()) - } -} - -impl<'data> InputRef<'data> { - pub(crate) fn lib_name(&self) -> &'data [u8] { - self.file.original_filename.as_os_str().as_encoded_bytes() - } - - pub(crate) fn has_archive_semantics(&self) -> bool { - self.entry.is_some() || self.file.modifiers.archive_semantics - } - - pub(crate) fn data(&self) -> &'data [u8] { - if let Some(entry) = &self.entry { - &self.file.data()[entry.byte_range()] - } else { - self.file.data() - } - } - - fn is_archive_entry(&self) -> bool { - self.entry.is_some() - } -} - -impl Display for InputBytes<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Display::fmt(&self.input, f) - } -} - -impl<'data, O: ObjectFile<'data>> LoadedInputs<'data, O> { - fn add_record( - &mut self, - record: InputRecord<'data, O>, - plugin: &mut Option>, - ) { - match record { - InputRecord::Object(obj) => self.objects.push(obj), - InputRecord::LtoInput(obj) => { - let UnclaimedLtoInput { - input_ref, - file, - kind, - } = *obj; - let result = plugin.as_mut() - .with_context(|| { - format!( - "Input file {input_ref} contains {kind}, but linker plugin was not supplied" - ) - }) - .and_then(|plugin| plugin.process_input(input_ref, &file, kind)); - self.lto_objects.push(result); - } - } - } - - fn add_records( - &mut self, - parsed_parts: Vec>, - plugin: &mut Option>, - ) { - for part in parsed_parts { - self.add_record(part, plugin); - } - } -} - -impl<'data, O: ObjectFile<'data>> InputRecord<'data, O> { - fn is_dynamic_object(&self) -> bool { - match self { - InputRecord::Object(Ok(obj)) => obj.is_dynamic(), - _ => false, - } - } -} +//! Code for figuring out what input files we need to read then mapping them into memory. + +use crate::archive; +use crate::archive::ArchiveEntry; +use crate::archive::ArchiveIterator; +use crate::archive::EntryMeta; +use crate::args::Args; +use crate::args::Input; +use crate::args::InputSpec; +use crate::args::Modifiers; +use crate::bail; +use crate::error::Context as _; +use crate::error::Error; +use crate::error::Result; +use crate::file_kind::FileKind; +use crate::linker_plugins::LinkerPlugin; +use crate::linker_plugins::LtoInputInfo; +use crate::linker_script::LinkerScript; +use crate::parsing::ParsedInputObject; +use crate::platform::ObjectFile; +use crate::timing_phase; +use crate::verbose_timing_phase; +use colosseum::sync::Arena; +use crossbeam_queue::SegQueue; +use hashbrown::HashMap; +use memmap2::Mmap; +use rayon::Scope; +use rayon::iter::IntoParallelIterator; +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::ParallelIterator; +use std::fmt::Display; +use std::ops::Deref; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::Mutex; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +pub(crate) struct FileLoader<'data> { + /// The files that we've loaded so far. + pub(crate) loaded_files: Vec<&'data InputFile>, + + /// Whether we have at least one input file that is a dynamic object. + pub(crate) has_dynamic: bool, + + inputs_arena: &'data Arena, +} + +#[derive(Default)] +pub(crate) struct LoadedInputs<'data, O: ObjectFile<'data>> { + /// The results of parsing all the input files and archive entries. We defer checking for + /// success until later, since otherwise a parse error would mean that the save-dir mechanism + /// wouldn't capture all the input files. + pub(crate) objects: Vec>>>, + + pub(crate) linker_scripts: Vec>, + + pub(crate) lto_objects: Vec>>>, +} + +pub(crate) struct InputBytes<'data> { + pub(crate) input: InputRef<'data>, + pub(crate) kind: FileKind, + pub(crate) data: &'data [u8], + pub(crate) modifiers: Modifiers, +} + +#[derive(Clone, Copy)] +pub(crate) struct ScriptData<'data> { + pub(crate) raw: &'data [u8], +} + +/// Identifies an input file. IDs start from 0 which is reserved for our prelude file. +#[derive(derive_more::Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[debug("file-{_0}")] +pub(crate) struct FileId(u32); + +pub(crate) const PRELUDE_FILE_ID: FileId = FileId::new(0, 0); + +#[derive(Debug)] +pub(crate) struct InputFile { + pub(crate) filename: PathBuf, + + /// The filename prior to path search. If this is absolute, then `filename` will be the same. + pub(crate) original_filename: PathBuf, + + pub(crate) modifiers: Modifiers, + + pub(crate) data: Option, +} + +#[derive(Debug)] +pub(crate) struct FileData { + bytes: Mmap, + + /// The modification timestamp of the input file just before we opened it. We expect our input + /// files not to change while we're running. + modification_time: std::time::SystemTime, +} + +/// Identifies an input object that may not be a regular file on disk, or may be an entry in an +/// archive. +#[derive(Clone, Copy)] +pub(crate) struct InputRef<'data> { + pub(crate) file: &'data InputFile, + pub(crate) entry: Option>, +} + +impl InputFile { + pub(crate) fn data(&self) -> &[u8] { + self.data.as_deref().unwrap_or_default() + } +} + +#[derive(Debug)] +struct InputPath { + /// An absolute path to the file. + absolute: PathBuf, + + /// The file as specified on the command line. In the case of an argument like -lfoo, this will + /// be "libfoo.so". + original: PathBuf, +} + +#[derive(Debug)] +pub(crate) struct InputLinkerScript<'data> { + pub(crate) script: LinkerScript<'data>, + pub(crate) input_file: &'data InputFile, +} + +struct TemporaryState<'data, O: ObjectFile<'data>> { + args: &'data Args, + + /// Mapping from paths to the index in `files` at which we'll place the result. + path_to_load_index: Mutex>, + + next_file_load_index: AtomicUsize, + + files: SegQueue>, + + inputs_arena: &'data Arena, +} + +struct LoadedFile<'data, O: ObjectFile<'data>> { + index: FileLoadIndex, + state: LoadedFileState<'data, O>, +} + +enum LoadedFileState<'data, O: ObjectFile<'data>> { + Loaded(&'data InputFile, InputRecord<'data, O>), + Archive(&'data InputFile, Vec>), + ThinArchive(Vec<&'data InputFile>, Vec>), + LinkerScript(LoadedLinkerScriptState<'data>), + Error(Error), +} + +enum InputRecord<'data, O: ObjectFile<'data>> { + Object(Result>>), + LtoInput(Box>), +} + +struct UnclaimedLtoInput<'data> { + input_ref: InputRef<'data>, + file: Arc, + kind: FileKind, +} + +struct LoadedLinkerScriptState<'data> { + /// The indexes of the files requested by the linker script. Some of these indexes may turn out + /// to have been claimed earlier in the command-line, so we'll only load those that haven't. + file_indexes: Vec, + + /// The parsed linker script. + script: InputLinkerScript<'data>, +} + +/// A temporary ID for files that we loaded. Files specified on the command-line will have +/// deterministic values. Other files, e.g. those referenced by thin archives or linker scripts will +/// have non-deterministic values. +#[derive(Clone, Copy)] +struct FileLoadIndex(usize); + +/// A request for a worker to open the specified input, mmap its contents and identify what type of +/// file it is. If it turns out to be a thin archive, then the referenced files are also loaded. +struct OpenFileRequest { + file_index: FileLoadIndex, + paths: InputPath, + modifiers: Modifiers, + + /// The file that requested this file be opened. e.g. a linker script. In theory, we could have + /// a chain of files where linker scripts reference linker scripts, but for simplicity, we only + /// report the last file in the chain. + referenced_by: Option, +} + +struct LoadedLinkerScript<'data> { + script: InputLinkerScript<'data>, + extra_inputs: Vec, +} + +pub(crate) struct AuxiliaryFiles<'data> { + pub(crate) version_script_data: Option>, + pub(crate) export_list_data: Option>, +} + +impl<'data> AuxiliaryFiles<'data> { + pub(crate) fn new(args: &'data Args, inputs_arena: &'data Arena) -> Result { + let resolve_script_path = |path: &Path| -> PathBuf { + if path.exists() { + path.to_owned() + } else if let Some(found) = search_for_file(&args.lib_search_path, None, path) { + found + } else { + path.to_owned() + } + }; + + Ok(Self { + version_script_data: args + .version_script_path + .as_ref() + .map(|path| read_script_data(&resolve_script_path(path), inputs_arena)) + .transpose()?, + export_list_data: args + .export_list_path + .as_ref() + .map(|path| read_script_data(&resolve_script_path(path), inputs_arena)) + .transpose()?, + }) + } +} + +impl<'data> FileLoader<'data> { + pub(crate) fn new(inputs_arena: &'data Arena) -> Self { + Self { + loaded_files: Vec::new(), + inputs_arena, + has_dynamic: false, + } + } + + pub(crate) fn load_inputs>( + &mut self, + inputs: &[Input], + args: &'data Args, + plugin: &mut Option>, + ) -> Result> { + timing_phase!("Open input files"); + + let mut path_to_load_index = HashMap::new(); + + let mut initial_work = Vec::with_capacity(inputs.len()); + for input in inputs { + let path = input.path(args)?; + path_to_load_index + .entry(path.absolute.clone()) + .or_insert_with(|| { + let file_index = FileLoadIndex(initial_work.len()); + + initial_work.push(OpenFileRequest { + file_index, + paths: path, + modifiers: input.modifiers, + referenced_by: None, + }); + + file_index + }); + } + + let temporary_state = TemporaryState { + args, + path_to_load_index: Mutex::new(path_to_load_index), + next_file_load_index: AtomicUsize::new(initial_work.len()), + files: SegQueue::new(), + inputs_arena: self.inputs_arena, + }; + + // Open files, mmap them and identify their type from separate threads. + rayon::scope(|scope| { + initial_work.into_par_iter().for_each(|request| { + temporary_state.process_and_record_open_file_request(request, scope); + }); + }); + + verbose_timing_phase!("Finalise open input files"); + + // Put files into a deterministic order. That order will the order we'd find them if we just + // processed command-line arguments in order, recursively processing any files that those + // files pulled in. + let mut files_by_index = Vec::new(); + files_by_index.resize_with(temporary_state.files.len(), || None); + for file in temporary_state.files.into_iter() { + let entry = &mut files_by_index[file.index.0]; + assert!( + entry.is_none(), + "Internal error: Multiple files with the same index" + ); + *entry = Some(file.state); + } + self.extract_all(&mut files_by_index, plugin) + } + + /// Checks that the modification timestamp on all our input files hasn't changed since we opened + /// them. If they were modified while we were running, then we may fail with a SIGBUS if we try + /// to access part of the file that's no longer there, however if we don't, then we may have + /// read inconsistent data from the changed object, so we want to fail the link. + pub(crate) fn verify_inputs_unchanged(&self) -> Result { + timing_phase!("Verify inputs unchanged"); + + self.loaded_files.par_iter().try_for_each(|file| { + let Some(file_data) = &file.data else { + return Ok(()); + }; + + let metadata = std::fs::metadata(&file.filename).with_context(|| { + format!("Failed to read metadata for `{}`", file.filename.display()) + })?; + + let new_modified = metadata.modified().with_context(|| { + format!( + "Failed to get modification time for `{}`", + file.filename.display() + ) + })?; + + if file_data.modification_time != new_modified { + bail!( + "The file `{}` was changed while we were running", + file.filename.display() + ); + } + + Ok(()) + }) + } + + /// Extract all files and linker scripts from `files`. Extraction order is the same as the order + /// on the original command-line. This is roughly FileLoadIndex order, except that (a) if a file + /// is loaded multiple times, it will only appear the first time it's encountered and (b) when a + /// linker script is loaded, its files appear at the point at which the linker script appeared + /// on the command-line, even though the FileLoadIndex for files loaded by linker scripts is + /// later. + fn extract_all>( + &mut self, + files: &mut [Option>], + plugin: &mut Option>, + ) -> Result> { + let mut loaded = LoadedInputs { + objects: Vec::with_capacity(files.len()), + linker_scripts: Vec::new(), + lto_objects: Vec::new(), + }; + + for i in 0..files.len() { + self.extract_file(FileLoadIndex(i), files, &mut loaded, plugin)?; + } + + Ok(loaded) + } + + fn extract_file>( + &mut self, + index: FileLoadIndex, + files: &mut [Option>], + loaded: &mut LoadedInputs<'data, O>, + plugin: &mut Option>, + ) -> Result { + match core::mem::take(&mut files[index.0]) { + None => {} + Some(LoadedFileState::Loaded(input_file, parse_result)) => { + if parse_result.is_dynamic_object() { + self.has_dynamic = true; + } + loaded.add_record(parse_result, plugin); + self.loaded_files.push(input_file); + } + Some(LoadedFileState::Archive(input_file, parsed_parts)) => { + loaded.add_records(parsed_parts, plugin); + self.loaded_files.push(input_file); + } + Some(LoadedFileState::ThinArchive(mut input_files, parsed_parts)) => { + loaded.add_records(parsed_parts, plugin); + self.loaded_files.append(&mut input_files); + } + Some(LoadedFileState::LinkerScript(loaded_linker_script_state)) => { + self.loaded_files + .push(loaded_linker_script_state.script.input_file); + + loaded + .linker_scripts + .push(loaded_linker_script_state.script); + + for i in loaded_linker_script_state.file_indexes { + self.extract_file(i, files, loaded, plugin)?; + } + } + Some(LoadedFileState::Error(error)) => { + // For now, we just report the first error that we come to. + return Err(error); + } + } + + Ok(()) + } +} + +fn process_linker_script<'data, T>( + input_file: &'data InputFile, + args: &Args, +) -> Result> { + let bytes = input_file.data(); + let script = LinkerScript::parse(bytes, &input_file.filename)?; + + let script_path = std::fs::canonicalize(&input_file.filename)?; + let directory = script_path.parent().expect("expected an absolute path"); + + let mut extra_inputs = Vec::new(); + + script.foreach_input(input_file.modifiers, |mut input| { + input.search_first = Some(directory.to_owned()); + + if let (Some(sysroot), InputSpec::File(file)) = (args.sysroot.as_ref(), &mut input.spec) + && let Some(new_file) = + crate::linker_script::maybe_apply_sysroot(&script_path, file, sysroot) + { + *file = new_file; + } + + extra_inputs.push(input); + + Ok(()) + })?; + + Ok(LoadedLinkerScript { + script: InputLinkerScript { script, input_file }, + extra_inputs, + }) +} + +fn process_archive<'data, O: ObjectFile<'data>>( + input_file: &'data InputFile, + file: &Arc, + state: &TemporaryState<'data, O>, +) -> Result> { + let mut outputs = Vec::new(); + + for entry in ArchiveIterator::from_archive_bytes(input_file.data())? { + let entry = entry?; + match entry { + ArchiveEntry::Regular(archive_entry) => { + let input_ref = InputRef { + file: input_file, + entry: Some(EntryMeta { + identifier: archive_entry.ident, + start_offset: archive_entry.data_offset, + end_offset: archive_entry.data_offset + archive_entry.entry_data.len(), + }), + }; + + let kind = FileKind::identify_bytes(input_ref.data()) + .with_context(|| format!("Failed process input `{input_ref}`"))?; + + outputs.push(state.process_input(input_ref, file, kind)?); + } + ArchiveEntry::Thin(_) => unreachable!(), + } + } + + Ok(LoadedFileState::Archive(input_file, outputs)) +} + +fn process_thin_archive<'data, O: ObjectFile<'data>>( + input_file: &InputFile, + state: &TemporaryState<'data, O>, +) -> Result> { + let absolute_path = &input_file.filename; + let parent_path = absolute_path.parent().unwrap(); + let mut files = Vec::new(); + let mut parsed_files = Vec::new(); + + for entry in ArchiveIterator::from_archive_bytes(input_file.data())? { + match entry? { + ArchiveEntry::Thin(entry) => { + let path = entry.ident.as_path(); + let entry_path = parent_path.join(path); + + let (file_data, file) = FileData::open(&entry_path, state.args.prepopulate_maps) + .with_context(|| { + format!( + "Failed to open file referenced by thin archive `{}`", + input_file.filename.display() + ) + })?; + + let input_file = InputFile { + filename: entry_path.clone(), + original_filename: entry_path, + modifiers: Modifiers { + archive_semantics: true, + ..input_file.modifiers + }, + data: Some(file_data), + }; + + let input_file = &*state.inputs_arena.alloc(input_file); + + let input_ref = InputRef { + file: input_file, + entry: None, + }; + + let kind = FileKind::identify_bytes(input_ref.data()) + .with_context(|| format!("Failed process input `{input_ref}`"))?; + + parsed_files.push(state.process_input(input_ref, &Arc::new(file), kind)?); + files.push(input_file); + } + ArchiveEntry::Regular(_) => {} + } + } + + Ok(LoadedFileState::ThinArchive(files, parsed_files)) +} + +impl<'data, O: ObjectFile<'data>> TemporaryState<'data, O> { + fn process_and_record_open_file_request<'scope>( + &'scope self, + request: OpenFileRequest, + scope: &Scope<'scope>, + ) { + let file_index = request.file_index; + let loaded_state = self + .process_open_file_request(request, scope) + .unwrap_or_else(LoadedFileState::Error); + self.files.push(LoadedFile { + index: file_index, + state: loaded_state, + }); + } + + fn process_open_file_request<'scope>( + &'scope self, + request: OpenFileRequest, + scope: &Scope<'scope>, + ) -> Result> { + verbose_timing_phase!("Open file"); + + let absolute_path = &request.paths.absolute; + let result = FileData::open(absolute_path.as_path(), self.args.prepopulate_maps); + let (data, file) = match request.referenced_by.as_ref() { + Some(referenced_by) => { + result.with_context(|| format!("Failed to process `{}`", referenced_by.display())) + } + None => result, + }?; + + let input_file = self.inputs_arena.alloc(InputFile { + filename: absolute_path.to_owned(), + original_filename: request.paths.original, + modifiers: request.modifiers, + data: Some(data), + }); + + let input_ref = InputRef { + file: input_file, + entry: None, + }; + + let data = input_ref.file.data.as_ref().unwrap(); + let kind = FileKind::identify_bytes(&data.bytes)?; + + match kind { + FileKind::Archive => process_archive(input_file, &Arc::new(file), self), + FileKind::ThinArchive => process_thin_archive(input_file, self), + FileKind::Text => { + let script = process_linker_script(input_file, self.args)?; + + let file_indexes = script + .extra_inputs + .into_iter() + .map(|input| { + self.load_input( + &input, + scope, + Some(script.script.input_file.filename.clone()), + ) + }) + .collect::>>()?; + + Ok(LoadedFileState::LinkerScript(LoadedLinkerScriptState { + file_indexes, + script: script.script, + })) + } + _ => { + let parsed = self.process_input(input_ref, &Arc::new(file), kind)?; + Ok(LoadedFileState::Loaded(input_file, parsed)) + } + } + } + + /// Sends a request to load `input` unless it has already been requested. In either case, return + /// the index for `input` in our files Vec. + fn load_input<'scope>( + &'scope self, + input: &Input, + scope: &Scope<'scope>, + referenced_by: Option, + ) -> Result { + let paths = input.path(self.args)?; + + let mut path_to_load_index = self.path_to_load_index.lock().unwrap(); + + let index = match path_to_load_index.entry(paths.absolute.clone()) { + hashbrown::hash_map::Entry::Occupied(e) => *e.get(), + hashbrown::hash_map::Entry::Vacant(e) => { + let new_index = + FileLoadIndex(self.next_file_load_index.fetch_add(1, Ordering::Relaxed)); + e.insert(new_index); + + drop(path_to_load_index); + + let request = OpenFileRequest { + file_index: new_index, + paths, + modifiers: input.modifiers, + referenced_by, + }; + + scope.spawn(|scope| { + self.process_and_record_open_file_request(request, scope); + }); + + new_index + } + }; + + Ok(index) + } + + fn process_input( + &self, + input_ref: InputRef<'data>, + file: &Arc, + kind: FileKind, + ) -> Result> { + let data = input_ref.data(); + + // The plugin API docs say to pass files to the plugin before the linker tries to identify + // the them. Unfortunately the plugin API doesn't provide a fast way to identify files. The + // plugin API doesn't say anything about thread-safety and although the GCC plugin appears + // to be threadsafe, the clang plugin definitely isn't. This means that using the API to + // identify files is much too slow, so we do our own file identification and only pass files + // to the plugin if we think it can handle them. We can't rely on a plugin only being + // supplied when actually needed, since GCC seems to pretty much always pass a plugin to the + // linker. + if kind.is_compiler_ir() { + return Ok(InputRecord::LtoInput(Box::new(UnclaimedLtoInput { + input_ref, + file: Arc::clone(file), + kind, + }))); + } + + if input_ref.is_archive_entry() + && kind != FileKind::ElfObject + && kind != FileKind::CoffObject + && kind != FileKind::CoffImport + { + bail!("Unexpected archive member of kind {kind:?}: {input_ref}"); + } + + let input_bytes = InputBytes { + kind, + input: input_ref, + data, + modifiers: input_ref.file.modifiers, + }; + + let object = ParsedInputObject::new(&input_bytes, self.args); + + Ok(InputRecord::Object(object)) + } +} + +fn read_script_data<'data>( + path: &Path, + inputs_arena: &'data Arena, +) -> Result> { + let data = FileData::new(path, false).context("Failed to read script")?; + + let file = inputs_arena.alloc(InputFile { + filename: path.to_owned(), + original_filename: path.to_owned(), + modifiers: Default::default(), + data: Some(data), + }); + + Ok(ScriptData { raw: file.data() }) +} + +impl Input { + fn path(&self, args: &Args) -> Result { + match &self.spec { + InputSpec::File(p) => { + if self.search_first.is_some() + && let Some(path) = search_for_file( + &args.lib_search_path, + self.search_first.as_ref(), + p.as_ref(), + ) + { + return Ok(InputPath { + absolute: std::path::absolute(path)?, + original: p.as_ref().to_owned(), + }); + } + Ok(InputPath { + absolute: p.as_ref().to_owned(), + original: p.as_ref().to_owned(), + }) + } + InputSpec::Lib(lib_name) => { + if self.modifiers.allow_shared { + let filename = format!("lib{lib_name}.so"); + if let Some(path) = search_for_file( + &args.lib_search_path, + self.search_first.as_ref(), + &filename, + ) { + return Ok(InputPath { + absolute: std::path::absolute(&path)?, + original: PathBuf::from(filename), + }); + } + } + let filename = format!("lib{lib_name}.a"); + if let Some(path) = + search_for_file(&args.lib_search_path, self.search_first.as_ref(), &filename) + { + return Ok(InputPath { + absolute: std::path::absolute(&path)?, + original: PathBuf::from(filename), + }); + } + bail!("Couldn't find library `{lib_name}` on library search path"); + } + InputSpec::Search(filename) => { + if let Some(path) = search_for_file( + &args.lib_search_path, + self.search_first.as_ref(), + filename.as_ref(), + ) { + return Ok(InputPath { + absolute: std::path::absolute(&path)?, + original: PathBuf::from(filename.as_ref()), + }); + } + bail!("Couldn't find library `{filename}` on library search path"); + } + } + } +} + +impl FileData { + pub(crate) fn new(path: &Path, prepopulate_maps: bool) -> Result { + Self::open(path, prepopulate_maps).map(|(file_data, _file)| file_data) + } + + fn open(path: &Path, prepopulate_maps: bool) -> Result<(Self, std::fs::File)> { + let file = std::fs::File::open(path) + .with_context(|| format!("Failed to open input file `{}`", path.display()))?; + + let modification_time = std::fs::metadata(path) + .and_then(|meta| meta.modified()) + .with_context(|| { + format!("Failed to read file modification time `{}`", path.display()) + })?; + + // Safety: Unfortunately, this is a bit of a compromise. Basically this is only safe if our + // users manage to avoid editing the input files while we've got them mapped. It'd be great + // if there were a way to protect against unsoundness when the input files were modified + // externally, but there isn't - at least on Linux. Not only could the bytes change without + // notice, but the mapped file could be truncated causing any access to result in a SIGBUS. + // + // For our use case, mmap just has too many advantages. There are likely large parts of our + // input files that we don't need to read, so reading all our input files up front isn't + // really an option. Reading just the parts we need might be an option, but would add + // substantial complexity. Also, using mmap means that if the system needs to reclaim + // memory, it can just release some of our pages. + + let mut mmap_options = memmap2::MmapOptions::new(); + + // Prepopulating maps generally slows things down, so is off by default, however it's useful + // when profiling, since it means that you don't see false positive slowness in the parts of + // the code that first read a bit of memory. + if prepopulate_maps { + mmap_options.populate(); + } + + let bytes = unsafe { mmap_options.map(&file) } + .with_context(|| format!("Failed to mmap input file `{}`", path.display()))?; + + Ok(( + FileData { + bytes, + modification_time, + }, + file, + )) + } +} + +fn search_for_file( + lib_search_path: &[Box], + search_first: Option<&PathBuf>, + filename: impl AsRef, +) -> Option { + let filename = filename.as_ref(); + if let Some(search_first) = search_first { + let path = search_first.join(filename); + if path.exists() { + return Some(path); + } + } + for dir in lib_search_path { + let path = dir.join(filename); + if path.exists() { + return Some(path); + } + } + None +} + +impl Deref for FileData { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +const FILE_INDEX_BITS: u32 = 8; +pub(crate) const MAX_FILES_PER_GROUP: u32 = 1 << FILE_INDEX_BITS; + +impl FileId { + pub(crate) const fn new(group: u32, file: u32) -> Self { + Self((group << FILE_INDEX_BITS) | file) + } + + pub(crate) const fn from_encoded(v: u32) -> Self { + Self(v) + } + + pub(crate) fn group(self) -> usize { + self.0 as usize >> FILE_INDEX_BITS + } + + pub(crate) fn file(self) -> usize { + self.0 as usize & ((1 << FILE_INDEX_BITS) - 1) + } + + pub(crate) fn as_u32(self) -> u32 { + self.0 + } +} + +impl std::fmt::Display for InputRef<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.file.filename.display(), f)?; + if let Some(entry) = &self.entry { + std::fmt::Display::fmt(" @ ", f)?; + std::fmt::Display::fmt(&String::from_utf8_lossy(entry.identifier.as_slice()), f)?; + } + Ok(()) + } +} + +impl std::fmt::Debug for InputRef<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} + +impl std::fmt::Display for FileId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{} ({}/{})", self.0, self.group(), self.file()) + } +} + +impl<'data> InputRef<'data> { + pub(crate) fn lib_name(&self) -> &'data [u8] { + self.file.original_filename.as_os_str().as_encoded_bytes() + } + + pub(crate) fn has_archive_semantics(&self) -> bool { + self.entry.is_some() || self.file.modifiers.archive_semantics + } + + pub(crate) fn data(&self) -> &'data [u8] { + if let Some(entry) = &self.entry { + &self.file.data()[entry.byte_range()] + } else { + self.file.data() + } + } + + fn is_archive_entry(&self) -> bool { + self.entry.is_some() + } +} + +impl Display for InputBytes<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.input, f) + } +} + +impl<'data, O: ObjectFile<'data>> LoadedInputs<'data, O> { + fn add_record( + &mut self, + record: InputRecord<'data, O>, + plugin: &mut Option>, + ) { + match record { + InputRecord::Object(obj) => self.objects.push(obj), + InputRecord::LtoInput(obj) => { + let UnclaimedLtoInput { + input_ref, + file, + kind, + } = *obj; + let result = plugin.as_mut() + .with_context(|| { + format!( + "Input file {input_ref} contains {kind}, but linker plugin was not supplied" + ) + }) + .and_then(|plugin| plugin.process_input(input_ref, &file, kind)); + self.lto_objects.push(result); + } + } + } + + fn add_records( + &mut self, + parsed_parts: Vec>, + plugin: &mut Option>, + ) { + for part in parsed_parts { + self.add_record(part, plugin); + } + } +} + +impl<'data, O: ObjectFile<'data>> InputRecord<'data, O> { + fn is_dynamic_object(&self) -> bool { + match self { + InputRecord::Object(Ok(obj)) => obj.is_dynamic(), + _ => false, + } + } +} diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs index 9bfd9ba4a..5355e76ca 100644 --- a/libwild/src/layout.rs +++ b/libwild/src/layout.rs @@ -548,7 +548,7 @@ fn compute_total_file_size(section_layouts: &OutputSectionMap> { pub(crate) symbol_db: SymbolDb<'data, O>, pub(crate) symbol_resolutions: SymbolResolutions, @@ -1393,7 +1393,7 @@ impl<'data, O: ObjectFile<'data>> Layout<'data, O> { i } - pub(crate) fn args(&self) -> &'data Args { + pub(crate) fn args(&self) -> &'data Args { self.symbol_db.args } @@ -1674,7 +1674,7 @@ fn compute_segment_layout<'data, O: ObjectFile<'data>>( output_order: &OutputOrder, program_segments: &ProgramSegments, header_info: &HeaderInfo, - args: &Args, + args: &Args, ) -> Result { #[derive(Clone)] struct Record { @@ -3055,7 +3055,7 @@ impl<'data> PreludeLayoutState<'data> { &mut self, common: &mut CommonGroupState<'data, O>, uses_tlsld: &AtomicBool, - args: &Args, + args: &Args, output_kind: OutputKind, ) { if uses_tlsld.load(atomic::Ordering::Relaxed) { @@ -3560,7 +3560,7 @@ fn should_emit_undefined_error<'data, O: ObjectFile<'data>>( sym_file_id: FileId, sym_def_file_id: FileId, flags: ValueFlags, - args: &Args, + args: &Args, output_kind: OutputKind, ) -> bool { if (output_kind.is_shared_object() && !args.no_undefined) || symbol.is_weak() { @@ -3633,7 +3633,7 @@ impl<'data> SyntheticSymbolsLayoutState<'data> { impl<'data, O: ObjectFile<'data>> EpilogueLayoutState<'data, O> { fn new( - args: &Args, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition], ) -> Self { @@ -5031,7 +5031,7 @@ fn layout_section_parts<'data, O: ObjectFile<'data>>( output_sections: &OutputSections, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &Args, + args: &Args, ) -> OutputSectionPartMap { let segment_alignments = compute_segment_alignments::( sizes, @@ -5153,7 +5153,7 @@ fn compute_segment_alignments<'data, O: ObjectFile<'data>>( sizes: &OutputSectionPartMap, program_segments: &ProgramSegments, output_order: &OutputOrder, - args: &Args, + args: &Args, output_sections: &OutputSections, ) -> HashMap { timing_phase!("Computing segment alignments"); diff --git a/libwild/src/lib.rs b/libwild/src/lib.rs index 231b967eb..853c4ad99 100644 --- a/libwild/src/lib.rs +++ b/libwild/src/lib.rs @@ -1,444 +1,444 @@ -pub(crate) mod alignment; -pub(crate) mod arch; -pub(crate) mod archive; -pub mod args; -pub(crate) mod coff; -pub(crate) mod debug_trace; -pub(crate) mod diagnostics; -pub(crate) mod diff; -pub(crate) mod dwarf_address_info; -pub(crate) mod elf; -pub(crate) mod elf_aarch64; -pub(crate) mod elf_loongarch64; -pub(crate) mod elf_riscv64; -pub(crate) mod elf_writer; -pub(crate) mod elf_x86_64; -pub mod error; -pub(crate) mod export_list; -pub(crate) mod file_kind; -pub(crate) mod file_writer; -pub(crate) mod fs; -pub(crate) mod gc_stats; -pub(crate) mod grouping; -pub(crate) mod hash; -pub(crate) mod identity; -pub(crate) mod input_data; -pub(crate) mod layout; -pub(crate) mod layout_rules; -#[cfg_attr(not(feature = "plugins"), path = "linker_plugins_disabled.rs")] -mod linker_plugins; -pub(crate) mod linker_script; -pub(crate) mod output_kind; -pub(crate) mod output_section_id; -pub(crate) mod output_section_map; -pub(crate) mod output_section_part_map; -pub(crate) mod output_trace; -pub(crate) mod parsing; -pub(crate) mod part_id; -pub(crate) mod pe_writer; -#[cfg(all( - target_os = "linux", - any(target_arch = "x86_64", target_arch = "aarch64") -))] -pub(crate) mod perf; -#[cfg(any( - not(target_os = "linux"), - all( - target_os = "linux", - any(target_arch = "riscv64", target_arch = "loongarch64") - ) -))] -#[path = "perf_unsupported.rs"] -pub(crate) mod perf; -pub(crate) mod platform; -pub(crate) mod program_segments; -pub(crate) mod resolution; -pub(crate) mod save_dir; -pub(crate) mod sframe; -pub(crate) mod sharding; -pub(crate) mod string_merging; -#[cfg(feature = "fork")] -pub(crate) mod subprocess; -#[cfg(not(feature = "fork"))] -#[path = "subprocess_unsupported.rs"] -pub(crate) mod subprocess; -pub(crate) mod symbol; -pub(crate) mod symbol_db; -pub(crate) mod target_os; -pub(crate) mod timing; -pub(crate) mod validation; -pub(crate) mod value_flags; -pub(crate) mod verification; -pub(crate) mod version_script; - -use crate::args::ActivatedArgs; -use crate::error::Context; -use crate::error::Result; -use crate::identity::linker_identity; -use crate::layout_rules::LayoutRulesBuilder; -use crate::output_kind::OutputKind; -use crate::platform::ObjectFile; -use crate::platform::Platform; -use crate::value_flags::PerSymbolFlags; -pub use args::Args; -use colosseum::sync::Arena; -use crossbeam_utils::atomic::AtomicCell; -use error::AlreadyInitialised; -use input_data::FileLoader; -use input_data::InputFile; -use output_section_id::OutputSections; -use std::io::BufWriter; -use std::io::Write; -use std::path::Path; -pub use subprocess::run_in_subprocess; -use tracing_subscriber::EnvFilter; -use tracing_subscriber::fmt; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::util::SubscriberInitExt; - -/// Trait implemented by format-specific args types to dispatch linking by architecture. -pub(crate) trait TargetFormat: Send + Sync + 'static { - fn dispatch_link<'layout_inputs>( - linker: &'layout_inputs Linker, - args: &'layout_inputs Args, - ) -> error::Result> - where - Self: Sized; -} - -impl TargetFormat for args::linux::ElfArgs { - fn dispatch_link<'layout_inputs>( - linker: &'layout_inputs Linker, - args: &'layout_inputs Args, - ) -> error::Result> { - let res = match args.arch { - arch::Architecture::X86_64 => linker.link_for_arch::(args)?, - arch::Architecture::AArch64 => linker.link_for_arch::(args)?, - arch::Architecture::RISCV64 => linker.link_for_arch::(args)?, - arch::Architecture::LoongArch64 => { - linker.link_for_arch::(args)? - } - }; - Ok(match res { - Some(layout) => LinkerOutput::Elf(layout), - None => LinkerOutput::None, - }) - } -} - -impl TargetFormat for args::windows::PeArgs { - fn dispatch_link<'layout_inputs>( - linker: &'layout_inputs Linker, - args: &'layout_inputs Args, - ) -> error::Result> { - let res = match args.arch { - arch::Architecture::X86_64 | arch::Architecture::AArch64 => { - linker.link_for_arch::(args)? - } - other => { - bail!("PE format does not support architecture: {other}"); - } - }; - Ok(match res { - Some(layout) => LinkerOutput::Pe(layout), - None => LinkerOutput::None, - }) - } -} - -#[macro_export] -macro_rules! linker_run { - ($linker:ident, $args:ident, $after:expr) => { - use $crate::TargetFormat; - let args = $args.args; - match args.target_args { - $crate::args::TargetArgs::Elf(_) => { - let args = args.map_target(|t| match t { - $crate::args::TargetArgs::Elf(e) => e, - _ => unreachable!(), - }); - let res = $crate::args::linux::ElfArgs::dispatch_link(&$linker, &args)?; - $after(res); - } - $crate::args::TargetArgs::Pe(_) => { - let args = args.map_target(|t| match t { - $crate::args::TargetArgs::Pe(p) => p, - _ => unreachable!(), - }); - let res = $crate::args::windows::PeArgs::dispatch_link(&$linker, &args)?; - $after(res); - } - } - }; -} - -/// Runs the linker and cleans up associated resources. -pub fn run(args: args::Args) -> error::Result { - // Note, we need to setup tracing before we activate the thread pool. In particular, we need to - // initialise the timing module before the worker threads are started, otherwise the threads - // won't contribute to counters such as --time=cycles,instructions etc. - setup_tracing(&args)?; - let args = args.activate_thread_pool()?; - let linker = Linker::new(); - linker_run!(linker, args, |_| {}); - - drop(linker); - timing::finalise_perfetto_trace()?; - Ok(()) -} - -/// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be -/// called once and only if nothing else has already set the global tracing dispatcher. Calling this -/// is optional. If it isn't called, no tracing-based features will function. e.g. --time. -pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { - if let Some(opts) = args.time_phase_options.as_ref() { - timing::init_tracing(opts) - } else if args.print_allocations.is_some() { - debug_trace::init() - } else { - tracing_subscriber::registry() - .with(fmt::layer()) - .with(EnvFilter::from_default_env()) - .try_init() - .map_err(|_| AlreadyInitialised) - } -} - -/// This is effectively a data store for use while linking. It takes ownership of all the input data -/// that we read, which allows the linking stages to borrow that data. Dropping this struct might be -/// expensive, so the caller of the linker might want to think about when best to drop it - probably -/// together with the `LinkerOutput`. Note, calling `exit` without dropping this struct is an -/// option, but likely won't save any time, since the bulk of the work done during drop (unmapping -/// pages) will still happen anyway. -pub struct Linker { - /// We store our input files here once we've read them. - pub(crate) inputs_arena: Arena, - - pub(crate) linker_plugin_arena: Arena, - - /// Anything that doesn't need a custom Drop implementation can go in here. In practice, it's - /// mostly just the decompressed copy of compressed string-merge sections. - pub(crate) herd: bumpalo_herd::Herd, - - /// We'll fill this in when we're done linking and start shutting down. Once this is dropped, - /// that signals the end of shutdown for the purposes of timing measurement. - #[allow(dyn_drop)] - shutdown_scope: AtomicCell>>, - - /// A timing scope that exists for the whole time we're linking. - #[allow(dyn_drop)] - _link_scope: Vec>, -} - -/// This is just here so that we defer its destruction. This allows us to (a) measure how long -/// it takes to drop and (b) if we forked, signal our parent that we're done, then drop it in -/// the background. -pub(crate) enum LinkerOutput<'layout_inputs> { - Elf(layout::Layout<'layout_inputs, crate::elf::File<'layout_inputs>>), - Pe(layout::Layout<'layout_inputs, crate::coff::CoffObjectFile<'layout_inputs>>), - None, -} - -impl Linker { - pub fn new() -> Self { - let (guard_a, guard_b) = timing_guard!("Link"); - - Self { - inputs_arena: Arena::new(), - linker_plugin_arena: Arena::new(), - herd: Default::default(), - shutdown_scope: Default::default(), - _link_scope: vec![Box::new(guard_a), Box::new(guard_b)], - } - } - - /// Runs the linker. Generic over the target format args type (ElfArgs or PeArgs). - /// The caller is responsible for mapping the args to the correct format type first. - pub(crate) fn run<'layout_inputs, T: TargetFormat>( - &'layout_inputs self, - args: &'layout_inputs ActivatedArgs, - ) -> error::Result> { - let args = &args.args; - match args.version_mode { - args::VersionMode::ExitAfterPrint => { - let mut stdout = std::io::stdout().lock(); - writeln!(stdout, "{}", linker_identity())?; - return Ok(LinkerOutput::None); - } - args::VersionMode::Verbose => { - let mut stdout = std::io::stdout().lock(); - writeln!(stdout, "{}", linker_identity())?; - // Continue linking - } - args::VersionMode::None => { - // Don't print version - } - } - - T::dispatch_link(self, args) - } - - fn link_for_arch<'layout_inputs, P: Platform<'layout_inputs>>( - &'layout_inputs self, - args: &'layout_inputs Args<>::ArgsType>, - ) -> error::Result>> { - let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); - - // Note, we propagate errors from `load_inputs_and_link` after we've checked if any files - // changed. We want inputs-changed errors to take precedence over all other errors. - let result = self.load_inputs_and_link::

(&mut file_loader, args); - - file_loader.verify_inputs_unchanged()?; - - // Write dependency file after successful linking - if result.is_ok() - && let Some(dep_file_path) = &args.dependency_file - { - write_dependency_file(dep_file_path, &args.output, &file_loader.loaded_files) - .with_context(|| { - format!( - "Failed to write dependency file `{}`", - dep_file_path.display() - ) - })?; - } - - result - } - - fn load_inputs_and_link<'layout_inputs, P: Platform<'layout_inputs>>( - &'layout_inputs self, - file_loader: &mut FileLoader<'layout_inputs>, - args: &'layout_inputs Args<>::ArgsType>, - ) -> error::Result>> { - let mut plugin = P::create_plugin(self, args)?; - - let loaded = file_loader.load_inputs(&args.inputs, args, &mut plugin); - - args.save_dir.finish(file_loader, args)?; - - let loaded = loaded?; - - let output_kind = OutputKind::new(args, file_loader); - - let mut output_sections = OutputSections::with_base_address(output_kind.base_address()); - - let mut layout_rules_builder = LayoutRulesBuilder::default(); - - let auxiliary = input_data::AuxiliaryFiles::new(args, &self.inputs_arena)?; - - let mut symbol_db = symbol_db::SymbolDb::new(args, output_kind, &auxiliary, &self.herd)?; - let mut per_symbol_flags = PerSymbolFlags::new(); - - symbol_db.add_inputs( - &mut per_symbol_flags, - &mut output_sections, - &mut layout_rules_builder, - loaded, - )?; - - // TODO: Doing this here means that we can't wrap symbols produced by the linker plugin. - // Moving it earlier or later however requires some rethought as to how this works. - symbol_db.apply_wrapped_symbol_overrides(); - - let mut resolver = resolution::Resolver::default(); - - resolver.resolve_symbols_and_select_archive_entries(&mut symbol_db)?; - - // Now that we know which archive entries are being loaded, we can resolve alternative - // symbol definitions. - crate::symbol_db::resolve_alternative_symbol_definitions( - &mut symbol_db, - &mut per_symbol_flags, - &resolver.resolved_groups, - )?; - - let layout = P::finish_link( - file_loader, - args, - &mut plugin, - symbol_db, - per_symbol_flags, - resolver, - output_sections, - layout_rules_builder, - output_kind, - )?; - - diff::maybe_diff()?; - - // We've finished linking. We consider everything from this point onwards as shutdown. - let (g1, g2) = timing_guard!("Shutdown"); - self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); - - Ok(layout) - } -} - -impl Default for Linker { - fn default() -> Self { - Self::new() - } -} - -impl Drop for Linker { - fn drop(&mut self) { - timing_phase!("Drop inputs"); - self.inputs_arena = Arena::new(); - self.herd = Default::default(); - } -} - -impl<'layout_inputs> Drop for LinkerOutput<'layout_inputs> { - fn drop(&mut self) { - timing_phase!("Drop layout"); - let _ = std::mem::swap(self, &mut LinkerOutput::None); - } -} - -/// Writes a dependency file in Makefile format. -fn write_dependency_file( - dep_file_path: &Path, - output_path: &Path, - loaded_files: &[&InputFile], -) -> std::io::Result<()> { - timing_phase!("Write dependency file"); - - let file = std::fs::File::create(dep_file_path)?; - let mut writer = BufWriter::new(file); - - // Collect unique dependency paths - let mut seen = std::collections::HashSet::new(); - let mut deps = Vec::new(); - for input_file in loaded_files { - // Skip temporary files. e.g. those generated by linker plugins. - if input_file.modifiers.temporary { - continue; - } - - let path_str = input_file.filename.display().to_string(); - if seen.insert(path_str.clone()) { - deps.push(path_str); - } - } - - write!(writer, "{}:", output_path.display())?; - - for dep in &deps { - write!(writer, " {dep}")?; - } - - writeln!(writer)?; - - for dep in &deps { - writeln!(writer, "\n{dep}:")?; - } - - Ok(()) -} - -/// Possibly initialise timing if a timing-related environment variable is active and it was enabled -/// in the build, otherwise, do nothing. See `BENCHMARKING.md` for details. -pub fn init_timing() -> Result { - timing::setup() -} +pub(crate) mod alignment; +pub(crate) mod arch; +pub(crate) mod archive; +pub mod args; +pub(crate) mod coff; +pub(crate) mod debug_trace; +pub(crate) mod diagnostics; +pub(crate) mod diff; +pub(crate) mod dwarf_address_info; +pub(crate) mod elf; +pub(crate) mod elf_aarch64; +pub(crate) mod elf_loongarch64; +pub(crate) mod elf_riscv64; +pub(crate) mod elf_writer; +pub(crate) mod elf_x86_64; +pub mod error; +pub(crate) mod export_list; +pub(crate) mod file_kind; +pub(crate) mod file_writer; +pub(crate) mod fs; +pub(crate) mod gc_stats; +pub(crate) mod grouping; +pub(crate) mod hash; +pub(crate) mod identity; +pub(crate) mod input_data; +pub(crate) mod layout; +pub(crate) mod layout_rules; +#[cfg_attr(not(feature = "plugins"), path = "linker_plugins_disabled.rs")] +mod linker_plugins; +pub(crate) mod linker_script; +pub(crate) mod output_kind; +pub(crate) mod output_section_id; +pub(crate) mod output_section_map; +pub(crate) mod output_section_part_map; +pub(crate) mod output_trace; +pub(crate) mod parsing; +pub(crate) mod part_id; +pub(crate) mod pe_writer; +#[cfg(all( + target_os = "linux", + any(target_arch = "x86_64", target_arch = "aarch64") +))] +pub(crate) mod perf; +#[cfg(any( + not(target_os = "linux"), + all( + target_os = "linux", + any(target_arch = "riscv64", target_arch = "loongarch64") + ) +))] +#[path = "perf_unsupported.rs"] +pub(crate) mod perf; +pub(crate) mod platform; +pub(crate) mod program_segments; +pub(crate) mod resolution; +pub(crate) mod save_dir; +pub(crate) mod sframe; +pub(crate) mod sharding; +pub(crate) mod string_merging; +#[cfg(feature = "fork")] +pub(crate) mod subprocess; +#[cfg(not(feature = "fork"))] +#[path = "subprocess_unsupported.rs"] +pub(crate) mod subprocess; +pub(crate) mod symbol; +pub(crate) mod symbol_db; +pub(crate) mod target_os; +pub(crate) mod timing; +pub(crate) mod validation; +pub(crate) mod value_flags; +pub(crate) mod verification; +pub(crate) mod version_script; + +use crate::args::ActivatedArgs; +use crate::error::Context; +use crate::error::Result; +use crate::identity::linker_identity; +use crate::layout_rules::LayoutRulesBuilder; +use crate::output_kind::OutputKind; +use crate::platform::ObjectFile; +use crate::platform::Platform; +use crate::value_flags::PerSymbolFlags; +pub use args::Args; +use colosseum::sync::Arena; +use crossbeam_utils::atomic::AtomicCell; +use error::AlreadyInitialised; +use input_data::FileLoader; +use input_data::InputFile; +use output_section_id::OutputSections; +use std::io::BufWriter; +use std::io::Write; +use std::path::Path; +pub use subprocess::run_in_subprocess; +use tracing_subscriber::EnvFilter; +use tracing_subscriber::fmt; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +/// Trait implemented by format-specific args types to dispatch linking by architecture. +pub(crate) trait TargetFormat: Send + Sync + 'static { + fn dispatch_link<'layout_inputs>( + linker: &'layout_inputs Linker, + args: &'layout_inputs Args, + ) -> error::Result> + where + Self: Sized; +} + +impl TargetFormat for args::linux::ElfArgs { + fn dispatch_link<'layout_inputs>( + linker: &'layout_inputs Linker, + args: &'layout_inputs Args, + ) -> error::Result> { + let res = match args.arch { + arch::Architecture::X86_64 => linker.link_for_arch::(args)?, + arch::Architecture::AArch64 => linker.link_for_arch::(args)?, + arch::Architecture::RISCV64 => linker.link_for_arch::(args)?, + arch::Architecture::LoongArch64 => { + linker.link_for_arch::(args)? + } + }; + Ok(match res { + Some(layout) => LinkerOutput::Elf(layout), + None => LinkerOutput::None, + }) + } +} + +impl TargetFormat for args::windows::PeArgs { + fn dispatch_link<'layout_inputs>( + linker: &'layout_inputs Linker, + args: &'layout_inputs Args, + ) -> error::Result> { + let res = match args.arch { + arch::Architecture::X86_64 | arch::Architecture::AArch64 => { + linker.link_for_arch::(args)? + } + other => { + bail!("PE format does not support architecture: {other}"); + } + }; + Ok(match res { + Some(layout) => LinkerOutput::Pe(layout), + None => LinkerOutput::None, + }) + } +} + +#[macro_export] +macro_rules! linker_run { + ($linker:ident, $args:ident, $after:expr) => { + use $crate::TargetFormat; + let args = $args.args; + match args.target_args { + $crate::args::TargetArgs::Elf(_) => { + let args = args.map_target(|t| match t { + $crate::args::TargetArgs::Elf(e) => e, + _ => unreachable!(), + }); + let res = $crate::args::linux::ElfArgs::dispatch_link(&$linker, &args)?; + $after(res); + } + $crate::args::TargetArgs::Pe(_) => { + let args = args.map_target(|t| match t { + $crate::args::TargetArgs::Pe(p) => p, + _ => unreachable!(), + }); + let res = $crate::args::windows::PeArgs::dispatch_link(&$linker, &args)?; + $after(res); + } + } + }; +} + +/// Runs the linker and cleans up associated resources. +pub fn run(args: args::Args) -> error::Result { + // Note, we need to setup tracing before we activate the thread pool. In particular, we need to + // initialise the timing module before the worker threads are started, otherwise the threads + // won't contribute to counters such as --time=cycles,instructions etc. + setup_tracing(&args)?; + let args = args.activate_thread_pool()?; + let linker = Linker::new(); + linker_run!(linker, args, |_| {}); + + drop(linker); + timing::finalise_perfetto_trace()?; + Ok(()) +} + +/// Sets up whatever tracing, if any, is indicated by the supplied arguments. This can only be +/// called once and only if nothing else has already set the global tracing dispatcher. Calling this +/// is optional. If it isn't called, no tracing-based features will function. e.g. --time. +pub fn setup_tracing(args: &args::Args) -> Result<(), AlreadyInitialised> { + if let Some(opts) = args.time_phase_options.as_ref() { + timing::init_tracing(opts) + } else if args.print_allocations.is_some() { + debug_trace::init() + } else { + tracing_subscriber::registry() + .with(fmt::layer()) + .with(EnvFilter::from_default_env()) + .try_init() + .map_err(|_| AlreadyInitialised) + } +} + +/// This is effectively a data store for use while linking. It takes ownership of all the input data +/// that we read, which allows the linking stages to borrow that data. Dropping this struct might be +/// expensive, so the caller of the linker might want to think about when best to drop it - probably +/// together with the `LinkerOutput`. Note, calling `exit` without dropping this struct is an +/// option, but likely won't save any time, since the bulk of the work done during drop (unmapping +/// pages) will still happen anyway. +pub struct Linker { + /// We store our input files here once we've read them. + pub(crate) inputs_arena: Arena, + + pub(crate) linker_plugin_arena: Arena, + + /// Anything that doesn't need a custom Drop implementation can go in here. In practice, it's + /// mostly just the decompressed copy of compressed string-merge sections. + pub(crate) herd: bumpalo_herd::Herd, + + /// We'll fill this in when we're done linking and start shutting down. Once this is dropped, + /// that signals the end of shutdown for the purposes of timing measurement. + #[allow(dyn_drop)] + shutdown_scope: AtomicCell>>, + + /// A timing scope that exists for the whole time we're linking. + #[allow(dyn_drop)] + _link_scope: Vec>, +} + +/// This is just here so that we defer its destruction. This allows us to (a) measure how long +/// it takes to drop and (b) if we forked, signal our parent that we're done, then drop it in +/// the background. +pub(crate) enum LinkerOutput<'layout_inputs> { + Elf(layout::Layout<'layout_inputs, crate::elf::File<'layout_inputs>>), + Pe(layout::Layout<'layout_inputs, crate::coff::CoffObjectFile<'layout_inputs>>), + None, +} + +impl Linker { + pub fn new() -> Self { + let (guard_a, guard_b) = timing_guard!("Link"); + + Self { + inputs_arena: Arena::new(), + linker_plugin_arena: Arena::new(), + herd: Default::default(), + shutdown_scope: Default::default(), + _link_scope: vec![Box::new(guard_a), Box::new(guard_b)], + } + } + + /// Runs the linker. Generic over the target format args type (ElfArgs or PeArgs). + /// The caller is responsible for mapping the args to the correct format type first. + pub(crate) fn run<'layout_inputs, T: TargetFormat>( + &'layout_inputs self, + args: &'layout_inputs ActivatedArgs, + ) -> error::Result> { + let args = &args.args; + match args.version_mode { + args::VersionMode::ExitAfterPrint => { + let mut stdout = std::io::stdout().lock(); + writeln!(stdout, "{}", linker_identity())?; + return Ok(LinkerOutput::None); + } + args::VersionMode::Verbose => { + let mut stdout = std::io::stdout().lock(); + writeln!(stdout, "{}", linker_identity())?; + // Continue linking + } + args::VersionMode::None => { + // Don't print version + } + } + + T::dispatch_link(self, args) + } + + fn link_for_arch<'layout_inputs, P: Platform<'layout_inputs>>( + &'layout_inputs self, + args: &'layout_inputs Args<>::Args>, + ) -> error::Result>> { + let mut file_loader = input_data::FileLoader::new(&self.inputs_arena); + + // Note, we propagate errors from `load_inputs_and_link` after we've checked if any files + // changed. We want inputs-changed errors to take precedence over all other errors. + let result = self.load_inputs_and_link::

(&mut file_loader, args); + + file_loader.verify_inputs_unchanged()?; + + // Write dependency file after successful linking + if result.is_ok() + && let Some(dep_file_path) = &args.dependency_file + { + write_dependency_file(dep_file_path, &args.output, &file_loader.loaded_files) + .with_context(|| { + format!( + "Failed to write dependency file `{}`", + dep_file_path.display() + ) + })?; + } + + result + } + + fn load_inputs_and_link<'layout_inputs, P: Platform<'layout_inputs>>( + &'layout_inputs self, + file_loader: &mut FileLoader<'layout_inputs>, + args: &'layout_inputs Args<>::Args>, + ) -> error::Result>> { + let mut plugin = P::create_plugin(self, args)?; + + let loaded = file_loader.load_inputs(&args.inputs, args, &mut plugin); + + args.save_dir.finish(file_loader, args)?; + + let loaded = loaded?; + + let output_kind = OutputKind::new(args, file_loader); + + let mut output_sections = OutputSections::with_base_address(output_kind.base_address()); + + let mut layout_rules_builder = LayoutRulesBuilder::default(); + + let auxiliary = input_data::AuxiliaryFiles::new(args, &self.inputs_arena)?; + + let mut symbol_db = symbol_db::SymbolDb::new(args, output_kind, &auxiliary, &self.herd)?; + let mut per_symbol_flags = PerSymbolFlags::new(); + + symbol_db.add_inputs( + &mut per_symbol_flags, + &mut output_sections, + &mut layout_rules_builder, + loaded, + )?; + + // TODO: Doing this here means that we can't wrap symbols produced by the linker plugin. + // Moving it earlier or later however requires some rethought as to how this works. + symbol_db.apply_wrapped_symbol_overrides(); + + let mut resolver = resolution::Resolver::default(); + + resolver.resolve_symbols_and_select_archive_entries(&mut symbol_db)?; + + // Now that we know which archive entries are being loaded, we can resolve alternative + // symbol definitions. + crate::symbol_db::resolve_alternative_symbol_definitions( + &mut symbol_db, + &mut per_symbol_flags, + &resolver.resolved_groups, + )?; + + let layout = P::finish_link( + file_loader, + args, + &mut plugin, + symbol_db, + per_symbol_flags, + resolver, + output_sections, + layout_rules_builder, + output_kind, + )?; + + diff::maybe_diff()?; + + // We've finished linking. We consider everything from this point onwards as shutdown. + let (g1, g2) = timing_guard!("Shutdown"); + self.shutdown_scope.store(vec![Box::new(g1), Box::new(g2)]); + + Ok(layout) + } +} + +impl Default for Linker { + fn default() -> Self { + Self::new() + } +} + +impl Drop for Linker { + fn drop(&mut self) { + timing_phase!("Drop inputs"); + self.inputs_arena = Arena::new(); + self.herd = Default::default(); + } +} + +impl<'layout_inputs> Drop for LinkerOutput<'layout_inputs> { + fn drop(&mut self) { + timing_phase!("Drop layout"); + let _ = std::mem::swap(self, &mut LinkerOutput::None); + } +} + +/// Writes a dependency file in Makefile format. +fn write_dependency_file( + dep_file_path: &Path, + output_path: &Path, + loaded_files: &[&InputFile], +) -> std::io::Result<()> { + timing_phase!("Write dependency file"); + + let file = std::fs::File::create(dep_file_path)?; + let mut writer = BufWriter::new(file); + + // Collect unique dependency paths + let mut seen = std::collections::HashSet::new(); + let mut deps = Vec::new(); + for input_file in loaded_files { + // Skip temporary files. e.g. those generated by linker plugins. + if input_file.modifiers.temporary { + continue; + } + + let path_str = input_file.filename.display().to_string(); + if seen.insert(path_str.clone()) { + deps.push(path_str); + } + } + + write!(writer, "{}:", output_path.display())?; + + for dep in &deps { + write!(writer, " {dep}")?; + } + + writeln!(writer)?; + + for dep in &deps { + writeln!(writer, "\n{dep}:")?; + } + + Ok(()) +} + +/// Possibly initialise timing if a timing-related environment variable is active and it was enabled +/// in the build, otherwise, do nothing. See `BENCHMARKING.md` for details. +pub fn init_timing() -> Result { + timing::setup() +} diff --git a/libwild/src/parsing.rs b/libwild/src/parsing.rs index 01f8c51ad..72fa495d4 100644 --- a/libwild/src/parsing.rs +++ b/libwild/src/parsing.rs @@ -1,318 +1,318 @@ -use crate::OutputKind; -use crate::OutputSections; -use crate::args::Args; -use crate::args::DefsymValue; -use crate::args::Modifiers; -use crate::error::Context as _; -use crate::error::Result; -use crate::input_data::FileId; -use crate::input_data::InputBytes; -use crate::input_data::InputLinkerScript; -use crate::input_data::InputRef; -use crate::layout_rules::LayoutRulesBuilder; -use crate::output_section_id::OutputSectionId; -use crate::platform::ObjectFile; -use crate::symbol::UnversionedSymbolName; -use crate::symbol_db::SymbolId; -use crate::symbol_db::SymbolIdRange; -use crate::timing_phase; -use crate::verbose_timing_phase; -use linker_utils::elf::SymbolType; -use linker_utils::elf::stt; - -pub(crate) fn process_linker_scripts<'data>( - linker_scripts_in: &[InputLinkerScript<'data>], - output_sections: &mut OutputSections<'data>, - layout_rules_builder: &mut LayoutRulesBuilder<'data>, -) -> Result>> { - timing_phase!("Process linker scripts"); - - linker_scripts_in - .iter() - .map(|script| layout_rules_builder.process_linker_script(script, output_sections)) - .collect::>>() -} - -#[derive(Debug)] -pub(crate) struct Prelude<'data> { - pub(crate) symbol_definitions: Vec>, -} - -#[derive(Debug)] -pub(crate) struct ParsedInputObject<'data, O: ObjectFile<'data>> { - pub(crate) input: InputRef<'data>, - pub(crate) object: O, - pub(crate) modifiers: Modifiers, -} - -#[derive(Debug)] -pub(crate) struct ProcessedLinkerScript<'data> { - pub(crate) input: InputRef<'data>, - pub(crate) symbol_defs: Vec>, -} - -#[derive(Debug)] -pub(crate) struct SyntheticSymbols { - pub(crate) file_id: FileId, - pub(crate) symbol_id_range: SymbolIdRange, -} - -#[derive(Clone, Copy, derive_more::Debug)] -pub(crate) struct InternalSymDefInfo<'data> { - pub(crate) placement: SymbolPlacement<'data>, - #[debug("{:?}", String::from_utf8_lossy(name))] - pub(crate) name: &'data [u8], - pub(crate) elf_symbol_type: SymbolType, - /// If true, this symbol should have hidden visibility (from PROVIDE_HIDDEN). - pub(crate) is_hidden: bool, -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub(crate) enum SymbolPlacement<'data> { - /// Symbol 0 - the undefined symbol. - Undefined, - - /// Defines a symbol that points to the start of a section. - SectionStart(OutputSectionId), - - /// Defines a symbol that points at the non-inclusive end of the section. i.e. 1 byte past the - /// last byte of the section. - SectionEnd(OutputSectionId), - - /// Where secondary sections are merged into a primary section, this causes our symbol to point - /// to the non-inclusive end of the last section merged into the specified primary. - SectionGroupEnd(OutputSectionId), - - /// An undefined symbol supplied by the user, e.g. via `--undefined=symbol-name`. - ForceUndefined, - - /// A symbol defined via --defsym with an absolute address. - DefsymAbsolute(u64), - - /// A symbol defined via --defsym that references another symbol. - /// Stores the name of the target symbol and an optional offset to add to its value. - DefsymSymbol(&'data str, i64), - - /// Symbol will point to the start of the first loadable segment. - LoadBaseAddress, -} - -/// Result of parsing a defsym-style expression like "0x1000", "symbol", or "symbol+0x40". -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(crate) enum ParsedSymbolExpression<'a> { - /// An absolute numeric value. - Absolute(u64), - /// A symbol reference with an optional offset. - SymbolWithOffset(&'a str, i64), -} - -impl<'a> ParsedSymbolExpression<'a> { - pub(crate) fn to_placement(self) -> SymbolPlacement<'a> { - match self { - ParsedSymbolExpression::Absolute(value) => SymbolPlacement::DefsymAbsolute(value), - ParsedSymbolExpression::SymbolWithOffset(sym, offset) => { - SymbolPlacement::DefsymSymbol(sym, offset) - } - } - } -} - -pub fn parse_symbol_expression(s: &str) -> ParsedSymbolExpression<'_> { - let mut symbol = None; - let mut offset: i64 = 0; - let mut token_start = 0; - let mut current_sign: i64 = 1; - - // Handle leading sign - if s.starts_with('-') { - current_sign = -1; - token_start = 1; - } else if s.starts_with('+') { - token_start = 1; - } - - for (i, ch) in s.bytes().enumerate().skip(token_start) { - if ch == b'+' || ch == b'-' { - let token = s[token_start..i].trim(); - if let Ok(val) = parse_number(token) { - offset = offset.wrapping_add(current_sign * val as i64); - } else if symbol.is_none() && !token.is_empty() { - symbol = Some(token); - } - current_sign = if ch == b'+' { 1 } else { -1 }; - token_start = i + 1; - } - } - - // Process the last token - let token = s[token_start..].trim(); - if let Ok(val) = parse_number(token) { - offset = offset.wrapping_add(current_sign * val as i64); - } else if symbol.is_none() && !token.is_empty() { - symbol = Some(token); - } - - match symbol { - Some(sym) => ParsedSymbolExpression::SymbolWithOffset(sym, offset), - None => ParsedSymbolExpression::Absolute(offset as u64), - } -} - -/// Parse a number. Interprets 0x prefix as hex, otherwise as decimal. -pub(crate) fn parse_number(s: &str) -> Result { - if let Some(hex) = s.strip_prefix("0x") { - u64::from_str_radix(hex, 16).map_err(|_| ()) - } else { - s.parse::().map_err(|_| ()) - } -} - -impl<'data> InternalSymDefInfo<'data> { - pub(crate) fn new(placement: SymbolPlacement<'data>, name: &'data [u8]) -> Self { - Self { - placement, - name, - elf_symbol_type: stt::NOTYPE, - is_hidden: false, - } - } - - pub(crate) fn with_hidden(self, hidden: bool) -> Self { - Self { - is_hidden: hidden, - ..self - } - } - - pub(crate) fn hide(&mut self) -> &mut Self { - self.is_hidden = true; - self - } -} - -impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { - pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { - verbose_timing_phase!("Parse file"); - - let object = O::parse(input, args) - .with_context(|| format!("Failed to parse object file `{input}`"))?; - - Ok(Box::new(Self { - input: input.input, - object, - modifiers: input.modifiers, - })) - } - - pub(crate) fn is_dynamic(&self) -> bool { - self.object.is_dynamic() - } - - pub(crate) fn num_symbols(&self) -> usize { - self.object.num_symbols() - } -} - -impl<'data> Prelude<'data> { - pub(crate) fn new>(args: &'data Args, output_kind: OutputKind) -> Self { - verbose_timing_phase!("Construct prelude"); - - let mut symbols = InternalSymbolsBuilder::default(); - - O::create_linker_defined_symbols(&mut symbols, output_kind); - - args.undefined.iter().for_each(|name| { - symbols.add_symbol(InternalSymDefInfo::new( - SymbolPlacement::ForceUndefined, - name.as_bytes(), - )); - }); - - // Add symbols defined via --defsym - args.defsym.iter().for_each(|(name, value)| { - let placement = match value { - DefsymValue::Value(addr) => SymbolPlacement::DefsymAbsolute(*addr), - DefsymValue::SymbolWithOffset(target, offset) => { - SymbolPlacement::DefsymSymbol(target.as_str(), *offset) - } - }; - symbols.add_symbol(InternalSymDefInfo::new(placement, name.as_bytes())); - }); - - Self { - symbol_definitions: symbols.symbol_definitions, - } - } - - pub(crate) fn symbol_name(&self, symbol_id: SymbolId) -> UnversionedSymbolName<'data> { - let def = &self.symbol_definitions[symbol_id.as_usize()]; - UnversionedSymbolName::new(def.name) - } -} - -#[derive(Default)] -pub(crate) struct InternalSymbolsBuilder<'data> { - symbol_definitions: Vec>, -} - -impl<'data> InternalSymbolsBuilder<'data> { - pub(crate) fn add_symbol( - &mut self, - def: InternalSymDefInfo<'data>, - ) -> &mut InternalSymDefInfo<'data> { - let index = self.symbol_definitions.len(); - self.symbol_definitions.push(def); - &mut self.symbol_definitions[index] - } - - pub(crate) fn section_start( - &mut self, - section_id: OutputSectionId, - name: &'static str, - ) -> &mut InternalSymDefInfo<'data> { - self.add_symbol(InternalSymDefInfo::new( - SymbolPlacement::SectionStart(section_id), - name.as_bytes(), - )) - } - - pub(crate) fn section_end( - &mut self, - section_id: OutputSectionId, - name: &'static str, - ) -> &mut InternalSymDefInfo<'data> { - self.add_symbol(InternalSymDefInfo::new( - SymbolPlacement::SectionEnd(section_id), - name.as_bytes(), - )) - } - - pub(crate) fn section_group_end( - &mut self, - section_id: OutputSectionId, - name: &'static str, - ) -> &mut InternalSymDefInfo<'data> { - self.add_symbol(InternalSymDefInfo::new( - SymbolPlacement::SectionGroupEnd(section_id), - name.as_bytes(), - )) - } -} - -impl<'data> ProcessedLinkerScript<'data> { - pub(crate) fn num_symbols(&self) -> usize { - self.symbol_defs.len() - } -} - -impl<'data, O: ObjectFile<'data>> std::fmt::Display for ParsedInputObject<'data, O> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f) - } -} - -impl std::fmt::Display for ProcessedLinkerScript<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f) - } -} +use crate::OutputKind; +use crate::OutputSections; +use crate::args::Args; +use crate::args::DefsymValue; +use crate::args::Modifiers; +use crate::error::Context as _; +use crate::error::Result; +use crate::input_data::FileId; +use crate::input_data::InputBytes; +use crate::input_data::InputLinkerScript; +use crate::input_data::InputRef; +use crate::layout_rules::LayoutRulesBuilder; +use crate::output_section_id::OutputSectionId; +use crate::platform::ObjectFile; +use crate::symbol::UnversionedSymbolName; +use crate::symbol_db::SymbolId; +use crate::symbol_db::SymbolIdRange; +use crate::timing_phase; +use crate::verbose_timing_phase; +use linker_utils::elf::SymbolType; +use linker_utils::elf::stt; + +pub(crate) fn process_linker_scripts<'data>( + linker_scripts_in: &[InputLinkerScript<'data>], + output_sections: &mut OutputSections<'data>, + layout_rules_builder: &mut LayoutRulesBuilder<'data>, +) -> Result>> { + timing_phase!("Process linker scripts"); + + linker_scripts_in + .iter() + .map(|script| layout_rules_builder.process_linker_script(script, output_sections)) + .collect::>>() +} + +#[derive(Debug)] +pub(crate) struct Prelude<'data> { + pub(crate) symbol_definitions: Vec>, +} + +#[derive(Debug)] +pub(crate) struct ParsedInputObject<'data, O: ObjectFile<'data>> { + pub(crate) input: InputRef<'data>, + pub(crate) object: O, + pub(crate) modifiers: Modifiers, +} + +#[derive(Debug)] +pub(crate) struct ProcessedLinkerScript<'data> { + pub(crate) input: InputRef<'data>, + pub(crate) symbol_defs: Vec>, +} + +#[derive(Debug)] +pub(crate) struct SyntheticSymbols { + pub(crate) file_id: FileId, + pub(crate) symbol_id_range: SymbolIdRange, +} + +#[derive(Clone, Copy, derive_more::Debug)] +pub(crate) struct InternalSymDefInfo<'data> { + pub(crate) placement: SymbolPlacement<'data>, + #[debug("{:?}", String::from_utf8_lossy(name))] + pub(crate) name: &'data [u8], + pub(crate) elf_symbol_type: SymbolType, + /// If true, this symbol should have hidden visibility (from PROVIDE_HIDDEN). + pub(crate) is_hidden: bool, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub(crate) enum SymbolPlacement<'data> { + /// Symbol 0 - the undefined symbol. + Undefined, + + /// Defines a symbol that points to the start of a section. + SectionStart(OutputSectionId), + + /// Defines a symbol that points at the non-inclusive end of the section. i.e. 1 byte past the + /// last byte of the section. + SectionEnd(OutputSectionId), + + /// Where secondary sections are merged into a primary section, this causes our symbol to point + /// to the non-inclusive end of the last section merged into the specified primary. + SectionGroupEnd(OutputSectionId), + + /// An undefined symbol supplied by the user, e.g. via `--undefined=symbol-name`. + ForceUndefined, + + /// A symbol defined via --defsym with an absolute address. + DefsymAbsolute(u64), + + /// A symbol defined via --defsym that references another symbol. + /// Stores the name of the target symbol and an optional offset to add to its value. + DefsymSymbol(&'data str, i64), + + /// Symbol will point to the start of the first loadable segment. + LoadBaseAddress, +} + +/// Result of parsing a defsym-style expression like "0x1000", "symbol", or "symbol+0x40". +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum ParsedSymbolExpression<'a> { + /// An absolute numeric value. + Absolute(u64), + /// A symbol reference with an optional offset. + SymbolWithOffset(&'a str, i64), +} + +impl<'a> ParsedSymbolExpression<'a> { + pub(crate) fn to_placement(self) -> SymbolPlacement<'a> { + match self { + ParsedSymbolExpression::Absolute(value) => SymbolPlacement::DefsymAbsolute(value), + ParsedSymbolExpression::SymbolWithOffset(sym, offset) => { + SymbolPlacement::DefsymSymbol(sym, offset) + } + } + } +} + +pub fn parse_symbol_expression(s: &str) -> ParsedSymbolExpression<'_> { + let mut symbol = None; + let mut offset: i64 = 0; + let mut token_start = 0; + let mut current_sign: i64 = 1; + + // Handle leading sign + if s.starts_with('-') { + current_sign = -1; + token_start = 1; + } else if s.starts_with('+') { + token_start = 1; + } + + for (i, ch) in s.bytes().enumerate().skip(token_start) { + if ch == b'+' || ch == b'-' { + let token = s[token_start..i].trim(); + if let Ok(val) = parse_number(token) { + offset = offset.wrapping_add(current_sign * val as i64); + } else if symbol.is_none() && !token.is_empty() { + symbol = Some(token); + } + current_sign = if ch == b'+' { 1 } else { -1 }; + token_start = i + 1; + } + } + + // Process the last token + let token = s[token_start..].trim(); + if let Ok(val) = parse_number(token) { + offset = offset.wrapping_add(current_sign * val as i64); + } else if symbol.is_none() && !token.is_empty() { + symbol = Some(token); + } + + match symbol { + Some(sym) => ParsedSymbolExpression::SymbolWithOffset(sym, offset), + None => ParsedSymbolExpression::Absolute(offset as u64), + } +} + +/// Parse a number. Interprets 0x prefix as hex, otherwise as decimal. +pub(crate) fn parse_number(s: &str) -> Result { + if let Some(hex) = s.strip_prefix("0x") { + u64::from_str_radix(hex, 16).map_err(|_| ()) + } else { + s.parse::().map_err(|_| ()) + } +} + +impl<'data> InternalSymDefInfo<'data> { + pub(crate) fn new(placement: SymbolPlacement<'data>, name: &'data [u8]) -> Self { + Self { + placement, + name, + elf_symbol_type: stt::NOTYPE, + is_hidden: false, + } + } + + pub(crate) fn with_hidden(self, hidden: bool) -> Self { + Self { + is_hidden: hidden, + ..self + } + } + + pub(crate) fn hide(&mut self) -> &mut Self { + self.is_hidden = true; + self + } +} + +impl<'data, O: ObjectFile<'data>> ParsedInputObject<'data, O> { + pub(crate) fn new(input: &InputBytes<'data>, args: &Args) -> Result> { + verbose_timing_phase!("Parse file"); + + let object = O::parse(input, args) + .with_context(|| format!("Failed to parse object file `{input}`"))?; + + Ok(Box::new(Self { + input: input.input, + object, + modifiers: input.modifiers, + })) + } + + pub(crate) fn is_dynamic(&self) -> bool { + self.object.is_dynamic() + } + + pub(crate) fn num_symbols(&self) -> usize { + self.object.num_symbols() + } +} + +impl<'data> Prelude<'data> { + pub(crate) fn new>(args: &'data Args, output_kind: OutputKind) -> Self { + verbose_timing_phase!("Construct prelude"); + + let mut symbols = InternalSymbolsBuilder::default(); + + O::create_linker_defined_symbols(&mut symbols, output_kind); + + args.undefined.iter().for_each(|name| { + symbols.add_symbol(InternalSymDefInfo::new( + SymbolPlacement::ForceUndefined, + name.as_bytes(), + )); + }); + + // Add symbols defined via --defsym + args.defsym.iter().for_each(|(name, value)| { + let placement = match value { + DefsymValue::Value(addr) => SymbolPlacement::DefsymAbsolute(*addr), + DefsymValue::SymbolWithOffset(target, offset) => { + SymbolPlacement::DefsymSymbol(target.as_str(), *offset) + } + }; + symbols.add_symbol(InternalSymDefInfo::new(placement, name.as_bytes())); + }); + + Self { + symbol_definitions: symbols.symbol_definitions, + } + } + + pub(crate) fn symbol_name(&self, symbol_id: SymbolId) -> UnversionedSymbolName<'data> { + let def = &self.symbol_definitions[symbol_id.as_usize()]; + UnversionedSymbolName::new(def.name) + } +} + +#[derive(Default)] +pub(crate) struct InternalSymbolsBuilder<'data> { + symbol_definitions: Vec>, +} + +impl<'data> InternalSymbolsBuilder<'data> { + pub(crate) fn add_symbol( + &mut self, + def: InternalSymDefInfo<'data>, + ) -> &mut InternalSymDefInfo<'data> { + let index = self.symbol_definitions.len(); + self.symbol_definitions.push(def); + &mut self.symbol_definitions[index] + } + + pub(crate) fn section_start( + &mut self, + section_id: OutputSectionId, + name: &'static str, + ) -> &mut InternalSymDefInfo<'data> { + self.add_symbol(InternalSymDefInfo::new( + SymbolPlacement::SectionStart(section_id), + name.as_bytes(), + )) + } + + pub(crate) fn section_end( + &mut self, + section_id: OutputSectionId, + name: &'static str, + ) -> &mut InternalSymDefInfo<'data> { + self.add_symbol(InternalSymDefInfo::new( + SymbolPlacement::SectionEnd(section_id), + name.as_bytes(), + )) + } + + pub(crate) fn section_group_end( + &mut self, + section_id: OutputSectionId, + name: &'static str, + ) -> &mut InternalSymDefInfo<'data> { + self.add_symbol(InternalSymDefInfo::new( + SymbolPlacement::SectionGroupEnd(section_id), + name.as_bytes(), + )) + } +} + +impl<'data> ProcessedLinkerScript<'data> { + pub(crate) fn num_symbols(&self) -> usize { + self.symbol_defs.len() + } +} + +impl<'data, O: ObjectFile<'data>> std::fmt::Display for ParsedInputObject<'data, O> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f) + } +} + +impl std::fmt::Display for ProcessedLinkerScript<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f) + } +} diff --git a/libwild/src/platform.rs b/libwild/src/platform.rs index aaa7123ba..403d546e0 100644 --- a/libwild/src/platform.rs +++ b/libwild/src/platform.rs @@ -40,14 +40,14 @@ pub(crate) trait Platform<'data>: 'data { fn create_plugin( _linker: &'data crate::Linker, - _args: &'data Args<>::ArgsType>, + _args: &'data Args<>::Args>, ) -> crate::Result>> { Ok(None) } fn finish_link( file_loader: &mut crate::input_data::FileLoader<'data>, - args: &'data Args<>::ArgsType>, + args: &'data Args<>::Args>, plugin: &mut Option>, symbol_db: crate::symbol_db::SymbolDb<'data, Self::File>, per_symbol_flags: crate::value_flags::PerSymbolFlags, @@ -189,7 +189,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat type CommonGroupStateExt: Default + std::fmt::Debug + Send + Sync + 'static; type LayoutResourcesExt: std::fmt::Debug + Send + Sync + 'data; type ProgramSegmentDef: ProgramSegmentDef; - type ArgsType: Send + Sync + 'static; + type Args: Send + Sync + 'static; /// An index into the local object's symbol versions. type SymbolVersionIndex: Send + Sync + Copy; @@ -210,7 +210,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// As for `parse_bytes` but also validates that the file architecture matches what is expected /// based on `args`. - fn parse(input: &InputBytes<'data>, args: &Args) -> Result; + fn parse(input: &InputBytes<'data>, args: &Args) -> Result; fn is_dynamic(&self) -> bool; @@ -294,7 +294,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Self::DynamicLayout; fn new_epilogue_layout( - args: &Args, + args: &Args, output_kind: OutputKind, dynamic_symbol_definitions: &mut [DynamicSymbolDefinition<'_>], ) -> Self::EpilogueLayout; @@ -396,7 +396,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat ) -> Result; fn create_layout_properties<'states, 'files, P: Platform<'data, File = Self>>( - args: &Args, + args: &Args, objects: impl Iterator, states: impl Iterator + Clone, ) -> Result @@ -429,7 +429,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// Called after GC phase has completed. Mostly useful for platform-specific logging. fn finalise_find_required_sections(groups: &[layout::GroupState<'data, Self>]); - fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState<'data, Self>, args: &Args); + fn pre_finalise_sizes_prelude(common: &mut layout::CommonGroupState<'data, Self>, args: &Args); fn finalise_object_sizes( object: &mut layout::ObjectLayoutState<'data, Self>, @@ -512,7 +512,7 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat fn update_segment_keep_list( program_segments: &ProgramSegments, keep_segments: &mut [bool], - args: &Args, + args: &Args, ); fn program_segment_defs() -> &'static [Self::ProgramSegmentDef]; @@ -527,24 +527,24 @@ pub(crate) trait ObjectFile<'data>: Send + Sync + Sized + std::fmt::Debug + 'dat /// Implementations can force certain sections to be kept. Only needs to be done for sections /// that need to be emitted even if empty. - fn apply_force_keep_sections(keep_sections: &mut OutputSectionMap, args: &Args); + fn apply_force_keep_sections(keep_sections: &mut OutputSectionMap, args: &Args); /// Returns whether an input section with zero size destined for the specified output section /// should be considered content and thus prevent the output section from being discarded. fn is_zero_sized_section_content(section_id: OutputSectionId) -> bool; /// Whether to emit GOT/PLT symbol entries in the local symtab. - fn wants_got_plt_syms(_args: &Args) -> bool { + fn wants_got_plt_syms(_args: &Args) -> bool { false } /// Returns the stack size for the STACK segment. - fn stack_size(_args: &Args) -> u64 { + fn stack_size(_args: &Args) -> u64 { 0 } /// Whether the hash style includes sysv. - fn hash_includes_sysv(_args: &Args) -> bool { + fn hash_includes_sysv(_args: &Args) -> bool { false } } diff --git a/libwild/src/resolution.rs b/libwild/src/resolution.rs index d094304d7..698391f52 100644 --- a/libwild/src/resolution.rs +++ b/libwild/src/resolution.rs @@ -1,1525 +1,1525 @@ -//! This module resolves symbol references between objects. In the process, it decides which archive -//! entries are needed. We also resolve which output section, if any, each input section should be -//! assigned to. - -use crate::layout_rules::LayoutRules; -use crate::alignment::Alignment; -use crate::args::Args; -use crate::bail; -use crate::debug_assert_bail; -use crate::elf::RawSymbolName; -use crate::error::Context as _; -use crate::error::Error; -use crate::error::Result; -use crate::grouping::Group; -use crate::grouping::SequencedInputObject; -use crate::hash::PassThroughHashMap; -use crate::hash::PreHashed; -use crate::input_data::FileId; -use crate::input_data::InputRef; -use crate::input_data::PRELUDE_FILE_ID; -use crate::layout_rules::SectionRuleOutcome; -use crate::layout_rules::SectionRules; -use crate::output_section_id::CustomSectionDetails; -use crate::output_section_id::InitFiniSectionDetail; -use crate::output_section_id::OutputSections; -use crate::output_section_id::SectionName; -use crate::parsing::InternalSymDefInfo; -use crate::parsing::SymbolPlacement; -use crate::part_id; -use crate::part_id::PartId; -use crate::platform::DynamicTagValues as _; -use crate::platform::FrameIndex; -use crate::platform::ObjectFile; -use crate::platform::RawSymbolName as _; -use crate::platform::SectionFlags as _; -use crate::platform::SectionHeader as _; -use crate::platform::SectionType as _; -use crate::platform::Symbol as _; -use crate::platform::VerneedTable as _; -use crate::string_merging::StringMergeSectionExtra; -use crate::string_merging::StringMergeSectionSlot; -use crate::symbol::PreHashedSymbolName; -use crate::symbol::UnversionedSymbolName; -use crate::symbol::VersionedSymbolName; -use crate::symbol_db; -use crate::symbol_db::SymbolDb; -use crate::symbol_db::SymbolId; -use crate::symbol_db::SymbolIdRange; -use crate::symbol_db::SymbolStrength; -use crate::symbol_db::Visibility; -use crate::timing_phase; -use crate::value_flags::PerSymbolFlags; -use crate::value_flags::ValueFlags; -use crate::verbose_timing_phase; -use atomic_take::AtomicTake; -use crossbeam_queue::ArrayQueue; -use crossbeam_queue::SegQueue; -use linker_utils::elf::secnames; -use object::SectionIndex; -use rayon::Scope; -use rayon::iter::IntoParallelIterator; -use rayon::iter::IntoParallelRefMutIterator; -use rayon::iter::ParallelIterator; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; - -pub(crate) struct Resolver<'data, O: ObjectFile<'data>> { - undefined_symbols: Vec>, - pub(crate) resolved_groups: Vec>, -} - -impl<'data, O: ObjectFile<'data>> Resolver<'data, O> { - /// Resolves undefined symbols. In the process of resolving symbols, we decide which archive - /// entries to load. Some symbols may not have definitions, in which case we'll note those for - /// later processing. Can be called multiple times with additional groups having been added to - /// the SymbolDb in between. - pub(crate) fn resolve_symbols_and_select_archive_entries( - &mut self, - symbol_db: &mut SymbolDb<'data, O>, - ) -> Result { - resolve_symbols_and_select_archive_entries(self, symbol_db) - } - - /// For all regular objects that we've decided to load, decide what to do with each section. - /// Canonicalises undefined symbols. Some undefined symbols might be able to become defined if - /// we can identify them as start/stop symbols for which we found a custom section with the - /// appropriate name. - pub(crate) fn resolve_sections_and_canonicalise_undefined( - mut self, - symbol_db: &mut SymbolDb<'data, O>, - per_symbol_flags: &mut PerSymbolFlags, - output_sections: &mut OutputSections<'data>, - layout_rules: &LayoutRules<'data>, - ) -> Result>> { - timing_phase!("Section resolution"); - - resolve_sections(&mut self.resolved_groups, symbol_db, layout_rules)?; - - let mut syn = symbol_db.new_synthetic_symbols_group(); - - assign_section_ids(&mut self.resolved_groups, output_sections, symbol_db.args); - - canonicalise_undefined_symbols( - self.undefined_symbols, - output_sections, - &self.resolved_groups, - symbol_db, - per_symbol_flags, - &mut syn, - ); - - self.resolved_groups.push(ResolvedGroup { - files: vec![ResolvedFile::SyntheticSymbols(syn)], - }); - - Ok(self.resolved_groups) - } -} - -fn resolve_symbols_and_select_archive_entries<'data, O: ObjectFile<'data>>( - resolver: &mut Resolver<'data, O>, - symbol_db: &mut SymbolDb<'data, O>, -) -> Result { - timing_phase!("Resolve symbols"); - - // Note, this is the total number of objects including those that we might have processed in - // previous calls. This is just an upper bound on how many objects might need to be loaded. We - // can't just count the objects in the new groups because we might end up loading some of the - // objects from earlier groups. - let num_regular_objects = symbol_db.num_regular_objects(); - let num_lto_objects = symbol_db.num_lto_objects(); - if num_regular_objects == 0 && num_lto_objects == 0 { - bail!("no input files"); - } - - let mut symbol_definitions = symbol_db.take_definitions(); - let mut symbol_definitions_slice: &mut [SymbolId] = symbol_definitions.as_mut(); - - let mut definitions_per_group_and_file = Vec::new(); - definitions_per_group_and_file.resize_with(symbol_db.groups.len(), Vec::new); - - let outputs = { - verbose_timing_phase!("Allocate outputs store"); - Outputs::new(num_regular_objects, num_lto_objects) - }; - - let mut initial_work = Vec::new(); - - { - verbose_timing_phase!("Resolution setup"); - - let pre_existing_groups = resolver.resolved_groups.len(); - let new_groups = &symbol_db.groups[pre_existing_groups..]; - - for (group, definitions_out_per_file) in resolver - .resolved_groups - .iter() - .zip(&mut definitions_per_group_and_file) - { - *definitions_out_per_file = group - .files - .iter() - .map(|file| { - let definitions = symbol_definitions_slice - .split_off_mut(..file.symbol_id_range().len()) - .unwrap(); - - if matches!(file, ResolvedFile::NotLoaded(_)) { - AtomicTake::new(definitions) - } else { - AtomicTake::empty() - } - }) - .collect(); - } - - resolver.resolved_groups.extend( - new_groups - .iter() - .zip(&mut definitions_per_group_and_file[pre_existing_groups..]) - .map(|(group, definitions_out_per_file)| { - resolve_group( - group, - &mut initial_work, - definitions_out_per_file, - &mut symbol_definitions_slice, - symbol_db, - &outputs, - ) - }), - ); - }; - - let resources = ResolutionResources { - definitions_per_file: &definitions_per_group_and_file, - symbol_db, - outputs: &outputs, - }; - - rayon::in_place_scope(|scope| { - initial_work.into_par_iter().for_each(|work_item| { - process_object(work_item, &resources, scope); - }); - }); - - { - verbose_timing_phase!("Drop definitions_per_group_and_file"); - drop(definitions_per_group_and_file); - } - - symbol_db.restore_definitions(symbol_definitions); - - if let Some(e) = outputs.errors.pop() { - return Err(e); - } - - verbose_timing_phase!("Gather loaded objects"); - - for obj in outputs.loaded { - let file_id = match &obj { - ResolvedFile::Object(o) => o.common.file_id, - ResolvedFile::Dynamic(o) => o.common.file_id, - _ => unreachable!(), - }; - resolver.resolved_groups[file_id.group()].files[file_id.file()] = obj; - } - - #[cfg(feature = "plugins")] - for obj in outputs.loaded_lto_objects { - let file_id = obj.file_id; - resolver.resolved_groups[file_id.group()].files[file_id.file()] = - ResolvedFile::LtoInput(obj); - } - - resolver.undefined_symbols.extend(outputs.undefined_symbols); - - Ok(()) -} - -fn resolve_group<'data, 'definitions, O: ObjectFile<'data>>( - group: &Group<'data, O>, - initial_work_out: &mut Vec>, - definitions_out_per_file: &mut Vec>, - symbol_definitions_slice: &mut &'definitions mut [SymbolId], - symbol_db: &SymbolDb<'data, O>, - outputs: &Outputs<'data, O>, -) -> ResolvedGroup<'data, O> { - match group { - Group::Prelude(prelude) => { - let definitions_out = symbol_definitions_slice - .split_off_mut(..prelude.symbol_definitions.len()) - .unwrap(); - - work_items_do( - PRELUDE_FILE_ID, - definitions_out, - symbol_db, - outputs, - |work_item| { - initial_work_out.push(work_item); - }, - ); - - definitions_out_per_file.push(AtomicTake::empty()); - - ResolvedGroup { - files: vec![ResolvedFile::Prelude(ResolvedPrelude { - symbol_definitions: prelude.symbol_definitions.clone(), - })], - } - } - Group::Objects(parsed_input_objects) => { - definitions_out_per_file.reserve(parsed_input_objects.len()); - - let files = parsed_input_objects - .iter() - .map(|s| { - let definitions_out = symbol_definitions_slice - .split_off_mut(..s.symbol_id_range.len()) - .unwrap(); - - if s.is_optional() { - definitions_out_per_file.push(AtomicTake::new(definitions_out)); - } else { - work_items_do( - s.file_id, - definitions_out, - symbol_db, - outputs, - |work_item| { - initial_work_out.push(work_item); - }, - ); - definitions_out_per_file.push(AtomicTake::empty()); - } - - ResolvedFile::NotLoaded(NotLoaded { - symbol_id_range: s.symbol_id_range, - }) - }) - .collect(); - - ResolvedGroup { files } - } - Group::LinkerScripts(scripts) => { - let files = scripts - .iter() - .map(|s| { - definitions_out_per_file.push(AtomicTake::empty()); - - ResolvedFile::LinkerScript(ResolvedLinkerScript { - input: s.parsed.input, - file_id: s.file_id, - symbol_id_range: s.symbol_id_range, - // TODO: Consider alternative to cloning this. - symbol_definitions: s.parsed.symbol_defs.clone(), - }) - }) - .collect(); - - ResolvedGroup { files } - } - Group::SyntheticSymbols(syn) => { - definitions_out_per_file.push(AtomicTake::empty()); - - ResolvedGroup { - files: vec![ResolvedFile::SyntheticSymbols(ResolvedSyntheticSymbols { - file_id: syn.file_id, - start_symbol_id: syn.symbol_id_range.start(), - symbol_definitions: Vec::new(), - })], - } - } - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => ResolvedGroup { - files: lto_objects - .iter() - .map(|o| { - let definitions_out = symbol_definitions_slice - .split_off_mut(..o.symbol_id_range.len()) - .unwrap(); - - if o.is_optional() { - definitions_out_per_file.push(AtomicTake::new(definitions_out)); - } else { - work_items_do( - o.file_id, - definitions_out, - symbol_db, - outputs, - |work_item| { - initial_work_out.push(work_item); - }, - ); - definitions_out_per_file.push(AtomicTake::empty()); - } - - ResolvedFile::NotLoaded(NotLoaded { - symbol_id_range: o.symbol_id_range, - }) - }) - .collect(), - }, - } -} - -fn resolve_sections<'data, O: ObjectFile<'data>>( - groups: &mut [ResolvedGroup<'data, O>], - symbol_db: &SymbolDb<'data, O>, - layout_rules: &LayoutRules<'data>, -) -> Result { - timing_phase!("Resolve sections"); - - let loaded_metrics: LoadedMetrics = Default::default(); - let herd = symbol_db.herd; - - groups.par_iter_mut().try_for_each_init( - || herd.get(), - |allocator, group| -> Result { - verbose_timing_phase!("Resolve group sections"); - - for file in &mut group.files { - let ResolvedFile::::Object(obj) = file else { - continue; - }; - - obj.sections = resolve_sections_for_object( - obj, - symbol_db.args, - allocator, - &loaded_metrics, - &layout_rules.section_rules, - )?; - - obj.relocations = obj.common.object.parse_relocations()?; - } - Ok(()) - }, - )?; - - loaded_metrics.log(); - - Ok(()) -} - -const MAX_SYMBOLS_PER_WORK_ITEM: usize = 5000; - -/// A request to load a chunk of symbols from an object. -struct LoadObjectSymbolsRequest<'definitions> { - /// The ID of the object to load. - file_id: FileId, - - symbol_start_offset: usize, - - /// The symbol resolutions for the object to be loaded that should be written to when we load - /// the object. - definitions_out: &'definitions mut [SymbolId], -} - -#[derive(Default)] -pub(crate) struct LoadedMetrics { - pub(crate) loaded_bytes: AtomicUsize, - pub(crate) loaded_compressed_bytes: AtomicUsize, - pub(crate) decompressed_bytes: AtomicUsize, -} - -impl LoadedMetrics { - fn log(&self) { - let loaded_bytes = self.loaded_bytes.load(Ordering::Relaxed); - let loaded_compressed_bytes = self.loaded_compressed_bytes.load(Ordering::Relaxed); - let decompressed_bytes = self.decompressed_bytes.load(Ordering::Relaxed); - tracing::debug!(target: "metrics", loaded_bytes, loaded_compressed_bytes, decompressed_bytes, "input_sections"); - } -} - -struct ResolutionResources<'data, 'scope, O: ObjectFile<'data>> { - definitions_per_file: &'scope Vec>>, - symbol_db: &'scope SymbolDb<'data, O>, - outputs: &'scope Outputs<'data, O>, -} - -impl<'scope, 'data, O: ObjectFile<'data>> ResolutionResources<'data, 'scope, O> { - /// Request loading of `file_id` if it hasn't already been requested. - #[inline(always)] - fn try_request_file_id(&'scope self, file_id: FileId, scope: &Scope<'scope>) { - let definitions_group = &self.definitions_per_file[file_id.group()]; - - let Some(atomic_take) = &definitions_group.get(file_id.file()) else { - // A group from a previous resolution batch. Assume that the relevant file was already - // loaded. - return; - }; - - // Do a read before we call `take`. Reads are cheaper, so this is an optimisation that - // reduces the need for exclusive access to the cache line. - if atomic_take.is_taken() { - // The definitions have previously been taken indicating that this file has already been - // processed, nothing more to do. - return; - } - - let Some(definitions_out) = atomic_take.take() else { - // Another thread just beat us to it. - return; - }; - - work_items_do( - file_id, - definitions_out, - self.symbol_db, - self.outputs, - |work_item| { - scope.spawn(|scope| { - process_object(work_item, self, scope); - }); - }, - ); - } - - fn handle_result(&self, result: Result) { - if let Err(error) = result { - let _ = self.outputs.errors.push(error); - } - } -} - -fn work_items_do<'definitions, 'data, O: ObjectFile<'data>>( - file_id: FileId, - mut definitions_out: &'definitions mut [SymbolId], - symbol_db: &SymbolDb<'data, O>, - outputs: &Outputs<'data, O>, - mut request_callback: impl FnMut(LoadObjectSymbolsRequest<'definitions>), -) { - match &symbol_db.groups[file_id.group()] { - Group::Objects(parsed_input_objects) => { - let obj = &parsed_input_objects[file_id.file()]; - let common = ResolvedCommon::new(obj); - let resolved_object = - if let Some(dynamic_tag_values) = obj.parsed.object.dynamic_tag_values() { - ResolvedFile::Dynamic(ResolvedDynamic::new(common, dynamic_tag_values)) - } else { - ResolvedFile::Object(ResolvedObject::new(common)) - }; - // Push won't fail because we allocated enough space for all the objects. - outputs.loaded.push(resolved_object).unwrap(); - } - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => { - let obj = <o_objects[file_id.file()]; - // Push won't fail because we allocated enough space for all the LTO objects. - outputs - .loaded_lto_objects - .push(ResolvedLtoInput { - file_id: obj.file_id, - symbol_id_range: obj.symbol_id_range, - }) - .unwrap(); - - request_callback(LoadObjectSymbolsRequest { - file_id, - symbol_start_offset: 0, - definitions_out, - }); - return; - } - _ => {} - } - - let chunk_size = match &symbol_db.groups[file_id.group()] { - Group::Objects(_) => MAX_SYMBOLS_PER_WORK_ITEM, - _ => definitions_out.len(), - }; - - let mut symbol_start_offset = 0; - loop { - let len = chunk_size.min(definitions_out.len()); - let chunk_definitions_out = definitions_out.split_off_mut(..len).unwrap(); - - let work_item = LoadObjectSymbolsRequest { - file_id, - definitions_out: chunk_definitions_out, - symbol_start_offset, - }; - request_callback(work_item); - - symbol_start_offset += len; - if definitions_out.is_empty() { - break; - } - } -} - -#[derive(Debug)] -pub(crate) struct ResolvedGroup<'data, O: ObjectFile<'data>> { - pub(crate) files: Vec>, -} - -#[derive(Debug)] -pub(crate) enum ResolvedFile<'data, O: ObjectFile<'data>> { - NotLoaded(NotLoaded), - Prelude(ResolvedPrelude<'data>), - Object(ResolvedObject<'data, O>), - Dynamic(ResolvedDynamic<'data, O>), - LinkerScript(ResolvedLinkerScript<'data>), - SyntheticSymbols(ResolvedSyntheticSymbols<'data>), - #[cfg(feature = "plugins")] - LtoInput(ResolvedLtoInput), -} - -#[derive(Debug)] -pub(crate) struct NotLoaded { - pub(crate) symbol_id_range: SymbolIdRange, -} - -/// A section, but where we may or may not yet have decided to load it. -#[derive(Debug, Clone, Copy)] -pub(crate) enum SectionSlot { - /// We've decided that this section won't be loaded. - Discard, - - /// The section hasn't been loaded yet, but may be loaded if it's referenced. - Unloaded(UnloadedSection), - - /// The section had the retain bit set, so must be loaded. - MustLoad(UnloadedSection), - - /// We've already loaded the section. - Loaded(crate::layout::Section), - - /// The section contains frame data, e.g. .eh_frame or equivalent. - FrameData(object::SectionIndex), - - /// The section is a string-merge section. - MergeStrings(StringMergeSectionSlot), - - // The section contains a debug info section that might be loaded. - UnloadedDebugInfo(PartId), - - // Loaded section with debug info content. - LoadedDebugInfo(crate::layout::Section), - - // GNU property section (.note.gnu.property) - NoteGnuProperty(object::SectionIndex), - - // RISC-V attributes section (.riscv.attributes) - RiscvVAttributes(object::SectionIndex), -} - -#[derive(Debug, Clone, Copy)] -pub(crate) struct UnloadedSection { - pub(crate) part_id: PartId, - - /// The index of the last FDE for this section. Previous FDEs will be linked from this. - pub(crate) last_frame_index: Option, - - /// Whether the section has a name that makes it eligible for generation of __start_ / __stop_ - /// symbols. In particular, the name of the section doesn't start with a ".". - pub(crate) start_stop_eligible: bool, -} - -impl UnloadedSection { - fn new(part_id: PartId) -> Self { - Self { - part_id, - last_frame_index: None, - start_stop_eligible: false, - } - } -} - -#[derive(Debug, Clone)] -pub(crate) struct ResolvedPrelude<'data> { - pub(crate) symbol_definitions: Vec>, -} - -/// Resolved state common to dynamic and regular objects. -#[derive(Debug)] -pub(crate) struct ResolvedCommon<'data, O: ObjectFile<'data>> { - pub(crate) input: InputRef<'data>, - pub(crate) object: &'data O, - pub(crate) file_id: FileId, - pub(crate) symbol_id_range: SymbolIdRange, -} - -#[derive(Debug)] -pub(crate) struct ResolvedObject<'data, O: ObjectFile<'data>> { - pub(crate) common: ResolvedCommon<'data, O>, - - pub(crate) sections: Vec, - pub(crate) relocations: O::RelocationSections, - - pub(crate) string_merge_extras: Vec>, - - /// Details about each custom section that is defined in this object. - custom_sections: Vec>, - - init_fini_sections: Vec, -} - -#[derive(Debug)] -pub(crate) struct ResolvedDynamic<'data, O: ObjectFile<'data>> { - pub(crate) common: ResolvedCommon<'data, O>, - dynamic_tag_values: O::DynamicTagValues, -} - -#[derive(Debug)] -pub(crate) struct ResolvedLinkerScript<'data> { - pub(crate) input: InputRef<'data>, - pub(crate) file_id: FileId, - pub(crate) symbol_id_range: SymbolIdRange, - pub(crate) symbol_definitions: Vec>, -} - -#[derive(Debug, Clone)] -pub(crate) struct ResolvedSyntheticSymbols<'data> { - pub(crate) file_id: FileId, - pub(crate) start_symbol_id: SymbolId, - pub(crate) symbol_definitions: Vec>, -} - -#[cfg(feature = "plugins")] -#[derive(Debug, Clone)] -pub(crate) struct ResolvedLtoInput { - pub(crate) file_id: FileId, - pub(crate) symbol_id_range: SymbolIdRange, -} - -fn assign_section_ids<'data, O: ObjectFile<'data>>( - resolved: &mut [ResolvedGroup<'data, O>], - output_sections: &mut OutputSections<'data>, - args: &Args, -) { - timing_phase!("Assign section IDs"); - - for group in resolved { - for file in &mut group.files { - if let ResolvedFile::Object(s) = file { - output_sections.add_sections(&s.custom_sections, s.sections.as_mut_slice(), args); - apply_init_fini_secondaries( - &s.init_fini_sections, - s.sections.as_mut_slice(), - output_sections, - ); - } - } - } -} - -fn parse_priority_suffix(suffix: &[u8]) -> Option { - if suffix.is_empty() || !suffix.iter().all(|b| b.is_ascii_digit()) { - return None; - } - - let value = core::str::from_utf8(suffix).ok()?.parse::().ok()?; - Some(u16::try_from(value).unwrap_or(u16::MAX)) -} - -fn init_fini_priority(name: &[u8]) -> Option { - if name == secnames::INIT_ARRAY_SECTION_NAME || name == secnames::FINI_ARRAY_SECTION_NAME { - return Some(u16::MAX); - } - - if let Some(rest) = name.strip_prefix(b".init_array.") { - return parse_priority_suffix(rest); - } - - if let Some(rest) = name.strip_prefix(b".fini_array.") { - return parse_priority_suffix(rest); - } - - // .ctors and .dtors without suffix have the same priority as .init_array/.fini_array - if name == secnames::CTORS_SECTION_NAME || name == secnames::DTORS_SECTION_NAME { - return Some(u16::MAX); - } - - // .ctors uses descending order (65535 = lowest priority, 0 = highest) - // while .init_array uses ascending order (0 = highest priority, 65535 = lowest) - if let Some(rest) = name.strip_prefix(b".ctors.") { - return parse_priority_suffix(rest).map(|p| u16::MAX.saturating_sub(p)); - } - - if let Some(rest) = name.strip_prefix(b".dtors.") { - return parse_priority_suffix(rest).map(|p| u16::MAX.saturating_sub(p)); - } - - None -} - -struct Outputs<'data, O: ObjectFile<'data>> { - /// Where we put objects once we've loaded them. - loaded: ArrayQueue>, - - #[cfg(feature = "plugins")] - loaded_lto_objects: ArrayQueue, - - /// Any errors that we encountered. - errors: ArrayQueue, - - undefined_symbols: SegQueue>, -} - -impl<'data, O: ObjectFile<'data>> Outputs<'data, O> { - #[allow(unused_variables)] - fn new(num_regular_objects: usize, num_lto_objects: usize) -> Self { - Self { - loaded: ArrayQueue::new(num_regular_objects.max(1)), - #[cfg(feature = "plugins")] - loaded_lto_objects: ArrayQueue::new(num_lto_objects.max(1)), - errors: ArrayQueue::new(1), - undefined_symbols: SegQueue::new(), - } - } -} - -fn process_object<'scope, 'data: 'scope, 'definitions, O: ObjectFile<'data>>( - work_item: LoadObjectSymbolsRequest<'definitions>, - resources: &'scope ResolutionResources<'data, 'scope, O>, - scope: &Scope<'scope>, -) { - let file_id = work_item.file_id; - let definitions_out = work_item.definitions_out; - - match &resources.symbol_db.groups[file_id.group()] { - Group::Prelude(prelude) => { - verbose_timing_phase!("Resolve prelude symbols"); - - load_prelude(prelude, definitions_out, resources, scope); - } - Group::Objects(parsed_input_objects) => { - verbose_timing_phase!("Resolve object symbols"); - - let obj = &parsed_input_objects[file_id.file()]; - - resources.handle_result( - resolve_symbols( - obj, - resources, - work_item.symbol_start_offset, - definitions_out, - scope, - ) - .with_context(|| format!("Failed to resolve symbols in {obj}")), - ); - } - Group::LinkerScripts(_) => {} - Group::SyntheticSymbols(_) => {} - #[cfg(feature = "plugins")] - Group::LtoInputs(objects) => { - let obj = &objects[file_id.file()]; - resources.handle_result( - resolve_lto_symbols(obj, resources, definitions_out, scope) - .with_context(|| format!("Failed to resolve symbols in {obj}")), - ); - } - } -} - -#[cfg(feature = "plugins")] -fn resolve_lto_symbols<'data, 'scope, O: ObjectFile<'data>>( - obj: &crate::linker_plugins::LtoInput<'data>, - resources: &'scope ResolutionResources<'data, 'scope, O>, - definitions_out: &mut [SymbolId], - scope: &Scope<'scope>, -) -> Result { - obj.symbols - .iter() - .enumerate() - .zip(definitions_out) - .try_for_each( - |((local_symbol_index, local_symbol), definition)| -> Result { - if !local_symbol.is_definition() { - let mut name_info = RawSymbolName::parse(local_symbol.name.bytes()); - if let Some(version) = local_symbol.version { - name_info.version_name = Some(version); - } - - let symbol_attributes = SymbolAttributes { - name_info, - is_local: false, - default_visibility: local_symbol.visibility == object::elf::STV_DEFAULT, - is_weak: local_symbol.kind - == Some(crate::linker_plugins::SymbolKind::WeakUndef), - }; - - resolve_symbol( - obj.symbol_id_range.offset_to_id(local_symbol_index), - &symbol_attributes, - definition, - resources, - false, - obj.file_id, - scope, - )?; - } - - Ok(()) - }, - ) -} - -struct UndefinedSymbol<'data> { - /// If we have a file ID here and that file is loaded, then the symbol is actually defined and - /// this record can be ignored. - ignore_if_loaded: Option, - name: PreHashedSymbolName<'data>, - symbol_id: SymbolId, -} - -fn load_prelude<'scope, 'data, O: ObjectFile<'data>>( - prelude: &crate::parsing::Prelude, - definitions_out: &mut [SymbolId], - resources: &'scope ResolutionResources<'data, 'scope, O>, - scope: &Scope<'scope>, -) { - // The start symbol could be defined within an archive entry. If it is, then we need to load - // it. We don't currently store the resulting SymbolId, but instead look it up again during - // layout. - load_symbol_named( - resources, - &mut SymbolId::undefined(), - resources.symbol_db.entry_symbol_name(), - scope, - ); - - // Try to resolve any symbols that the user requested be undefined (e.g. via --undefined). If an - // object defines such a symbol, request that the object be loaded. Also, point our undefined - // symbol record to the definition. - for (def_info, definition_out) in prelude.symbol_definitions.iter().zip(definitions_out) { - match def_info.placement { - SymbolPlacement::ForceUndefined | SymbolPlacement::DefsymSymbol(_, _) => { - load_symbol_named(resources, definition_out, def_info.name, scope); - } - _ => {} - } - } -} - -fn load_symbol_named<'scope, 'data, O: ObjectFile<'data>>( - resources: &'scope ResolutionResources<'data, 'scope, O>, - definition_out: &mut SymbolId, - name: &[u8], - scope: &Scope<'scope>, -) { - if let Some(symbol_id) = resources - .symbol_db - .get_unversioned(&UnversionedSymbolName::prehashed(name)) - { - *definition_out = symbol_id; - - let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); - resources.try_request_file_id(symbol_file_id, scope); - } -} - -/// Where there are multiple references to undefined symbols with the same name, pick one reference -/// as the canonical one to which we'll refer. Where undefined symbols can be resolved to -/// __start/__stop symbols that refer to the start or stop of a custom section, collect that -/// information up and put it into `custom_start_stop_defs`. -fn canonicalise_undefined_symbols<'data, O: ObjectFile<'data>>( - mut undefined_symbols: Vec>, - output_sections: &OutputSections, - groups: &[ResolvedGroup<'data, O>], - symbol_db: &mut SymbolDb<'data, O>, - per_symbol_flags: &mut PerSymbolFlags, - custom_start_stop_defs: &mut ResolvedSyntheticSymbols<'data>, -) { - timing_phase!("Canonicalise undefined symbols"); - - let mut name_to_id: PassThroughHashMap, SymbolId> = - Default::default(); - - let mut versioned_name_to_id: PassThroughHashMap, SymbolId> = - Default::default(); - - // Sort by symbol ID to ensure deterministic behaviour. We sort in reverse order so that LTO - // outputs get higher priority than LTO inputs. This means that the canonical symbol ID for any - // given name will be the one for the last file that refers to that symbol. - undefined_symbols.sort_by_key(|u| usize::MAX - u.symbol_id.as_usize()); - - for undefined in undefined_symbols { - let is_defined = undefined.ignore_if_loaded.is_some_and(|file_id| { - !matches!( - groups[file_id.group()].files[file_id.file()], - ResolvedFile::NotLoaded(_) - ) - }); - - if is_defined { - // The archive entry that defined the symbol in question ended up being loaded, so the - // weak symbol is defined after all. - continue; - } - - match undefined.name { - PreHashedSymbolName::Unversioned(pre_hashed) => { - match name_to_id.entry(pre_hashed) { - hashbrown::hash_map::Entry::Vacant(entry) => { - let symbol_id = allocate_start_stop_symbol_id( - pre_hashed, - symbol_db, - per_symbol_flags, - custom_start_stop_defs, - output_sections, - ); - - // We either make our undefined symbol dynamic, allowing the possibility - // that it might end up being defined at runtime, or we make it - // non-interposable, which means it'll remain null and even if it ends up - // defined at runtime, we won't use that definition. If the symbol doesn't - // have default visibility, then we make it non-interposable. If we're - // building a shared object, we always make the symbol dynamic. If we're - // building a statically linked executable, then we always make it - // non-interposable. If we're building a regular, dynamically linked - // executable, then we make it dynamic if the symbol is weak and otherwise - // make it non-interposable. That last case, a non-weak, default-visibility, - // undefined symbol in an executable is generally a link error, however if - // the flag --warn-unresolved-symbols is passed, then it won't be. Linker - // behaviour differs in this case. GNU ld makes the symbol non-interposable, - // while lld makes it dynamic. We match GNU ld in this case. - if symbol_id.is_none() { - let output_kind = symbol_db.output_kind; - let visibility = symbol_db.input_symbol_visibility(undefined.symbol_id); - - if visibility == Visibility::Default - && (output_kind.is_shared_object() - || (!output_kind.is_static_executable() - && symbol_db.symbol_strength(undefined.symbol_id, groups) - == SymbolStrength::Weak)) - { - per_symbol_flags.set_flag(undefined.symbol_id, ValueFlags::DYNAMIC); - } else { - per_symbol_flags - .set_flag(undefined.symbol_id, ValueFlags::NON_INTERPOSABLE); - } - } - - // If the symbol isn't a start/stop symbol, then assign responsibility for - // the symbol to the first object that referenced - // it. This lets us have PLT/GOT entries - // for the symbol if they're needed. - let symbol_id = symbol_id.unwrap_or(undefined.symbol_id); - entry.insert(symbol_id); - symbol_db.replace_definition(undefined.symbol_id, symbol_id); - } - hashbrown::hash_map::Entry::Occupied(entry) => { - symbol_db.replace_definition(undefined.symbol_id, *entry.get()); - } - } - } - PreHashedSymbolName::Versioned(pre_hashed) => { - match versioned_name_to_id.entry(pre_hashed) { - hashbrown::hash_map::Entry::Vacant(entry) => { - entry.insert(undefined.symbol_id); - } - hashbrown::hash_map::Entry::Occupied(entry) => { - symbol_db.replace_definition(undefined.symbol_id, *entry.get()); - } - } - } - } - } -} - -fn allocate_start_stop_symbol_id<'data, O: ObjectFile<'data>>( - name: PreHashed>, - symbol_db: &mut SymbolDb<'data, O>, - per_symbol_flags: &mut PerSymbolFlags, - custom_start_stop_defs: &mut ResolvedSyntheticSymbols<'data>, - output_sections: &OutputSections, -) -> Option { - let symbol_name_bytes = name.bytes(); - - let (section_name, is_start) = if let Some(s) = symbol_name_bytes.strip_prefix(b"__start_") { - (s, true) - } else if let Some(s) = symbol_name_bytes.strip_prefix(b"__stop_") { - (s, false) - } else { - return None; - }; - - let section_id = output_sections.custom_name_to_id(SectionName(section_name))?; - - let def_info = if is_start { - InternalSymDefInfo::new(SymbolPlacement::SectionStart(section_id), name.bytes()) - } else { - InternalSymDefInfo::new(SymbolPlacement::SectionEnd(section_id), name.bytes()) - }; - - let symbol_id = symbol_db.add_synthetic_symbol(per_symbol_flags, name, custom_start_stop_defs); - - custom_start_stop_defs.symbol_definitions.push(def_info); - - Some(symbol_id) -} - -impl<'data, O: ObjectFile<'data>> ResolvedCommon<'data, O> { - fn new(obj: &'data SequencedInputObject<'data, O>) -> Self { - Self { - input: obj.parsed.input, - object: &obj.parsed.object, - file_id: obj.file_id, - symbol_id_range: obj.symbol_id_range, - } - } - - pub(crate) fn symbol_strength(&self, symbol_id: SymbolId) -> SymbolStrength { - let local_index = symbol_id.to_input(self.symbol_id_range); - let Ok(obj_symbol) = self.object.symbol(local_index) else { - // Errors from this function should have been reported elsewhere. - return SymbolStrength::Undefined; - }; - SymbolStrength::of(obj_symbol) - } -} - -fn apply_init_fini_secondaries<'data>( - details: &[InitFiniSectionDetail], - sections: &mut [SectionSlot], - output_sections: &mut OutputSections<'data>, -) { - for d in details { - let Some(slot) = sections.get_mut(d.index as usize) else { - continue; - }; - - let unloaded = match slot { - SectionSlot::Unloaded(u) | SectionSlot::MustLoad(u) => u, - _ => continue, - }; - - let sid = - output_sections.get_or_create_init_fini_secondary(d.primary, d.priority, d.alignment); - unloaded.part_id = sid.part_id_with_alignment(d.alignment); - } -} - -impl<'data, O: ObjectFile<'data>> ResolvedObject<'data, O> { - fn new(common: ResolvedCommon<'data, O>) -> Self { - Self { - common, - // We'll fill this the rest during section resolution. - sections: Default::default(), - relocations: Default::default(), - string_merge_extras: Default::default(), - custom_sections: Default::default(), - init_fini_sections: Default::default(), - } - } -} - -impl<'data, O: ObjectFile<'data>> ResolvedDynamic<'data, O> { - fn new(common: ResolvedCommon<'data, O>, dynamic_tag_values: O::DynamicTagValues) -> Self { - Self { - common, - dynamic_tag_values, - } - } - - pub(crate) fn lib_name(&self) -> &'data [u8] { - self.dynamic_tag_values.lib_name(&self.common.input) - } -} - -fn resolve_sections_for_object<'data, O: ObjectFile<'data>>( - obj: &mut ResolvedObject<'data, O>, - args: &Args, - allocator: &bumpalo_herd::Member<'data>, - loaded_metrics: &LoadedMetrics, - rules: &SectionRules, -) -> Result> { - // Note, we build up the collection with push rather than collect because at the time of - // writing, object's `SectionTable::enumerate` isn't an exact-size iterator, so using collect - // would result in resizing. - let mut sections = Vec::with_capacity(obj.common.object.num_sections()); - for (input_section_index, input_section) in obj.common.object.enumerate_sections() { - sections.push(resolve_section( - input_section_index, - input_section, - obj, - args, - allocator, - loaded_metrics, - rules, - )?); - } - Ok(sections) -} - -#[inline(always)] -fn resolve_section<'data, O: ObjectFile<'data>>( - input_section_index: SectionIndex, - input_section: &O::SectionHeader, - obj: &mut ResolvedObject<'data, O>, - args: &Args, - allocator: &bumpalo_herd::Member<'data>, - loaded_metrics: &LoadedMetrics, - rules: &SectionRules, -) -> Result { - let section_name = obj - .common - .object - .section_name(input_section) - .unwrap_or_default(); - - if section_name.starts_with(secnames::GNU_LTO_SYMTAB_PREFIX.as_bytes()) { - if cfg!(feature = "plugins") { - bail!("Found GCC LTO input that we didn't supply to linker plugin"); - } - return Err(symbol_db::linker_plugin_disabled_error()); - } - - let section_flags = input_section.flags(); - let raw_alignment = obj.common.object.section_alignment(input_section)?; - let alignment = Alignment::new(raw_alignment.max(1))?; - let should_merge_sections = part_id::should_merge_sections(section_flags, raw_alignment, args); - - let mut unloaded_section; - let mut is_debug_info = false; - let section_type = input_section.section_type(); - let mut must_load = section_flags.should_retain() || section_type.is_note(); - - let file_name = if let Some(entry) = &obj.common.input.entry { - // For archive members, match against the member name (e.g., "app.o"), - // not the archive filename (e.g., "libfoo.a"). - Some(entry.identifier.as_slice()) - } else { - obj.common - .input - .file - .filename - .file_name() - .map(|n| n.as_encoded_bytes()) - }; - - match rules.lookup(section_name, file_name, section_flags, section_type) { - SectionRuleOutcome::Section(output_info) => { - let part_id = if output_info.section_id.is_regular() { - output_info.section_id.part_id_with_alignment(alignment) - } else { - output_info.section_id.base_part_id() - }; - - must_load |= output_info.must_keep; - - unloaded_section = UnloadedSection::new(part_id); - } - SectionRuleOutcome::SortedSection(output_info) => { - let part_id = if output_info.section_id.is_regular() { - output_info.section_id.part_id_with_alignment(alignment) - } else { - output_info.section_id.base_part_id() - }; - if let Some(priority) = init_fini_priority(section_name) { - obj.init_fini_sections.push(InitFiniSectionDetail { - index: input_section_index.0 as u32, - primary: output_info.section_id, - priority, - alignment, - }); - } - - must_load |= output_info.must_keep; - - unloaded_section = UnloadedSection::new(part_id); - } - SectionRuleOutcome::Discard => return Ok(SectionSlot::Discard), - SectionRuleOutcome::EhFrame => { - return Ok(SectionSlot::FrameData(input_section_index)); - } - SectionRuleOutcome::NoteGnuProperty => { - return Ok(SectionSlot::NoteGnuProperty(input_section_index)); - } - SectionRuleOutcome::Debug => { - if args.strip_debug() && !section_flags.is_alloc() { - return Ok(SectionSlot::Discard); - } - - is_debug_info = !section_flags.is_alloc(); - - unloaded_section = UnloadedSection::new(part_id::CUSTOM_PLACEHOLDER); - } - SectionRuleOutcome::Custom => { - unloaded_section = UnloadedSection::new(part_id::CUSTOM_PLACEHOLDER); - unloaded_section.start_stop_eligible = !section_name.starts_with(b"."); - } - SectionRuleOutcome::RiscVAttribute => { - return Ok(SectionSlot::RiscvVAttributes(input_section_index)); - } - }; - - if unloaded_section.part_id == part_id::CUSTOM_PLACEHOLDER { - let custom_section = CustomSectionDetails { - name: SectionName(section_name), - alignment, - index: input_section_index, - }; - - obj.custom_sections.push(custom_section); - } - - let slot = if should_merge_sections { - let section_data = - obj.common - .object - .section_data(input_section, allocator, loaded_metrics)?; - let section_flags = input_section.flags(); - - if section_data.is_empty() { - SectionSlot::Discard - } else { - obj.string_merge_extras.push(StringMergeSectionExtra { - index: input_section_index, - section_data, - section_flags, - }); - - SectionSlot::MergeStrings(StringMergeSectionSlot::new(unloaded_section.part_id)) - } - } else if is_debug_info { - SectionSlot::UnloadedDebugInfo(part_id::CUSTOM_PLACEHOLDER) - } else if must_load { - SectionSlot::MustLoad(unloaded_section) - } else { - SectionSlot::Unloaded(unloaded_section) - }; - - Ok(slot) -} - -fn resolve_symbols<'data, 'scope, O: ObjectFile<'data>>( - obj: &SequencedInputObject<'data, O>, - resources: &'scope ResolutionResources<'data, 'scope, O>, - start_symbol_offset: usize, - definitions_out: &mut [SymbolId], - scope: &Scope<'scope>, -) -> Result { - let verneed = obj.parsed.object.verneed_table()?; - - obj.parsed.object.symbols()[start_symbol_offset..] - .iter() - .enumerate() - .zip(definitions_out) - .try_for_each( - |((local_symbol_index, local_symbol), definition)| -> Result { - // Don't try to resolve symbols that are already defined, e.g. locals and globals - // that we define. Also don't try to resolve symbol zero - the undefined symbol. - // Hidden symbols exported from shared objects don't make sense, so we skip - // resolving them as well. - if !definition.is_undefined() - || start_symbol_offset + local_symbol_index == 0 - || (obj.is_dynamic() && local_symbol.is_hidden()) - { - return Ok(()); - } - - let name_bytes = obj.parsed.object.symbol_name(local_symbol)?; - - let name_info = if let Some(version_name) = - verneed.version_name(object::SymbolIndex(local_symbol_index)) - { - RawSymbolName { - name: name_bytes, - version_name: Some(version_name), - is_default: false, - } - } else { - RawSymbolName::parse(name_bytes) - }; - - let symbol_attributes = SymbolAttributes { - name_info, - is_local: local_symbol.is_local(), - default_visibility: local_symbol.is_interposable(), - is_weak: local_symbol.is_weak(), - }; - - resolve_symbol( - obj.symbol_id_range - .offset_to_id(start_symbol_offset + local_symbol_index), - &symbol_attributes, - definition, - resources, - obj.is_dynamic(), - obj.file_id, - scope, - ) - }, - ) -} - -#[derive(Debug)] -struct SymbolAttributes<'data> { - is_local: bool, - default_visibility: bool, - is_weak: bool, - name_info: RawSymbolName<'data>, -} - -#[inline(always)] -fn resolve_symbol<'data, 'scope, O: ObjectFile<'data>>( - local_symbol_id: SymbolId, - local_symbol_attributes: &SymbolAttributes<'data>, - definition_out: &mut SymbolId, - resources: &'scope ResolutionResources<'data, 'scope, O>, - is_dynamic: bool, - file_id: FileId, - scope: &Scope<'scope>, -) -> Result { - debug_assert_bail!( - !local_symbol_attributes.is_local, - "Only globals should be undefined, found symbol `{}` ({local_symbol_id})", - local_symbol_attributes.name_info, - ); - - let prehashed_name = PreHashedSymbolName::from_raw(&local_symbol_attributes.name_info); - - // Only default-visibility symbols can reference symbols from shared objects. - let allow_dynamic = local_symbol_attributes.default_visibility; - - match resources.symbol_db.get(&prehashed_name, allow_dynamic) { - Some(symbol_id) => { - *definition_out = symbol_id; - let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); - - if symbol_file_id != file_id && !local_symbol_attributes.is_weak { - // Undefined symbols in shared objects should actually activate as-needed shared - // objects, however the rules for whether this should result in a DT_NEEDED entry - // are kind of subtle, so for now, we don't activate shared objects from shared - // objects. See - // https://github.com/wild-linker/wild/issues/930#issuecomment-3007027924 for - // more details. TODO: Fix this. - if !is_dynamic || !resources.symbol_db.file(symbol_file_id).is_dynamic() { - resources.try_request_file_id(symbol_file_id, scope); - } - } else if symbol_file_id != PRELUDE_FILE_ID { - // The symbol is weak and we can't be sure that the file that defined it will end up - // being loaded, so the symbol might actually be undefined. Register it as an - // undefined symbol then later when we handle undefined symbols, we'll check if the - // file got loaded. TODO: If the file is a non-archived object, or possibly even if - // it's an archived object that we've already decided to load, then we could skip - // this. - resources.outputs.undefined_symbols.push(UndefinedSymbol { - ignore_if_loaded: Some(symbol_file_id), - name: prehashed_name, - symbol_id: local_symbol_id, - }); - } - } - None => { - resources.outputs.undefined_symbols.push(UndefinedSymbol { - ignore_if_loaded: None, - name: prehashed_name, - symbol_id: local_symbol_id, - }); - } - } - Ok(()) -} - -impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedObject<'data, O> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.common.input, f) - } -} - -impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedDynamic<'data, O> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.common.input, f) - } -} - -impl<'data> std::fmt::Display for ResolvedLinkerScript<'data> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&self.input, f) - } -} - -impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedFile<'data, O> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ResolvedFile::NotLoaded(_) => std::fmt::Display::fmt("", f), - ResolvedFile::Prelude(_) => std::fmt::Display::fmt("", f), - ResolvedFile::Object(o) => std::fmt::Display::fmt(o, f), - ResolvedFile::Dynamic(o) => std::fmt::Display::fmt(o, f), - ResolvedFile::LinkerScript(o) => std::fmt::Display::fmt(o, f), - ResolvedFile::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), - #[cfg(feature = "plugins")] - ResolvedFile::LtoInput(_) => std::fmt::Display::fmt("", f), - } - } -} - -impl SectionSlot { - pub(crate) fn is_loaded(&self) -> bool { - !matches!(self, SectionSlot::Discard | SectionSlot::Unloaded(..)) - } - - pub(crate) fn set_part_id(&mut self, part_id: PartId) { - match self { - SectionSlot::Unloaded(section) => section.part_id = part_id, - SectionSlot::MustLoad(section) => section.part_id = part_id, - SectionSlot::Loaded(section) => section.part_id = part_id, - SectionSlot::MergeStrings(section) => section.part_id = part_id, - SectionSlot::UnloadedDebugInfo(out) => *out = part_id, - SectionSlot::LoadedDebugInfo(section) => section.part_id = part_id, - SectionSlot::Discard - | SectionSlot::FrameData(_) - | SectionSlot::NoteGnuProperty(_) - | SectionSlot::RiscvVAttributes(_) => {} - } - } - - pub(crate) fn unloaded_mut(&mut self) -> Option<&mut UnloadedSection> { - match self { - SectionSlot::Unloaded(unloaded) | SectionSlot::MustLoad(unloaded) => Some(unloaded), - _ => None, - } - } -} - -impl<'data, O: ObjectFile<'data>> ResolvedFile<'data, O> { - fn symbol_id_range(&self) -> SymbolIdRange { - match self { - ResolvedFile::NotLoaded(s) => s.symbol_id_range, - ResolvedFile::Prelude(s) => s.symbol_id_range(), - ResolvedFile::Object(s) => s.common.symbol_id_range, - ResolvedFile::Dynamic(s) => s.common.symbol_id_range, - ResolvedFile::LinkerScript(s) => s.symbol_id_range, - ResolvedFile::SyntheticSymbols(s) => s.symbol_id_range(), - #[cfg(feature = "plugins")] - ResolvedFile::LtoInput(s) => s.symbol_id_range, - } - } -} - -impl ResolvedPrelude<'_> { - fn symbol_id_range(&self) -> SymbolIdRange { - SymbolIdRange::input(SymbolId::undefined(), self.symbol_definitions.len()) - } -} - -impl ResolvedSyntheticSymbols<'_> { - fn symbol_id_range(&self) -> SymbolIdRange { - SymbolIdRange::input(self.start_symbol_id, self.symbol_definitions.len()) - } -} - -impl<'data, O: ObjectFile<'data>> Default for Resolver<'data, O> { - fn default() -> Self { - Self { - undefined_symbols: Default::default(), - resolved_groups: Default::default(), - } - } -} - -// We create quite a lot of `SectionSlot`s. We don't generally copy them, however we do need to -// eventually drop the Vecs that contain them. Dropping those Vecs is a lot cheaper if the slots -// don't need to have run Drop. We check for this, by making sure the type implements `Copy` -#[test] -fn section_slot_is_copy() { - fn assert_copy(_v: T) {} - - assert_copy(SectionSlot::Discard); -} +//! This module resolves symbol references between objects. In the process, it decides which archive +//! entries are needed. We also resolve which output section, if any, each input section should be +//! assigned to. + +use crate::layout_rules::LayoutRules; +use crate::alignment::Alignment; +use crate::args::Args; +use crate::bail; +use crate::debug_assert_bail; +use crate::elf::RawSymbolName; +use crate::error::Context as _; +use crate::error::Error; +use crate::error::Result; +use crate::grouping::Group; +use crate::grouping::SequencedInputObject; +use crate::hash::PassThroughHashMap; +use crate::hash::PreHashed; +use crate::input_data::FileId; +use crate::input_data::InputRef; +use crate::input_data::PRELUDE_FILE_ID; +use crate::layout_rules::SectionRuleOutcome; +use crate::layout_rules::SectionRules; +use crate::output_section_id::CustomSectionDetails; +use crate::output_section_id::InitFiniSectionDetail; +use crate::output_section_id::OutputSections; +use crate::output_section_id::SectionName; +use crate::parsing::InternalSymDefInfo; +use crate::parsing::SymbolPlacement; +use crate::part_id; +use crate::part_id::PartId; +use crate::platform::DynamicTagValues as _; +use crate::platform::FrameIndex; +use crate::platform::ObjectFile; +use crate::platform::RawSymbolName as _; +use crate::platform::SectionFlags as _; +use crate::platform::SectionHeader as _; +use crate::platform::SectionType as _; +use crate::platform::Symbol as _; +use crate::platform::VerneedTable as _; +use crate::string_merging::StringMergeSectionExtra; +use crate::string_merging::StringMergeSectionSlot; +use crate::symbol::PreHashedSymbolName; +use crate::symbol::UnversionedSymbolName; +use crate::symbol::VersionedSymbolName; +use crate::symbol_db; +use crate::symbol_db::SymbolDb; +use crate::symbol_db::SymbolId; +use crate::symbol_db::SymbolIdRange; +use crate::symbol_db::SymbolStrength; +use crate::symbol_db::Visibility; +use crate::timing_phase; +use crate::value_flags::PerSymbolFlags; +use crate::value_flags::ValueFlags; +use crate::verbose_timing_phase; +use atomic_take::AtomicTake; +use crossbeam_queue::ArrayQueue; +use crossbeam_queue::SegQueue; +use linker_utils::elf::secnames; +use object::SectionIndex; +use rayon::Scope; +use rayon::iter::IntoParallelIterator; +use rayon::iter::IntoParallelRefMutIterator; +use rayon::iter::ParallelIterator; +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +pub(crate) struct Resolver<'data, O: ObjectFile<'data>> { + undefined_symbols: Vec>, + pub(crate) resolved_groups: Vec>, +} + +impl<'data, O: ObjectFile<'data>> Resolver<'data, O> { + /// Resolves undefined symbols. In the process of resolving symbols, we decide which archive + /// entries to load. Some symbols may not have definitions, in which case we'll note those for + /// later processing. Can be called multiple times with additional groups having been added to + /// the SymbolDb in between. + pub(crate) fn resolve_symbols_and_select_archive_entries( + &mut self, + symbol_db: &mut SymbolDb<'data, O>, + ) -> Result { + resolve_symbols_and_select_archive_entries(self, symbol_db) + } + + /// For all regular objects that we've decided to load, decide what to do with each section. + /// Canonicalises undefined symbols. Some undefined symbols might be able to become defined if + /// we can identify them as start/stop symbols for which we found a custom section with the + /// appropriate name. + pub(crate) fn resolve_sections_and_canonicalise_undefined( + mut self, + symbol_db: &mut SymbolDb<'data, O>, + per_symbol_flags: &mut PerSymbolFlags, + output_sections: &mut OutputSections<'data>, + layout_rules: &LayoutRules<'data>, + ) -> Result>> { + timing_phase!("Section resolution"); + + resolve_sections(&mut self.resolved_groups, symbol_db, layout_rules)?; + + let mut syn = symbol_db.new_synthetic_symbols_group(); + + assign_section_ids(&mut self.resolved_groups, output_sections, symbol_db.args); + + canonicalise_undefined_symbols( + self.undefined_symbols, + output_sections, + &self.resolved_groups, + symbol_db, + per_symbol_flags, + &mut syn, + ); + + self.resolved_groups.push(ResolvedGroup { + files: vec![ResolvedFile::SyntheticSymbols(syn)], + }); + + Ok(self.resolved_groups) + } +} + +fn resolve_symbols_and_select_archive_entries<'data, O: ObjectFile<'data>>( + resolver: &mut Resolver<'data, O>, + symbol_db: &mut SymbolDb<'data, O>, +) -> Result { + timing_phase!("Resolve symbols"); + + // Note, this is the total number of objects including those that we might have processed in + // previous calls. This is just an upper bound on how many objects might need to be loaded. We + // can't just count the objects in the new groups because we might end up loading some of the + // objects from earlier groups. + let num_regular_objects = symbol_db.num_regular_objects(); + let num_lto_objects = symbol_db.num_lto_objects(); + if num_regular_objects == 0 && num_lto_objects == 0 { + bail!("no input files"); + } + + let mut symbol_definitions = symbol_db.take_definitions(); + let mut symbol_definitions_slice: &mut [SymbolId] = symbol_definitions.as_mut(); + + let mut definitions_per_group_and_file = Vec::new(); + definitions_per_group_and_file.resize_with(symbol_db.groups.len(), Vec::new); + + let outputs = { + verbose_timing_phase!("Allocate outputs store"); + Outputs::new(num_regular_objects, num_lto_objects) + }; + + let mut initial_work = Vec::new(); + + { + verbose_timing_phase!("Resolution setup"); + + let pre_existing_groups = resolver.resolved_groups.len(); + let new_groups = &symbol_db.groups[pre_existing_groups..]; + + for (group, definitions_out_per_file) in resolver + .resolved_groups + .iter() + .zip(&mut definitions_per_group_and_file) + { + *definitions_out_per_file = group + .files + .iter() + .map(|file| { + let definitions = symbol_definitions_slice + .split_off_mut(..file.symbol_id_range().len()) + .unwrap(); + + if matches!(file, ResolvedFile::NotLoaded(_)) { + AtomicTake::new(definitions) + } else { + AtomicTake::empty() + } + }) + .collect(); + } + + resolver.resolved_groups.extend( + new_groups + .iter() + .zip(&mut definitions_per_group_and_file[pre_existing_groups..]) + .map(|(group, definitions_out_per_file)| { + resolve_group( + group, + &mut initial_work, + definitions_out_per_file, + &mut symbol_definitions_slice, + symbol_db, + &outputs, + ) + }), + ); + }; + + let resources = ResolutionResources { + definitions_per_file: &definitions_per_group_and_file, + symbol_db, + outputs: &outputs, + }; + + rayon::in_place_scope(|scope| { + initial_work.into_par_iter().for_each(|work_item| { + process_object(work_item, &resources, scope); + }); + }); + + { + verbose_timing_phase!("Drop definitions_per_group_and_file"); + drop(definitions_per_group_and_file); + } + + symbol_db.restore_definitions(symbol_definitions); + + if let Some(e) = outputs.errors.pop() { + return Err(e); + } + + verbose_timing_phase!("Gather loaded objects"); + + for obj in outputs.loaded { + let file_id = match &obj { + ResolvedFile::Object(o) => o.common.file_id, + ResolvedFile::Dynamic(o) => o.common.file_id, + _ => unreachable!(), + }; + resolver.resolved_groups[file_id.group()].files[file_id.file()] = obj; + } + + #[cfg(feature = "plugins")] + for obj in outputs.loaded_lto_objects { + let file_id = obj.file_id; + resolver.resolved_groups[file_id.group()].files[file_id.file()] = + ResolvedFile::LtoInput(obj); + } + + resolver.undefined_symbols.extend(outputs.undefined_symbols); + + Ok(()) +} + +fn resolve_group<'data, 'definitions, O: ObjectFile<'data>>( + group: &Group<'data, O>, + initial_work_out: &mut Vec>, + definitions_out_per_file: &mut Vec>, + symbol_definitions_slice: &mut &'definitions mut [SymbolId], + symbol_db: &SymbolDb<'data, O>, + outputs: &Outputs<'data, O>, +) -> ResolvedGroup<'data, O> { + match group { + Group::Prelude(prelude) => { + let definitions_out = symbol_definitions_slice + .split_off_mut(..prelude.symbol_definitions.len()) + .unwrap(); + + work_items_do( + PRELUDE_FILE_ID, + definitions_out, + symbol_db, + outputs, + |work_item| { + initial_work_out.push(work_item); + }, + ); + + definitions_out_per_file.push(AtomicTake::empty()); + + ResolvedGroup { + files: vec![ResolvedFile::Prelude(ResolvedPrelude { + symbol_definitions: prelude.symbol_definitions.clone(), + })], + } + } + Group::Objects(parsed_input_objects) => { + definitions_out_per_file.reserve(parsed_input_objects.len()); + + let files = parsed_input_objects + .iter() + .map(|s| { + let definitions_out = symbol_definitions_slice + .split_off_mut(..s.symbol_id_range.len()) + .unwrap(); + + if s.is_optional() { + definitions_out_per_file.push(AtomicTake::new(definitions_out)); + } else { + work_items_do( + s.file_id, + definitions_out, + symbol_db, + outputs, + |work_item| { + initial_work_out.push(work_item); + }, + ); + definitions_out_per_file.push(AtomicTake::empty()); + } + + ResolvedFile::NotLoaded(NotLoaded { + symbol_id_range: s.symbol_id_range, + }) + }) + .collect(); + + ResolvedGroup { files } + } + Group::LinkerScripts(scripts) => { + let files = scripts + .iter() + .map(|s| { + definitions_out_per_file.push(AtomicTake::empty()); + + ResolvedFile::LinkerScript(ResolvedLinkerScript { + input: s.parsed.input, + file_id: s.file_id, + symbol_id_range: s.symbol_id_range, + // TODO: Consider alternative to cloning this. + symbol_definitions: s.parsed.symbol_defs.clone(), + }) + }) + .collect(); + + ResolvedGroup { files } + } + Group::SyntheticSymbols(syn) => { + definitions_out_per_file.push(AtomicTake::empty()); + + ResolvedGroup { + files: vec![ResolvedFile::SyntheticSymbols(ResolvedSyntheticSymbols { + file_id: syn.file_id, + start_symbol_id: syn.symbol_id_range.start(), + symbol_definitions: Vec::new(), + })], + } + } + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => ResolvedGroup { + files: lto_objects + .iter() + .map(|o| { + let definitions_out = symbol_definitions_slice + .split_off_mut(..o.symbol_id_range.len()) + .unwrap(); + + if o.is_optional() { + definitions_out_per_file.push(AtomicTake::new(definitions_out)); + } else { + work_items_do( + o.file_id, + definitions_out, + symbol_db, + outputs, + |work_item| { + initial_work_out.push(work_item); + }, + ); + definitions_out_per_file.push(AtomicTake::empty()); + } + + ResolvedFile::NotLoaded(NotLoaded { + symbol_id_range: o.symbol_id_range, + }) + }) + .collect(), + }, + } +} + +fn resolve_sections<'data, O: ObjectFile<'data>>( + groups: &mut [ResolvedGroup<'data, O>], + symbol_db: &SymbolDb<'data, O>, + layout_rules: &LayoutRules<'data>, +) -> Result { + timing_phase!("Resolve sections"); + + let loaded_metrics: LoadedMetrics = Default::default(); + let herd = symbol_db.herd; + + groups.par_iter_mut().try_for_each_init( + || herd.get(), + |allocator, group| -> Result { + verbose_timing_phase!("Resolve group sections"); + + for file in &mut group.files { + let ResolvedFile::::Object(obj) = file else { + continue; + }; + + obj.sections = resolve_sections_for_object( + obj, + symbol_db.args, + allocator, + &loaded_metrics, + &layout_rules.section_rules, + )?; + + obj.relocations = obj.common.object.parse_relocations()?; + } + Ok(()) + }, + )?; + + loaded_metrics.log(); + + Ok(()) +} + +const MAX_SYMBOLS_PER_WORK_ITEM: usize = 5000; + +/// A request to load a chunk of symbols from an object. +struct LoadObjectSymbolsRequest<'definitions> { + /// The ID of the object to load. + file_id: FileId, + + symbol_start_offset: usize, + + /// The symbol resolutions for the object to be loaded that should be written to when we load + /// the object. + definitions_out: &'definitions mut [SymbolId], +} + +#[derive(Default)] +pub(crate) struct LoadedMetrics { + pub(crate) loaded_bytes: AtomicUsize, + pub(crate) loaded_compressed_bytes: AtomicUsize, + pub(crate) decompressed_bytes: AtomicUsize, +} + +impl LoadedMetrics { + fn log(&self) { + let loaded_bytes = self.loaded_bytes.load(Ordering::Relaxed); + let loaded_compressed_bytes = self.loaded_compressed_bytes.load(Ordering::Relaxed); + let decompressed_bytes = self.decompressed_bytes.load(Ordering::Relaxed); + tracing::debug!(target: "metrics", loaded_bytes, loaded_compressed_bytes, decompressed_bytes, "input_sections"); + } +} + +struct ResolutionResources<'data, 'scope, O: ObjectFile<'data>> { + definitions_per_file: &'scope Vec>>, + symbol_db: &'scope SymbolDb<'data, O>, + outputs: &'scope Outputs<'data, O>, +} + +impl<'scope, 'data, O: ObjectFile<'data>> ResolutionResources<'data, 'scope, O> { + /// Request loading of `file_id` if it hasn't already been requested. + #[inline(always)] + fn try_request_file_id(&'scope self, file_id: FileId, scope: &Scope<'scope>) { + let definitions_group = &self.definitions_per_file[file_id.group()]; + + let Some(atomic_take) = &definitions_group.get(file_id.file()) else { + // A group from a previous resolution batch. Assume that the relevant file was already + // loaded. + return; + }; + + // Do a read before we call `take`. Reads are cheaper, so this is an optimisation that + // reduces the need for exclusive access to the cache line. + if atomic_take.is_taken() { + // The definitions have previously been taken indicating that this file has already been + // processed, nothing more to do. + return; + } + + let Some(definitions_out) = atomic_take.take() else { + // Another thread just beat us to it. + return; + }; + + work_items_do( + file_id, + definitions_out, + self.symbol_db, + self.outputs, + |work_item| { + scope.spawn(|scope| { + process_object(work_item, self, scope); + }); + }, + ); + } + + fn handle_result(&self, result: Result) { + if let Err(error) = result { + let _ = self.outputs.errors.push(error); + } + } +} + +fn work_items_do<'definitions, 'data, O: ObjectFile<'data>>( + file_id: FileId, + mut definitions_out: &'definitions mut [SymbolId], + symbol_db: &SymbolDb<'data, O>, + outputs: &Outputs<'data, O>, + mut request_callback: impl FnMut(LoadObjectSymbolsRequest<'definitions>), +) { + match &symbol_db.groups[file_id.group()] { + Group::Objects(parsed_input_objects) => { + let obj = &parsed_input_objects[file_id.file()]; + let common = ResolvedCommon::new(obj); + let resolved_object = + if let Some(dynamic_tag_values) = obj.parsed.object.dynamic_tag_values() { + ResolvedFile::Dynamic(ResolvedDynamic::new(common, dynamic_tag_values)) + } else { + ResolvedFile::Object(ResolvedObject::new(common)) + }; + // Push won't fail because we allocated enough space for all the objects. + outputs.loaded.push(resolved_object).unwrap(); + } + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => { + let obj = <o_objects[file_id.file()]; + // Push won't fail because we allocated enough space for all the LTO objects. + outputs + .loaded_lto_objects + .push(ResolvedLtoInput { + file_id: obj.file_id, + symbol_id_range: obj.symbol_id_range, + }) + .unwrap(); + + request_callback(LoadObjectSymbolsRequest { + file_id, + symbol_start_offset: 0, + definitions_out, + }); + return; + } + _ => {} + } + + let chunk_size = match &symbol_db.groups[file_id.group()] { + Group::Objects(_) => MAX_SYMBOLS_PER_WORK_ITEM, + _ => definitions_out.len(), + }; + + let mut symbol_start_offset = 0; + loop { + let len = chunk_size.min(definitions_out.len()); + let chunk_definitions_out = definitions_out.split_off_mut(..len).unwrap(); + + let work_item = LoadObjectSymbolsRequest { + file_id, + definitions_out: chunk_definitions_out, + symbol_start_offset, + }; + request_callback(work_item); + + symbol_start_offset += len; + if definitions_out.is_empty() { + break; + } + } +} + +#[derive(Debug)] +pub(crate) struct ResolvedGroup<'data, O: ObjectFile<'data>> { + pub(crate) files: Vec>, +} + +#[derive(Debug)] +pub(crate) enum ResolvedFile<'data, O: ObjectFile<'data>> { + NotLoaded(NotLoaded), + Prelude(ResolvedPrelude<'data>), + Object(ResolvedObject<'data, O>), + Dynamic(ResolvedDynamic<'data, O>), + LinkerScript(ResolvedLinkerScript<'data>), + SyntheticSymbols(ResolvedSyntheticSymbols<'data>), + #[cfg(feature = "plugins")] + LtoInput(ResolvedLtoInput), +} + +#[derive(Debug)] +pub(crate) struct NotLoaded { + pub(crate) symbol_id_range: SymbolIdRange, +} + +/// A section, but where we may or may not yet have decided to load it. +#[derive(Debug, Clone, Copy)] +pub(crate) enum SectionSlot { + /// We've decided that this section won't be loaded. + Discard, + + /// The section hasn't been loaded yet, but may be loaded if it's referenced. + Unloaded(UnloadedSection), + + /// The section had the retain bit set, so must be loaded. + MustLoad(UnloadedSection), + + /// We've already loaded the section. + Loaded(crate::layout::Section), + + /// The section contains frame data, e.g. .eh_frame or equivalent. + FrameData(object::SectionIndex), + + /// The section is a string-merge section. + MergeStrings(StringMergeSectionSlot), + + // The section contains a debug info section that might be loaded. + UnloadedDebugInfo(PartId), + + // Loaded section with debug info content. + LoadedDebugInfo(crate::layout::Section), + + // GNU property section (.note.gnu.property) + NoteGnuProperty(object::SectionIndex), + + // RISC-V attributes section (.riscv.attributes) + RiscvVAttributes(object::SectionIndex), +} + +#[derive(Debug, Clone, Copy)] +pub(crate) struct UnloadedSection { + pub(crate) part_id: PartId, + + /// The index of the last FDE for this section. Previous FDEs will be linked from this. + pub(crate) last_frame_index: Option, + + /// Whether the section has a name that makes it eligible for generation of __start_ / __stop_ + /// symbols. In particular, the name of the section doesn't start with a ".". + pub(crate) start_stop_eligible: bool, +} + +impl UnloadedSection { + fn new(part_id: PartId) -> Self { + Self { + part_id, + last_frame_index: None, + start_stop_eligible: false, + } + } +} + +#[derive(Debug, Clone)] +pub(crate) struct ResolvedPrelude<'data> { + pub(crate) symbol_definitions: Vec>, +} + +/// Resolved state common to dynamic and regular objects. +#[derive(Debug)] +pub(crate) struct ResolvedCommon<'data, O: ObjectFile<'data>> { + pub(crate) input: InputRef<'data>, + pub(crate) object: &'data O, + pub(crate) file_id: FileId, + pub(crate) symbol_id_range: SymbolIdRange, +} + +#[derive(Debug)] +pub(crate) struct ResolvedObject<'data, O: ObjectFile<'data>> { + pub(crate) common: ResolvedCommon<'data, O>, + + pub(crate) sections: Vec, + pub(crate) relocations: O::RelocationSections, + + pub(crate) string_merge_extras: Vec>, + + /// Details about each custom section that is defined in this object. + custom_sections: Vec>, + + init_fini_sections: Vec, +} + +#[derive(Debug)] +pub(crate) struct ResolvedDynamic<'data, O: ObjectFile<'data>> { + pub(crate) common: ResolvedCommon<'data, O>, + dynamic_tag_values: O::DynamicTagValues, +} + +#[derive(Debug)] +pub(crate) struct ResolvedLinkerScript<'data> { + pub(crate) input: InputRef<'data>, + pub(crate) file_id: FileId, + pub(crate) symbol_id_range: SymbolIdRange, + pub(crate) symbol_definitions: Vec>, +} + +#[derive(Debug, Clone)] +pub(crate) struct ResolvedSyntheticSymbols<'data> { + pub(crate) file_id: FileId, + pub(crate) start_symbol_id: SymbolId, + pub(crate) symbol_definitions: Vec>, +} + +#[cfg(feature = "plugins")] +#[derive(Debug, Clone)] +pub(crate) struct ResolvedLtoInput { + pub(crate) file_id: FileId, + pub(crate) symbol_id_range: SymbolIdRange, +} + +fn assign_section_ids<'data, O: ObjectFile<'data>>( + resolved: &mut [ResolvedGroup<'data, O>], + output_sections: &mut OutputSections<'data>, + args: &Args, +) { + timing_phase!("Assign section IDs"); + + for group in resolved { + for file in &mut group.files { + if let ResolvedFile::Object(s) = file { + output_sections.add_sections(&s.custom_sections, s.sections.as_mut_slice(), args); + apply_init_fini_secondaries( + &s.init_fini_sections, + s.sections.as_mut_slice(), + output_sections, + ); + } + } + } +} + +fn parse_priority_suffix(suffix: &[u8]) -> Option { + if suffix.is_empty() || !suffix.iter().all(|b| b.is_ascii_digit()) { + return None; + } + + let value = core::str::from_utf8(suffix).ok()?.parse::().ok()?; + Some(u16::try_from(value).unwrap_or(u16::MAX)) +} + +fn init_fini_priority(name: &[u8]) -> Option { + if name == secnames::INIT_ARRAY_SECTION_NAME || name == secnames::FINI_ARRAY_SECTION_NAME { + return Some(u16::MAX); + } + + if let Some(rest) = name.strip_prefix(b".init_array.") { + return parse_priority_suffix(rest); + } + + if let Some(rest) = name.strip_prefix(b".fini_array.") { + return parse_priority_suffix(rest); + } + + // .ctors and .dtors without suffix have the same priority as .init_array/.fini_array + if name == secnames::CTORS_SECTION_NAME || name == secnames::DTORS_SECTION_NAME { + return Some(u16::MAX); + } + + // .ctors uses descending order (65535 = lowest priority, 0 = highest) + // while .init_array uses ascending order (0 = highest priority, 65535 = lowest) + if let Some(rest) = name.strip_prefix(b".ctors.") { + return parse_priority_suffix(rest).map(|p| u16::MAX.saturating_sub(p)); + } + + if let Some(rest) = name.strip_prefix(b".dtors.") { + return parse_priority_suffix(rest).map(|p| u16::MAX.saturating_sub(p)); + } + + None +} + +struct Outputs<'data, O: ObjectFile<'data>> { + /// Where we put objects once we've loaded them. + loaded: ArrayQueue>, + + #[cfg(feature = "plugins")] + loaded_lto_objects: ArrayQueue, + + /// Any errors that we encountered. + errors: ArrayQueue, + + undefined_symbols: SegQueue>, +} + +impl<'data, O: ObjectFile<'data>> Outputs<'data, O> { + #[allow(unused_variables)] + fn new(num_regular_objects: usize, num_lto_objects: usize) -> Self { + Self { + loaded: ArrayQueue::new(num_regular_objects.max(1)), + #[cfg(feature = "plugins")] + loaded_lto_objects: ArrayQueue::new(num_lto_objects.max(1)), + errors: ArrayQueue::new(1), + undefined_symbols: SegQueue::new(), + } + } +} + +fn process_object<'scope, 'data: 'scope, 'definitions, O: ObjectFile<'data>>( + work_item: LoadObjectSymbolsRequest<'definitions>, + resources: &'scope ResolutionResources<'data, 'scope, O>, + scope: &Scope<'scope>, +) { + let file_id = work_item.file_id; + let definitions_out = work_item.definitions_out; + + match &resources.symbol_db.groups[file_id.group()] { + Group::Prelude(prelude) => { + verbose_timing_phase!("Resolve prelude symbols"); + + load_prelude(prelude, definitions_out, resources, scope); + } + Group::Objects(parsed_input_objects) => { + verbose_timing_phase!("Resolve object symbols"); + + let obj = &parsed_input_objects[file_id.file()]; + + resources.handle_result( + resolve_symbols( + obj, + resources, + work_item.symbol_start_offset, + definitions_out, + scope, + ) + .with_context(|| format!("Failed to resolve symbols in {obj}")), + ); + } + Group::LinkerScripts(_) => {} + Group::SyntheticSymbols(_) => {} + #[cfg(feature = "plugins")] + Group::LtoInputs(objects) => { + let obj = &objects[file_id.file()]; + resources.handle_result( + resolve_lto_symbols(obj, resources, definitions_out, scope) + .with_context(|| format!("Failed to resolve symbols in {obj}")), + ); + } + } +} + +#[cfg(feature = "plugins")] +fn resolve_lto_symbols<'data, 'scope, O: ObjectFile<'data>>( + obj: &crate::linker_plugins::LtoInput<'data>, + resources: &'scope ResolutionResources<'data, 'scope, O>, + definitions_out: &mut [SymbolId], + scope: &Scope<'scope>, +) -> Result { + obj.symbols + .iter() + .enumerate() + .zip(definitions_out) + .try_for_each( + |((local_symbol_index, local_symbol), definition)| -> Result { + if !local_symbol.is_definition() { + let mut name_info = RawSymbolName::parse(local_symbol.name.bytes()); + if let Some(version) = local_symbol.version { + name_info.version_name = Some(version); + } + + let symbol_attributes = SymbolAttributes { + name_info, + is_local: false, + default_visibility: local_symbol.visibility == object::elf::STV_DEFAULT, + is_weak: local_symbol.kind + == Some(crate::linker_plugins::SymbolKind::WeakUndef), + }; + + resolve_symbol( + obj.symbol_id_range.offset_to_id(local_symbol_index), + &symbol_attributes, + definition, + resources, + false, + obj.file_id, + scope, + )?; + } + + Ok(()) + }, + ) +} + +struct UndefinedSymbol<'data> { + /// If we have a file ID here and that file is loaded, then the symbol is actually defined and + /// this record can be ignored. + ignore_if_loaded: Option, + name: PreHashedSymbolName<'data>, + symbol_id: SymbolId, +} + +fn load_prelude<'scope, 'data, O: ObjectFile<'data>>( + prelude: &crate::parsing::Prelude, + definitions_out: &mut [SymbolId], + resources: &'scope ResolutionResources<'data, 'scope, O>, + scope: &Scope<'scope>, +) { + // The start symbol could be defined within an archive entry. If it is, then we need to load + // it. We don't currently store the resulting SymbolId, but instead look it up again during + // layout. + load_symbol_named( + resources, + &mut SymbolId::undefined(), + resources.symbol_db.entry_symbol_name(), + scope, + ); + + // Try to resolve any symbols that the user requested be undefined (e.g. via --undefined). If an + // object defines such a symbol, request that the object be loaded. Also, point our undefined + // symbol record to the definition. + for (def_info, definition_out) in prelude.symbol_definitions.iter().zip(definitions_out) { + match def_info.placement { + SymbolPlacement::ForceUndefined | SymbolPlacement::DefsymSymbol(_, _) => { + load_symbol_named(resources, definition_out, def_info.name, scope); + } + _ => {} + } + } +} + +fn load_symbol_named<'scope, 'data, O: ObjectFile<'data>>( + resources: &'scope ResolutionResources<'data, 'scope, O>, + definition_out: &mut SymbolId, + name: &[u8], + scope: &Scope<'scope>, +) { + if let Some(symbol_id) = resources + .symbol_db + .get_unversioned(&UnversionedSymbolName::prehashed(name)) + { + *definition_out = symbol_id; + + let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); + resources.try_request_file_id(symbol_file_id, scope); + } +} + +/// Where there are multiple references to undefined symbols with the same name, pick one reference +/// as the canonical one to which we'll refer. Where undefined symbols can be resolved to +/// __start/__stop symbols that refer to the start or stop of a custom section, collect that +/// information up and put it into `custom_start_stop_defs`. +fn canonicalise_undefined_symbols<'data, O: ObjectFile<'data>>( + mut undefined_symbols: Vec>, + output_sections: &OutputSections, + groups: &[ResolvedGroup<'data, O>], + symbol_db: &mut SymbolDb<'data, O>, + per_symbol_flags: &mut PerSymbolFlags, + custom_start_stop_defs: &mut ResolvedSyntheticSymbols<'data>, +) { + timing_phase!("Canonicalise undefined symbols"); + + let mut name_to_id: PassThroughHashMap, SymbolId> = + Default::default(); + + let mut versioned_name_to_id: PassThroughHashMap, SymbolId> = + Default::default(); + + // Sort by symbol ID to ensure deterministic behaviour. We sort in reverse order so that LTO + // outputs get higher priority than LTO inputs. This means that the canonical symbol ID for any + // given name will be the one for the last file that refers to that symbol. + undefined_symbols.sort_by_key(|u| usize::MAX - u.symbol_id.as_usize()); + + for undefined in undefined_symbols { + let is_defined = undefined.ignore_if_loaded.is_some_and(|file_id| { + !matches!( + groups[file_id.group()].files[file_id.file()], + ResolvedFile::NotLoaded(_) + ) + }); + + if is_defined { + // The archive entry that defined the symbol in question ended up being loaded, so the + // weak symbol is defined after all. + continue; + } + + match undefined.name { + PreHashedSymbolName::Unversioned(pre_hashed) => { + match name_to_id.entry(pre_hashed) { + hashbrown::hash_map::Entry::Vacant(entry) => { + let symbol_id = allocate_start_stop_symbol_id( + pre_hashed, + symbol_db, + per_symbol_flags, + custom_start_stop_defs, + output_sections, + ); + + // We either make our undefined symbol dynamic, allowing the possibility + // that it might end up being defined at runtime, or we make it + // non-interposable, which means it'll remain null and even if it ends up + // defined at runtime, we won't use that definition. If the symbol doesn't + // have default visibility, then we make it non-interposable. If we're + // building a shared object, we always make the symbol dynamic. If we're + // building a statically linked executable, then we always make it + // non-interposable. If we're building a regular, dynamically linked + // executable, then we make it dynamic if the symbol is weak and otherwise + // make it non-interposable. That last case, a non-weak, default-visibility, + // undefined symbol in an executable is generally a link error, however if + // the flag --warn-unresolved-symbols is passed, then it won't be. Linker + // behaviour differs in this case. GNU ld makes the symbol non-interposable, + // while lld makes it dynamic. We match GNU ld in this case. + if symbol_id.is_none() { + let output_kind = symbol_db.output_kind; + let visibility = symbol_db.input_symbol_visibility(undefined.symbol_id); + + if visibility == Visibility::Default + && (output_kind.is_shared_object() + || (!output_kind.is_static_executable() + && symbol_db.symbol_strength(undefined.symbol_id, groups) + == SymbolStrength::Weak)) + { + per_symbol_flags.set_flag(undefined.symbol_id, ValueFlags::DYNAMIC); + } else { + per_symbol_flags + .set_flag(undefined.symbol_id, ValueFlags::NON_INTERPOSABLE); + } + } + + // If the symbol isn't a start/stop symbol, then assign responsibility for + // the symbol to the first object that referenced + // it. This lets us have PLT/GOT entries + // for the symbol if they're needed. + let symbol_id = symbol_id.unwrap_or(undefined.symbol_id); + entry.insert(symbol_id); + symbol_db.replace_definition(undefined.symbol_id, symbol_id); + } + hashbrown::hash_map::Entry::Occupied(entry) => { + symbol_db.replace_definition(undefined.symbol_id, *entry.get()); + } + } + } + PreHashedSymbolName::Versioned(pre_hashed) => { + match versioned_name_to_id.entry(pre_hashed) { + hashbrown::hash_map::Entry::Vacant(entry) => { + entry.insert(undefined.symbol_id); + } + hashbrown::hash_map::Entry::Occupied(entry) => { + symbol_db.replace_definition(undefined.symbol_id, *entry.get()); + } + } + } + } + } +} + +fn allocate_start_stop_symbol_id<'data, O: ObjectFile<'data>>( + name: PreHashed>, + symbol_db: &mut SymbolDb<'data, O>, + per_symbol_flags: &mut PerSymbolFlags, + custom_start_stop_defs: &mut ResolvedSyntheticSymbols<'data>, + output_sections: &OutputSections, +) -> Option { + let symbol_name_bytes = name.bytes(); + + let (section_name, is_start) = if let Some(s) = symbol_name_bytes.strip_prefix(b"__start_") { + (s, true) + } else if let Some(s) = symbol_name_bytes.strip_prefix(b"__stop_") { + (s, false) + } else { + return None; + }; + + let section_id = output_sections.custom_name_to_id(SectionName(section_name))?; + + let def_info = if is_start { + InternalSymDefInfo::new(SymbolPlacement::SectionStart(section_id), name.bytes()) + } else { + InternalSymDefInfo::new(SymbolPlacement::SectionEnd(section_id), name.bytes()) + }; + + let symbol_id = symbol_db.add_synthetic_symbol(per_symbol_flags, name, custom_start_stop_defs); + + custom_start_stop_defs.symbol_definitions.push(def_info); + + Some(symbol_id) +} + +impl<'data, O: ObjectFile<'data>> ResolvedCommon<'data, O> { + fn new(obj: &'data SequencedInputObject<'data, O>) -> Self { + Self { + input: obj.parsed.input, + object: &obj.parsed.object, + file_id: obj.file_id, + symbol_id_range: obj.symbol_id_range, + } + } + + pub(crate) fn symbol_strength(&self, symbol_id: SymbolId) -> SymbolStrength { + let local_index = symbol_id.to_input(self.symbol_id_range); + let Ok(obj_symbol) = self.object.symbol(local_index) else { + // Errors from this function should have been reported elsewhere. + return SymbolStrength::Undefined; + }; + SymbolStrength::of(obj_symbol) + } +} + +fn apply_init_fini_secondaries<'data>( + details: &[InitFiniSectionDetail], + sections: &mut [SectionSlot], + output_sections: &mut OutputSections<'data>, +) { + for d in details { + let Some(slot) = sections.get_mut(d.index as usize) else { + continue; + }; + + let unloaded = match slot { + SectionSlot::Unloaded(u) | SectionSlot::MustLoad(u) => u, + _ => continue, + }; + + let sid = + output_sections.get_or_create_init_fini_secondary(d.primary, d.priority, d.alignment); + unloaded.part_id = sid.part_id_with_alignment(d.alignment); + } +} + +impl<'data, O: ObjectFile<'data>> ResolvedObject<'data, O> { + fn new(common: ResolvedCommon<'data, O>) -> Self { + Self { + common, + // We'll fill this the rest during section resolution. + sections: Default::default(), + relocations: Default::default(), + string_merge_extras: Default::default(), + custom_sections: Default::default(), + init_fini_sections: Default::default(), + } + } +} + +impl<'data, O: ObjectFile<'data>> ResolvedDynamic<'data, O> { + fn new(common: ResolvedCommon<'data, O>, dynamic_tag_values: O::DynamicTagValues) -> Self { + Self { + common, + dynamic_tag_values, + } + } + + pub(crate) fn lib_name(&self) -> &'data [u8] { + self.dynamic_tag_values.lib_name(&self.common.input) + } +} + +fn resolve_sections_for_object<'data, O: ObjectFile<'data>>( + obj: &mut ResolvedObject<'data, O>, + args: &Args, + allocator: &bumpalo_herd::Member<'data>, + loaded_metrics: &LoadedMetrics, + rules: &SectionRules, +) -> Result> { + // Note, we build up the collection with push rather than collect because at the time of + // writing, object's `SectionTable::enumerate` isn't an exact-size iterator, so using collect + // would result in resizing. + let mut sections = Vec::with_capacity(obj.common.object.num_sections()); + for (input_section_index, input_section) in obj.common.object.enumerate_sections() { + sections.push(resolve_section( + input_section_index, + input_section, + obj, + args, + allocator, + loaded_metrics, + rules, + )?); + } + Ok(sections) +} + +#[inline(always)] +fn resolve_section<'data, O: ObjectFile<'data>>( + input_section_index: SectionIndex, + input_section: &O::SectionHeader, + obj: &mut ResolvedObject<'data, O>, + args: &Args, + allocator: &bumpalo_herd::Member<'data>, + loaded_metrics: &LoadedMetrics, + rules: &SectionRules, +) -> Result { + let section_name = obj + .common + .object + .section_name(input_section) + .unwrap_or_default(); + + if section_name.starts_with(secnames::GNU_LTO_SYMTAB_PREFIX.as_bytes()) { + if cfg!(feature = "plugins") { + bail!("Found GCC LTO input that we didn't supply to linker plugin"); + } + return Err(symbol_db::linker_plugin_disabled_error()); + } + + let section_flags = input_section.flags(); + let raw_alignment = obj.common.object.section_alignment(input_section)?; + let alignment = Alignment::new(raw_alignment.max(1))?; + let should_merge_sections = part_id::should_merge_sections(section_flags, raw_alignment, args); + + let mut unloaded_section; + let mut is_debug_info = false; + let section_type = input_section.section_type(); + let mut must_load = section_flags.should_retain() || section_type.is_note(); + + let file_name = if let Some(entry) = &obj.common.input.entry { + // For archive members, match against the member name (e.g., "app.o"), + // not the archive filename (e.g., "libfoo.a"). + Some(entry.identifier.as_slice()) + } else { + obj.common + .input + .file + .filename + .file_name() + .map(|n| n.as_encoded_bytes()) + }; + + match rules.lookup(section_name, file_name, section_flags, section_type) { + SectionRuleOutcome::Section(output_info) => { + let part_id = if output_info.section_id.is_regular() { + output_info.section_id.part_id_with_alignment(alignment) + } else { + output_info.section_id.base_part_id() + }; + + must_load |= output_info.must_keep; + + unloaded_section = UnloadedSection::new(part_id); + } + SectionRuleOutcome::SortedSection(output_info) => { + let part_id = if output_info.section_id.is_regular() { + output_info.section_id.part_id_with_alignment(alignment) + } else { + output_info.section_id.base_part_id() + }; + if let Some(priority) = init_fini_priority(section_name) { + obj.init_fini_sections.push(InitFiniSectionDetail { + index: input_section_index.0 as u32, + primary: output_info.section_id, + priority, + alignment, + }); + } + + must_load |= output_info.must_keep; + + unloaded_section = UnloadedSection::new(part_id); + } + SectionRuleOutcome::Discard => return Ok(SectionSlot::Discard), + SectionRuleOutcome::EhFrame => { + return Ok(SectionSlot::FrameData(input_section_index)); + } + SectionRuleOutcome::NoteGnuProperty => { + return Ok(SectionSlot::NoteGnuProperty(input_section_index)); + } + SectionRuleOutcome::Debug => { + if args.strip_debug() && !section_flags.is_alloc() { + return Ok(SectionSlot::Discard); + } + + is_debug_info = !section_flags.is_alloc(); + + unloaded_section = UnloadedSection::new(part_id::CUSTOM_PLACEHOLDER); + } + SectionRuleOutcome::Custom => { + unloaded_section = UnloadedSection::new(part_id::CUSTOM_PLACEHOLDER); + unloaded_section.start_stop_eligible = !section_name.starts_with(b"."); + } + SectionRuleOutcome::RiscVAttribute => { + return Ok(SectionSlot::RiscvVAttributes(input_section_index)); + } + }; + + if unloaded_section.part_id == part_id::CUSTOM_PLACEHOLDER { + let custom_section = CustomSectionDetails { + name: SectionName(section_name), + alignment, + index: input_section_index, + }; + + obj.custom_sections.push(custom_section); + } + + let slot = if should_merge_sections { + let section_data = + obj.common + .object + .section_data(input_section, allocator, loaded_metrics)?; + let section_flags = input_section.flags(); + + if section_data.is_empty() { + SectionSlot::Discard + } else { + obj.string_merge_extras.push(StringMergeSectionExtra { + index: input_section_index, + section_data, + section_flags, + }); + + SectionSlot::MergeStrings(StringMergeSectionSlot::new(unloaded_section.part_id)) + } + } else if is_debug_info { + SectionSlot::UnloadedDebugInfo(part_id::CUSTOM_PLACEHOLDER) + } else if must_load { + SectionSlot::MustLoad(unloaded_section) + } else { + SectionSlot::Unloaded(unloaded_section) + }; + + Ok(slot) +} + +fn resolve_symbols<'data, 'scope, O: ObjectFile<'data>>( + obj: &SequencedInputObject<'data, O>, + resources: &'scope ResolutionResources<'data, 'scope, O>, + start_symbol_offset: usize, + definitions_out: &mut [SymbolId], + scope: &Scope<'scope>, +) -> Result { + let verneed = obj.parsed.object.verneed_table()?; + + obj.parsed.object.symbols()[start_symbol_offset..] + .iter() + .enumerate() + .zip(definitions_out) + .try_for_each( + |((local_symbol_index, local_symbol), definition)| -> Result { + // Don't try to resolve symbols that are already defined, e.g. locals and globals + // that we define. Also don't try to resolve symbol zero - the undefined symbol. + // Hidden symbols exported from shared objects don't make sense, so we skip + // resolving them as well. + if !definition.is_undefined() + || start_symbol_offset + local_symbol_index == 0 + || (obj.is_dynamic() && local_symbol.is_hidden()) + { + return Ok(()); + } + + let name_bytes = obj.parsed.object.symbol_name(local_symbol)?; + + let name_info = if let Some(version_name) = + verneed.version_name(object::SymbolIndex(local_symbol_index)) + { + RawSymbolName { + name: name_bytes, + version_name: Some(version_name), + is_default: false, + } + } else { + RawSymbolName::parse(name_bytes) + }; + + let symbol_attributes = SymbolAttributes { + name_info, + is_local: local_symbol.is_local(), + default_visibility: local_symbol.is_interposable(), + is_weak: local_symbol.is_weak(), + }; + + resolve_symbol( + obj.symbol_id_range + .offset_to_id(start_symbol_offset + local_symbol_index), + &symbol_attributes, + definition, + resources, + obj.is_dynamic(), + obj.file_id, + scope, + ) + }, + ) +} + +#[derive(Debug)] +struct SymbolAttributes<'data> { + is_local: bool, + default_visibility: bool, + is_weak: bool, + name_info: RawSymbolName<'data>, +} + +#[inline(always)] +fn resolve_symbol<'data, 'scope, O: ObjectFile<'data>>( + local_symbol_id: SymbolId, + local_symbol_attributes: &SymbolAttributes<'data>, + definition_out: &mut SymbolId, + resources: &'scope ResolutionResources<'data, 'scope, O>, + is_dynamic: bool, + file_id: FileId, + scope: &Scope<'scope>, +) -> Result { + debug_assert_bail!( + !local_symbol_attributes.is_local, + "Only globals should be undefined, found symbol `{}` ({local_symbol_id})", + local_symbol_attributes.name_info, + ); + + let prehashed_name = PreHashedSymbolName::from_raw(&local_symbol_attributes.name_info); + + // Only default-visibility symbols can reference symbols from shared objects. + let allow_dynamic = local_symbol_attributes.default_visibility; + + match resources.symbol_db.get(&prehashed_name, allow_dynamic) { + Some(symbol_id) => { + *definition_out = symbol_id; + let symbol_file_id = resources.symbol_db.file_id_for_symbol(symbol_id); + + if symbol_file_id != file_id && !local_symbol_attributes.is_weak { + // Undefined symbols in shared objects should actually activate as-needed shared + // objects, however the rules for whether this should result in a DT_NEEDED entry + // are kind of subtle, so for now, we don't activate shared objects from shared + // objects. See + // https://github.com/wild-linker/wild/issues/930#issuecomment-3007027924 for + // more details. TODO: Fix this. + if !is_dynamic || !resources.symbol_db.file(symbol_file_id).is_dynamic() { + resources.try_request_file_id(symbol_file_id, scope); + } + } else if symbol_file_id != PRELUDE_FILE_ID { + // The symbol is weak and we can't be sure that the file that defined it will end up + // being loaded, so the symbol might actually be undefined. Register it as an + // undefined symbol then later when we handle undefined symbols, we'll check if the + // file got loaded. TODO: If the file is a non-archived object, or possibly even if + // it's an archived object that we've already decided to load, then we could skip + // this. + resources.outputs.undefined_symbols.push(UndefinedSymbol { + ignore_if_loaded: Some(symbol_file_id), + name: prehashed_name, + symbol_id: local_symbol_id, + }); + } + } + None => { + resources.outputs.undefined_symbols.push(UndefinedSymbol { + ignore_if_loaded: None, + name: prehashed_name, + symbol_id: local_symbol_id, + }); + } + } + Ok(()) +} + +impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedObject<'data, O> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.common.input, f) + } +} + +impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedDynamic<'data, O> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.common.input, f) + } +} + +impl<'data> std::fmt::Display for ResolvedLinkerScript<'data> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.input, f) + } +} + +impl<'data, O: ObjectFile<'data>> std::fmt::Display for ResolvedFile<'data, O> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ResolvedFile::NotLoaded(_) => std::fmt::Display::fmt("", f), + ResolvedFile::Prelude(_) => std::fmt::Display::fmt("", f), + ResolvedFile::Object(o) => std::fmt::Display::fmt(o, f), + ResolvedFile::Dynamic(o) => std::fmt::Display::fmt(o, f), + ResolvedFile::LinkerScript(o) => std::fmt::Display::fmt(o, f), + ResolvedFile::SyntheticSymbols(_) => std::fmt::Display::fmt("", f), + #[cfg(feature = "plugins")] + ResolvedFile::LtoInput(_) => std::fmt::Display::fmt("", f), + } + } +} + +impl SectionSlot { + pub(crate) fn is_loaded(&self) -> bool { + !matches!(self, SectionSlot::Discard | SectionSlot::Unloaded(..)) + } + + pub(crate) fn set_part_id(&mut self, part_id: PartId) { + match self { + SectionSlot::Unloaded(section) => section.part_id = part_id, + SectionSlot::MustLoad(section) => section.part_id = part_id, + SectionSlot::Loaded(section) => section.part_id = part_id, + SectionSlot::MergeStrings(section) => section.part_id = part_id, + SectionSlot::UnloadedDebugInfo(out) => *out = part_id, + SectionSlot::LoadedDebugInfo(section) => section.part_id = part_id, + SectionSlot::Discard + | SectionSlot::FrameData(_) + | SectionSlot::NoteGnuProperty(_) + | SectionSlot::RiscvVAttributes(_) => {} + } + } + + pub(crate) fn unloaded_mut(&mut self) -> Option<&mut UnloadedSection> { + match self { + SectionSlot::Unloaded(unloaded) | SectionSlot::MustLoad(unloaded) => Some(unloaded), + _ => None, + } + } +} + +impl<'data, O: ObjectFile<'data>> ResolvedFile<'data, O> { + fn symbol_id_range(&self) -> SymbolIdRange { + match self { + ResolvedFile::NotLoaded(s) => s.symbol_id_range, + ResolvedFile::Prelude(s) => s.symbol_id_range(), + ResolvedFile::Object(s) => s.common.symbol_id_range, + ResolvedFile::Dynamic(s) => s.common.symbol_id_range, + ResolvedFile::LinkerScript(s) => s.symbol_id_range, + ResolvedFile::SyntheticSymbols(s) => s.symbol_id_range(), + #[cfg(feature = "plugins")] + ResolvedFile::LtoInput(s) => s.symbol_id_range, + } + } +} + +impl ResolvedPrelude<'_> { + fn symbol_id_range(&self) -> SymbolIdRange { + SymbolIdRange::input(SymbolId::undefined(), self.symbol_definitions.len()) + } +} + +impl ResolvedSyntheticSymbols<'_> { + fn symbol_id_range(&self) -> SymbolIdRange { + SymbolIdRange::input(self.start_symbol_id, self.symbol_definitions.len()) + } +} + +impl<'data, O: ObjectFile<'data>> Default for Resolver<'data, O> { + fn default() -> Self { + Self { + undefined_symbols: Default::default(), + resolved_groups: Default::default(), + } + } +} + +// We create quite a lot of `SectionSlot`s. We don't generally copy them, however we do need to +// eventually drop the Vecs that contain them. Dropping those Vecs is a lot cheaper if the slots +// don't need to have run Drop. We check for this, by making sure the type implements `Copy` +#[test] +fn section_slot_is_copy() { + fn assert_copy(_v: T) {} + + assert_copy(SectionSlot::Discard); +} diff --git a/libwild/src/symbol_db.rs b/libwild/src/symbol_db.rs index 38d546bd7..6edc6a19d 100644 --- a/libwild/src/symbol_db.rs +++ b/libwild/src/symbol_db.rs @@ -1,2195 +1,2195 @@ -//! Reads global symbols for each input file and builds a map from symbol names to IDs together with -//! information about where each symbol can be obtained. - -use crate::input_data::InputLinkerScript; -use crate::OutputKind; -use crate::args; -use crate::args::Args; -use crate::bail; -use crate::elf::RawSymbolName; -use crate::error; -use crate::error::Context as _; -use crate::error::Error; -use crate::error::Result; -use crate::export_list::ExportList; -use crate::grouping; -use crate::grouping::Group; -use crate::grouping::SequencedInput; -use crate::grouping::SequencedInputObject; -use crate::grouping::SequencedLinkerScript; -use crate::hash::PassThroughHashMap; -use crate::hash::PreHashed; -use crate::hash::hash_bytes; -use crate::input_data::AuxiliaryFiles; -use crate::input_data::FileId; -use crate::input_data::LoadedInputs; -use crate::input_data::PRELUDE_FILE_ID; -use crate::layout_rules::LayoutRulesBuilder; -use crate::output_section_id; -use crate::output_section_id::OutputSectionId; -use crate::output_section_id::OutputSections; -use crate::parsing; -use crate::parsing::InternalSymDefInfo; -use crate::parsing::Prelude; -use crate::parsing::SymbolPlacement; -use crate::parsing::SyntheticSymbols; -use crate::platform; -use crate::platform::ObjectFile; -use crate::platform::RawSymbolName as _; -use crate::platform::SectionFlags as _; -use crate::platform::SectionHeader; -use crate::platform::Symbol; -use crate::resolution::ResolvedFile; -use crate::resolution::ResolvedGroup; -use crate::resolution::ResolvedSyntheticSymbols; -use crate::sharding::ShardKey; -use crate::symbol::PreHashedSymbolName; -use crate::symbol::UnversionedSymbolName; -use crate::symbol::VersionedSymbolName; -use crate::timing_phase; -use crate::value_flags::AtomicPerSymbolFlags; -use crate::value_flags::FlagsForSymbol; -use crate::value_flags::PerSymbolFlags; -use crate::value_flags::RawFlags; -use crate::value_flags::ValueFlags; -use crate::verbose_timing_phase; -use crate::version_script::RustVersionScript; -use crate::version_script::VersionScript; -use crossbeam_queue::SegQueue; -use hashbrown::HashMap; -use hashbrown::hash_map; -use itertools::Itertools; -use rayon::iter::IndexedParallelIterator as _; -use rayon::iter::IntoParallelRefIterator; -use rayon::iter::IntoParallelRefMutIterator as _; -use rayon::iter::ParallelIterator; -use std::fmt::Display; -use std::mem::take; -use std::sync::atomic::AtomicU32; -use std::sync::atomic::Ordering; -use symbolic_demangle::demangle; - -#[derive(Debug)] -pub struct SymbolDb<'data, O: ObjectFile<'data>> { - pub(crate) args: &'data Args, - - pub(crate) groups: Vec>, - - buckets: Vec>, - - /// Which file each symbol ID belongs to. - symbol_file_ids: Vec, - - /// Mapping from symbol IDs to the canonical definition of that symbol. For global symbols that - /// were selected as the definition and for all locals, this will point to itself. e.g. the - /// value at index 5 will be the symbol ID 5. - symbol_definitions: Vec, - - /// The names of symbols that mark the start / stop of sections. These are indexed by the - /// offset into the SyntheticSymbols' symbol IDs. - start_stop_symbol_names: Vec>, - - pub(crate) version_script: VersionScript<'data>, - pub(crate) export_list: Option>, - - /// The name of the entry symbol if overridden by a linker script. - entry: Option<&'data [u8]>, - - pub(crate) output_kind: OutputKind, - pub(crate) herd: &'data bumpalo_herd::Herd, -} - -/// Borrows from a SymbolDb, but allows temporary atomic access to some of the tables. These tables -/// are returned to the original SymbolDb when the AtomicSymbolDb is dropped. If the AtomicSymbolDb -/// gets leaked, then the tables in the original SymbolDb will remain empty. Provides some, but not -/// all of the APIs provided by SymbolDb. -struct AtomicSymbolDb<'data, 'db, O: ObjectFile<'data>> { - db: &'db mut SymbolDb<'data, O>, - definitions: Vec, -} - -#[derive(Debug)] -struct SymbolBucket<'data> { - /// Mapping from global symbol names to a symbol ID with that name. If there are multiple - /// globals with the same name, then this will point to the one we encountered first, which may - /// not be the selected definition. In order to find the selected definition, you still need to - /// look at `symbol_definitions`. - name_to_id: PassThroughHashMap, SymbolId>, - - versioned_name_to_id: PassThroughHashMap, SymbolId>, - - /// Global symbols that have multiple definitions keyed by the first symbol with that name. - alternative_definitions: HashMap>, - - /// Alternative definitions, but only for versioned symbols. This might be more efficient with - /// a proper multi-map that doesn't need a separate Vec for each value, however we don't - /// expect many entries here. - alternative_versioned_definitions: HashMap>, -} - -/// A global symbol that hasn't been put into our database yet. -#[derive(Clone, Copy)] -struct PendingSymbol<'data> { - symbol_id: SymbolId, - name: PreHashed>, -} - -#[derive(Clone, Copy)] -struct PendingVersionedSymbol<'data> { - symbol_id: SymbolId, - name: PreHashed>, -} - -/// An ID for a symbol. All symbols from all input files are allocated a unique symbol ID. The -/// symbol ID 0 is reserved for the undefined symbol. -#[derive(Clone, Copy, derive_more::Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[debug("sym-{_0}")] -pub(crate) struct SymbolId(u32); - -struct AtomicSymbolId(AtomicU32); - -/// A range of symbol IDs that are defined by the same input file. -/// -/// This exists to translate between 3 different ways of identifying a symbol: -/// - A `SymbolId` is a globally unique identifier for a symbol. -/// - An `object::SymbolIndex` is an index into the ELF symbol table of the input file. -/// - A `usize` offset is an index into our own data structures for the file. -#[derive(Clone, Copy, Debug)] -pub(crate) struct SymbolIdRange { - start_symbol_id: SymbolId, - num_symbols: usize, -} - -pub(crate) struct SymbolNameDisplay<'data> { - name: Option>, - demangle: bool, -} - -impl SymbolIdRange { - pub(crate) fn prelude(num_symbols: usize) -> SymbolIdRange { - SymbolIdRange { - start_symbol_id: SymbolId::undefined(), - num_symbols, - } - } - - pub(crate) fn input(start_symbol_id: SymbolId, num_symbols: usize) -> SymbolIdRange { - SymbolIdRange { - start_symbol_id, - num_symbols, - } - } - - pub(crate) fn len(&self) -> usize { - self.num_symbols - } - - pub(crate) fn start(&self) -> SymbolId { - self.start_symbol_id - } - - pub(crate) fn as_usize(&self) -> std::ops::Range { - self.start_symbol_id.as_usize()..self.start_symbol_id.as_usize() + self.num_symbols - } - - pub(crate) fn offset_to_id(&self, offset: usize) -> SymbolId { - debug_assert!(offset < self.num_symbols); - self.start_symbol_id.add_usize(offset) - } - - pub(crate) fn id_to_offset(&self, symbol_id: SymbolId) -> usize { - let offset = (symbol_id.0 - self.start_symbol_id.0) as usize; - debug_assert!( - offset < self.num_symbols, - "{symbol_id} not within {}..{}", - self.start_symbol_id.0, - self.start_symbol_id.0 as usize + self.num_symbols - ); - offset - } - - pub(crate) fn offset_to_input(&self, offset: usize) -> object::SymbolIndex { - debug_assert!(offset < self.num_symbols); - object::SymbolIndex(offset) - } - - pub(crate) fn input_to_offset(&self, symbol_index: object::SymbolIndex) -> usize { - let offset = symbol_index.0; - debug_assert!(offset < self.num_symbols); - offset - } - - pub(crate) fn input_to_id(&self, symbol_index: object::SymbolIndex) -> SymbolId { - self.offset_to_id(self.input_to_offset(symbol_index)) - } - - pub(crate) fn id_to_input(&self, symbol_id: SymbolId) -> object::SymbolIndex { - self.offset_to_input(self.id_to_offset(symbol_id)) - } - - /// Returns a range that covers from the start of `a` to the end of `b`. - pub(crate) fn covering(a: SymbolIdRange, b: SymbolIdRange) -> SymbolIdRange { - SymbolIdRange { - start_symbol_id: a.start_symbol_id, - num_symbols: b.start_symbol_id.as_usize() + b.len() - a.start_symbol_id.as_usize(), - } - } - - pub(crate) fn empty() -> SymbolIdRange { - Self::input(SymbolId::from_usize(0), 0) - } - - pub(crate) fn contains(&self, id: SymbolId) -> bool { - self.start() <= id && id < self.start().add_usize(self.len()) - } -} - -impl IntoIterator for SymbolIdRange { - type Item = SymbolId; - - type IntoIter = SymbolIdRangeIterator; - - fn into_iter(self) -> Self::IntoIter { - SymbolIdRangeIterator { - remaining: self.len(), - next: self.start_symbol_id, - } - } -} - -pub(crate) struct SymbolIdRangeIterator { - remaining: usize, - next: SymbolId, -} - -impl Iterator for SymbolIdRangeIterator { - type Item = SymbolId; - - fn next(&mut self) -> Option { - self.remaining = self.remaining.checked_sub(1)?; - let value = self.next; - self.next = value.next(); - Some(value) - } -} - -struct SymbolLoadOutputs<'data> { - /// Pending non-versioned symbols, grouped by hash bucket. - pending_symbols_by_bucket: Vec>, -} - -#[derive(Default, Clone)] -struct PendingSymbolHashBucket<'data> { - symbols: Vec>, - - versioned_symbols: Vec>, -} - -impl<'data, O: ObjectFile<'data>> SymbolDb<'data, O> { - /// If the version script is optimized fur rust, we downgraded all symbols to local visibility. - /// This promotes symbols marked for global visibility in a Rust version script back to global. - /// Also adds the non-interposable flag to all local symbols. - pub(crate) fn handle_rust_version_script( - &self, - rust_vscript: &RustVersionScript<'data>, - per_symbol_flags: &mut PerSymbolFlags, - ) { - verbose_timing_phase!("Upgrade locals for export"); - let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); - - rust_vscript.global.par_iter().for_each(|symbol| { - let prehashed = UnversionedSymbolName::prehashed(symbol); - if let Some(symbol_id) = self.get_unversioned(&prehashed) { - atomic_per_symbol_flags - .get_atomic(self.definition(symbol_id)) - .remove(ValueFlags::DOWNGRADE_TO_LOCAL); - } - }); - - // Don't forget to add the non-interposable flag the local symbols. - // We coudn't do this earlier as we didn't know which symbols would remain - // local. - per_symbol_flags - .flags_mut() - .par_iter_mut() - .for_each(|flags| { - let flags_val = flags.get(); - if flags_val.is_downgraded_to_local() { - *flags = (flags_val | ValueFlags::NON_INTERPOSABLE).raw(); - } - }); - } - - pub(crate) fn new( - args: &'data Args, - output_kind: OutputKind, - auxiliary: &AuxiliaryFiles<'data>, - herd: &'data bumpalo_herd::Herd, - ) -> Result { - let version_script = auxiliary - .version_script_data - .map(VersionScript::parse) - .transpose()? - .unwrap_or_default(); - - let export_list = auxiliary - .export_list_data - .map(ExportList::parse) - .transpose()?; - - let num_buckets = num_symbol_hash_buckets(args); - let mut buckets = Vec::new(); - buckets.resize_with(num_buckets, || SymbolBucket { - name_to_id: Default::default(), - versioned_name_to_id: Default::default(), - alternative_definitions: HashMap::new(), - alternative_versioned_definitions: HashMap::new(), - }); - - let mut symbol_db = SymbolDb { - args, - buckets, - symbol_file_ids: Vec::new(), - symbol_definitions: Vec::new(), - groups: Vec::new(), - start_stop_symbol_names: Default::default(), - version_script, - export_list, - entry: None, - output_kind, - herd, - }; - - for symbol in &args.export_list { - symbol_db - .export_list - .get_or_insert_default() - .add_symbol(symbol, true)?; - } - - Ok(symbol_db) - } - - pub(crate) fn add_inputs( - &mut self, - per_symbol_flags: &mut PerSymbolFlags, - output_sections: &mut OutputSections<'data>, - layout_rules_builder: &mut LayoutRulesBuilder<'data>, - loaded: LoadedInputs<'data, O>, - ) -> Result { - timing_phase!("Load inputs into symbol DB"); - - let parsed_objects = loaded.objects.into_iter().try_collect()?; - - let processed_linker_scripts = parsing::process_linker_scripts( - &loaded.linker_scripts, - output_sections, - layout_rules_builder, - )?; - - self.add_version_script_from_linker_scripts(&loaded.linker_scripts)?; - - let pre_existing_groups = self.groups.len(); - - if self.groups.is_empty() { - self.groups - .push(Group::Prelude(crate::parsing::Prelude::new::( - self.args, - self.output_kind, - ))); - } - - grouping::create_groups(self, parsed_objects, processed_linker_scripts); - - self.create_lto_input_groups(loaded.lto_objects)?; - - let new_groups = &self.groups[pre_existing_groups..]; - - let num_symbols = new_groups.iter().map(|group| group.num_symbols()).sum(); - - self.symbol_definitions.reserve(num_symbols); - per_symbol_flags.reserve(num_symbols); - self.symbol_file_ids.reserve(num_symbols); - - let mut writers = SymbolVecWriters::new( - &mut self.symbol_definitions, - &mut per_symbol_flags.flags, - &mut self.symbol_file_ids, - ); - - let mut per_group_shards = new_groups - .iter() - .map(|group| writers.new_shard(group)) - .collect_vec(); - - let per_group_outputs = read_symbols( - &self.version_script, - &mut per_group_shards, - self.args, - &self.export_list, - self.output_kind, - )?; - - populate_symbol_db(&mut self.buckets, &per_group_outputs); - - { - verbose_timing_phase!("Return shards"); - - for shard in per_group_shards { - writers.return_shard(shard); - } - } - - rayon::join( - || { - // This can take a while, so do it in parallel with other work. - verbose_timing_phase!("Drop per-group outputs"); - drop(per_group_outputs); - }, - || { - verbose_timing_phase!("Apply linker scripts"); - - for script in &loaded.linker_scripts { - self.apply_linker_script(script); - } - }, - ); - - Ok(()) - } - - #[cfg(feature = "plugins")] - fn create_lto_input_groups( - &mut self, - lto_objects: Vec>>>, - ) -> Result { - if lto_objects.is_empty() { - return Ok(()); - } - - verbose_timing_phase!("Create LTO input groups"); - - let lto_objects = lto_objects.into_iter().collect::>>()?; - - for group_objects in lto_objects - .into_iter() - .chunks(crate::input_data::MAX_FILES_PER_GROUP as usize) - .into_iter() - { - let mut next_symbol_id = self.next_symbol_id(); - let group_index = self.next_group_index(); - - self.groups.push(Group::LtoInputs( - group_objects - .into_iter() - .enumerate() - .map(|(file_index, o)| { - let symbol_id_range = SymbolIdRange::input(next_symbol_id, o.num_symbols()); - let input_obj = o.into_input_object( - FileId::new(group_index, file_index as u32), - symbol_id_range, - ); - next_symbol_id = next_symbol_id.add_usize(symbol_id_range.len()); - input_obj - }) - .collect(), - )); - } - - Ok(()) - } - - #[cfg(not(feature = "plugins"))] - #[allow( - clippy::unused_self, - clippy::needless_pass_by_value, - clippy::needless_pass_by_ref_mut - )] - fn create_lto_input_groups( - &mut self, - lto_objects: Vec>>>, - ) -> Result { - if !lto_objects.is_empty() { - return Err(linker_plugin_disabled_error()); - } - Ok(()) - } - - /// Adds a new synthetic symbol. `syn` must have been the most recently added group. - pub(crate) fn add_synthetic_symbol( - &mut self, - per_symbol_flags: &mut PerSymbolFlags, - symbol_name: PreHashed>, - syn: &ResolvedSyntheticSymbols<'data>, - ) -> SymbolId { - debug_assert_eq!(syn.file_id.group() + 1, self.groups.len()); - - let symbol_id = SymbolId::from_usize(self.symbol_definitions.len()); - - debug_assert_eq!( - symbol_id.0, - syn.start_symbol_id.0 + syn.symbol_definitions.len() as u32 - ); - - let num_buckets = self.buckets.len(); - self.buckets[symbol_name.hash() as usize % num_buckets].add_symbol(&PendingSymbol { - symbol_id, - name: symbol_name, - }); - - self.symbol_definitions.push(symbol_id); - self.start_stop_symbol_names.push(*symbol_name); - let Group::SyntheticSymbols(s) = &mut self.groups[syn.file_id.group()] else { - panic!("Tried to add synthetic symbol to non-synthetic-symbol group"); - }; - s.symbol_id_range.num_symbols += 1; - self.symbol_file_ids.push(syn.file_id); - - per_symbol_flags.push(ValueFlags::NON_INTERPOSABLE); - - symbol_id - } - - /// Applies overrides for symbols wrapped via the --wrap= argument. Note that like GNU ld, our - /// wrapping mechanism only affects resolution of undefined symbols. Defined symbols will be - /// unaffected. This means that references to a symbol from within the compilation unit that - /// defines it will not go via the wrapper. This is in contrast to LLD where wrapping also - /// affects references to symbols in compilation units where those symbols are defined. Our main - /// reason for this choice of behaviour is that it's much simpler to implement. - pub(crate) fn apply_wrapped_symbol_overrides(&mut self) { - if self.args.wrap.is_empty() { - return; - } - - verbose_timing_phase!("Apply wrapped symbol overrides"); - - let allocator = self.herd.get(); - - for name in &self.args.wrap { - let name_bytes = allocator.alloc_slice_copy(name.as_bytes()); - let orig_id = self.get_unversioned(&UnversionedSymbolName::prehashed(name_bytes)); - let wrap_name = format!("__wrap_{name}"); - if let Some(wrap_id) = - self.get_unversioned(&UnversionedSymbolName::prehashed(wrap_name.as_bytes())) - { - self.override_name(UnversionedSymbolName::prehashed(name_bytes), wrap_id); - } - - if let Some(orig_id) = orig_id { - let real_name = allocator.alloc_slice_copy(format!("__real_{name}").as_bytes()); - self.override_name(UnversionedSymbolName::prehashed(real_name), orig_id); - } - } - } - - /// Overrides `name` to point to `symbol_id`. Returns the old symbol ID for `name`. - fn override_name( - &mut self, - name: PreHashed>, - symbol_id: SymbolId, - ) -> Option { - let num_buckets = self.buckets.len(); - self.buckets[name.hash() as usize % num_buckets] - .name_to_id - .insert(name, symbol_id) - } - - /// Reads the symbol visibility from the original object. - pub(crate) fn input_symbol_visibility(&self, symbol_id: SymbolId) -> Visibility { - let file_id = self.file_id_for_symbol(symbol_id); - debug_assert!(self.file(file_id).symbol_id_range().contains(symbol_id)); - match &self.groups[file_id.group()] { - Group::Prelude(_) => Visibility::Default, - Group::Objects(parsed_input_objects) => { - let obj = &parsed_input_objects[file_id.file()]; - let local_index = symbol_id.to_input(obj.symbol_id_range); - - let Ok(obj_symbol) = obj.parsed.object.symbol(local_index) else { - return Visibility::Default; - }; - - obj_symbol.visibility() - } - Group::LinkerScripts(_) => Visibility::Default, - Group::SyntheticSymbols(_) => Visibility::Default, - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => { - lto_objects[file_id.file()].symbol_visibility(symbol_id) - } - } - } - - /// Returns a struct that can be used to print debug information about the specified symbol. - pub(crate) fn symbol_debug<'a>( - &'a self, - per_symbol_flags: &'a dyn FlagsForSymbol, - symbol_id: SymbolId, - ) -> SymbolDebug<'a, 'data, O> { - SymbolDebug { - db: self, - symbol_id, - per_symbol_flags, - } - } - - pub(crate) fn symbol_name_for_display(&self, symbol_id: SymbolId) -> SymbolNameDisplay<'data> { - SymbolNameDisplay { - name: self.symbol_name(symbol_id).ok(), - demangle: self.args.demangle, - } - } - - pub(crate) fn symbol_name(&self, symbol_id: SymbolId) -> Result> { - let file_id = self.file_id_for_symbol(symbol_id); - match &self.groups[file_id.group()] { - Group::Prelude(prelude) => Ok(prelude.symbol_name(symbol_id)), - Group::Objects(parsed_input_objects) => { - parsed_input_objects[file_id.file()].symbol_name(symbol_id) - } - Group::LinkerScripts(scripts) => Ok(scripts[file_id.file()].symbol_name(symbol_id)), - Group::SyntheticSymbols(syn) => { - Ok(self.start_stop_symbol_names[syn.symbol_id_range.id_to_offset(symbol_id)]) - } - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => Ok(lto_objects[file_id.file()].symbol_name(symbol_id)), - } - } - - /// Get the version of a symbol. Only intended for diagnostic purposes. - pub(crate) fn symbol_version_debug(&self, symbol_id: SymbolId) -> Option { - let file_id = self.file_id_for_symbol(symbol_id); - match &self.groups[file_id.group()] { - Group::Objects(parsed_input_objects) => { - parsed_input_objects[file_id.file()].symbol_version_debug(symbol_id) - } - _ => None, - } - } - - pub(crate) fn flags_for_symbol( - &self, - per_symbol_flags: &PerSymbolFlags, - symbol_id: SymbolId, - ) -> ValueFlags { - let mut flags = per_symbol_flags.flags_for_symbol(self.definition(symbol_id)); - flags.merge(per_symbol_flags.flags_for_symbol(symbol_id)); - flags - } - - pub(crate) fn num_symbols(&self) -> usize { - self.symbol_definitions.len() - } - - pub(crate) fn num_regular_objects(&self) -> usize { - self.groups - .iter() - .map(|group| match group { - Group::Objects(objects) => objects.len(), - _ => 0, - }) - .sum() - } - - pub(crate) fn num_lto_objects(&self) -> usize { - self.groups - .iter() - .map(|group| match group { - #[cfg(feature = "plugins")] - Group::LtoInputs(objects) => objects.len(), - _ => 0, - }) - .sum() - } - - /// If we have a symbol that when demangled produces `target_name`, then return the mangled - /// name. Note, this scans every symbol, so should only be used for debugging / diagnostic - /// purposes. - pub(crate) fn find_mangled_name(&self, target_name: &str) -> Option { - for i in 1..self.num_symbols() { - let symbol_id = SymbolId(i as u32); - let Ok(name) = self.symbol_name(symbol_id) else { - continue; - }; - - let Ok(name) = std::str::from_utf8(name.bytes()) else { - continue; - }; - - if demangle(name) == target_name { - return Some(name.to_owned()); - } - } - - None - } - - /// Returns our mapping from symbol IDs to the IDs that define them. Definitions should be - /// restored later by calling `restore_definitions`. While the definitions are taken, any method - /// that requires definitions will fail. - pub(crate) fn take_definitions(&mut self) -> Vec { - take(&mut self.symbol_definitions) - } - - pub(crate) fn restore_definitions(&mut self, definitions: Vec) { - self.symbol_definitions = definitions; - } - - fn borrow_atomic<'db>(&'db mut self) -> AtomicSymbolDb<'data, 'db, O> { - let definitions = self - .take_definitions() - .into_iter() - .map(|id| id.as_atomic()) - .collect(); - - AtomicSymbolDb { - db: self, - definitions, - } - } - - pub(crate) fn file_id_for_symbol(&self, symbol_id: SymbolId) -> FileId { - self.symbol_file_ids[symbol_id.as_usize()] - } - - /// Returns whether the supplied symbol ID is the canonical ID. A symbol won't be canonical, if - /// it resolves to a different symbol. The symbol may still be undefined. - pub(crate) fn is_canonical(&self, symbol_id: SymbolId) -> bool { - let resolution = self.symbol_definitions[symbol_id.as_usize()]; - resolution == symbol_id - } - - pub(crate) fn definition(&self, symbol_id: SymbolId) -> SymbolId { - // We need to do two steps when finding the definition for a symbol, since the definition - // may have changed since we did the original name lookup. It would be possible to avoid - // this, by resolving all definitions before we resolve references, except then, due to - // archive semantics, we'd need to do two passes to resolve symbols, one to determine which - // archive members to load, then a second to determine which symbols to use. - let step1 = self.symbol_definitions[symbol_id.as_usize()]; - self.symbol_definitions[step1.as_usize()] - } - - pub(crate) fn replace_definition(&mut self, symbol_id: SymbolId, new_definition: SymbolId) { - self.symbol_definitions[symbol_id.as_usize()] = new_definition; - } - - pub(crate) fn file<'db>(&'db self, file_id: FileId) -> SequencedInput<'db, 'data, O> { - match &self.groups[file_id.group()] { - Group::Prelude(prelude) => SequencedInput::Prelude(prelude), - Group::Objects(parsed_input_objects) => { - SequencedInput::Object(&parsed_input_objects[file_id.file()]) - } - Group::LinkerScripts(scripts) => SequencedInput::LinkerScript(&scripts[file_id.file()]), - Group::SyntheticSymbols(syn) => SequencedInput::SyntheticSymbols(syn), - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => SequencedInput::LtoInput(<o_objects[file_id.file()]), - } - } - - pub(crate) fn is_mapping_symbol(&self, symbol_id: SymbolId) -> bool { - let Ok(name) = self.symbol_name(symbol_id) else { - // We don't want to bother the caller with an error here. If there's a problem getting - // the name, it will be reported elsewhere. - return false; - }; - is_mapping_symbol_name(name.bytes()) - } - - pub(crate) fn get_unversioned( - &self, - prehashed: &PreHashed, - ) -> Option { - let num_buckets = self.buckets.len(); - self.buckets[prehashed.hash() as usize % num_buckets] - .name_to_id - .get(prehashed) - .copied() - } - - #[inline(always)] - pub(crate) fn get(&self, key: &PreHashedSymbolName, allow_dynamic: bool) -> Option { - let num_buckets = self.buckets.len(); - - match key { - PreHashedSymbolName::Unversioned(key) => { - let bucket = &self.buckets[key.hash() as usize % num_buckets]; - let symbol_id = bucket.name_to_id.get(key).copied()?; - - if !allow_dynamic && self.file(self.file_id_for_symbol(symbol_id)).is_dynamic() { - return bucket.get_non_dynamic(symbol_id, self); - } - - Some(symbol_id) - } - PreHashedSymbolName::Versioned(key) => { - let bucket = &self.buckets[key.hash() as usize % num_buckets]; - let symbol_id = bucket.versioned_name_to_id.get(key).copied()?; - - if !allow_dynamic && self.file(self.file_id_for_symbol(symbol_id)).is_dynamic() { - return bucket.get_non_dynamic(symbol_id, self); - } - - Some(symbol_id) - } - } - } - - pub(crate) fn all_unversioned_symbols( - &self, - ) -> impl Iterator>, &SymbolId)> { - self.buckets.iter().flat_map(|b| b.name_to_id.iter()) - } - - #[inline(always)] - pub(crate) fn symbol_strength( - &self, - symbol_id: SymbolId, - resolved: &[ResolvedGroup<'data, O>], - ) -> SymbolStrength { - let file_id = self.file_id_for_symbol(symbol_id); - match &resolved[file_id.group()].files[file_id.file()] { - ResolvedFile::Object(obj) => obj.common.symbol_strength(symbol_id), - ResolvedFile::Dynamic(obj) => obj.common.symbol_strength(symbol_id), - #[cfg(feature = "plugins")] - ResolvedFile::LtoInput(obj) => { - use crate::linker_plugins::SymbolKind; - - let SequencedInput::LtoInput(obj) = self.file(obj.file_id) else { - unreachable!(); - }; - if !obj.enabled { - return SymbolStrength::Undefined; - } - let local_index = symbol_id.to_input(obj.symbol_id_range); - let obj_symbol = &obj.symbols[local_index.0]; - match obj_symbol.kind { - Some(SymbolKind::Def) => SymbolStrength::Strong, - Some(SymbolKind::WeakDef) => SymbolStrength::Weak, - Some(SymbolKind::Common) => SymbolStrength::Common(obj_symbol.size), - _ => SymbolStrength::Undefined, - } - } - _ => SymbolStrength::Undefined, - } - } - - /// Returns whether the specified symbol is defined in a section with the SHF_GROUP flag set. - fn is_in_comdat_group( - &self, - symbol_id: SymbolId, - resolved: &[ResolvedGroup<'data, O>], - ) -> bool { - let file_id = self.file_id_for_symbol(symbol_id); - let ResolvedFile::Object(obj) = &resolved[file_id.group()].files[file_id.file()] else { - return false; - }; - - let local_index = symbol_id.to_input(obj.common.symbol_id_range); - let Ok(obj_symbol) = obj.common.object.symbol(local_index) else { - return false; - }; - - let section_index = obj_symbol.section_index(); - let Ok(header) = obj.common.object.section(section_index) else { - return false; - }; - - let flags = header.flags(); - - flags.is_group() - } - - pub(crate) fn entry_symbol_name(&self) -> &[u8] { - // The --entry flag is used first, falling back to what the linker script says, or otherwise - // defaults to `_start`. - self.args - .entry - .as_ref() - .map(|n| n.as_bytes()) - .or(self.entry) - .unwrap_or(b"_start") - } - - pub(crate) fn defsym_defined_via_cli_option(&self, symbol_name: &[u8]) -> bool { - self.args - .defsym - .iter() - .any(|(name, _)| name.as_bytes() == symbol_name) - } - - pub(crate) fn missing_defsym_target_error( - &self, - symbol_name: &[u8], - target_name: &str, - ) -> Error { - if self.defsym_defined_via_cli_option(symbol_name) { - crate::error!( - "Symbol '{}' referenced by --defsym does not exist", - target_name - ) - } else { - crate::error!( - "Undefined symbol '{}' referenced in expression", - target_name - ) - } - } - - fn apply_linker_script(&mut self, script: &InputLinkerScript<'data>) { - for cmd in &script.script.commands { - if let crate::linker_script::Command::Entry(symbol_name) = cmd { - self.entry = Some(*symbol_name); - } - } - } - - pub(crate) fn next_symbol_id(&self) -> SymbolId { - self.groups.last().map_or(SymbolId::undefined(), |group| { - let range = group.symbol_id_range(); - range.start().add_usize(range.len()) - }) - } - - pub(crate) fn new_synthetic_symbols_group(&mut self) -> ResolvedSyntheticSymbols<'data> { - let file_id = FileId::new(self.groups.len() as u32, 0); - let start_symbol_id = self.next_symbol_id(); - - self.groups.push(Group::SyntheticSymbols(SyntheticSymbols { - file_id, - symbol_id_range: SymbolIdRange::input(start_symbol_id, 0), - })); - - ResolvedSyntheticSymbols { - file_id, - start_symbol_id, - symbol_definitions: Vec::new(), - } - } - - fn add_version_script_from_linker_scripts( - &mut self, - linker_scripts: &[InputLinkerScript<'data>], - ) -> Result { - for script in linker_scripts { - // Check if the linker script contains a VERSION command - if let Some(version_content) = script.script.get_version_script_content() { - if self.version_script != VersionScript::default() { - bail!("Multiple version scripts provided"); - } - - self.version_script = VersionScript::parse(crate::input_data::ScriptData { - raw: version_content, - })?; - } - } - - Ok(()) - } - - pub(crate) fn groups_reserve(&mut self, additional: usize) { - self.groups.reserve(additional); - } - - pub(crate) fn next_group_index(&self) -> u32 { - self.groups.len() as u32 - } - - pub(crate) fn add_group(&mut self, group: Group<'data, O>) { - self.groups.push(group); - } - - #[cfg(feature = "plugins")] - pub(crate) fn disable_lto_inputs(&mut self) { - for group in &mut self.groups { - if let Group::LtoInputs(objects) = group { - for obj in objects { - obj.enabled = false; - } - } - } - } -} - -pub(crate) fn linker_plugin_disabled_error() -> Error { - error!("Wild was compiled without linker-plugin support, but LTO inputs were detected") -} - -struct SymbolVecWriters<'out> { - symbol_definitions_writer: sharded_vec_writer::VecWriter<'out, SymbolId>, - per_symbol_flags_writer: sharded_vec_writer::VecWriter<'out, RawFlags>, - symbol_file_ids_writer: sharded_vec_writer::VecWriter<'out, FileId>, -} - -impl<'out> SymbolVecWriters<'out> { - fn new( - symbol_definitions: &'out mut Vec, - per_symbol_flags: &'out mut Vec, - symbol_file_ids: &'out mut Vec, - ) -> Self { - Self { - symbol_definitions_writer: sharded_vec_writer::VecWriter::new(symbol_definitions), - per_symbol_flags_writer: sharded_vec_writer::VecWriter::new(per_symbol_flags), - symbol_file_ids_writer: sharded_vec_writer::VecWriter::new(symbol_file_ids), - } - } - - fn new_shard<'group, 'data, O: ObjectFile<'data>>( - &mut self, - group: &'group Group<'data, O>, - ) -> SymbolWriterShard<'out, 'group, 'data, O> { - let num_symbols = group.num_symbols(); - SymbolWriterShard { - group, - next: group.start_symbol_id(), - resolutions: self.symbol_definitions_writer.take_shard(num_symbols), - flags: self.per_symbol_flags_writer.take_shard(num_symbols), - file_ids: self.symbol_file_ids_writer.take_shard(num_symbols), - } - } - - fn return_shard<'data, O: ObjectFile<'data>>( - &mut self, - shard: SymbolWriterShard<'_, '_, 'data, O>, - ) { - self.symbol_definitions_writer - .return_shard(shard.resolutions); - self.per_symbol_flags_writer.return_shard(shard.flags); - self.symbol_file_ids_writer.return_shard(shard.file_ids); - } -} - -impl<'data> SymbolBucket<'data> { - fn add_symbol(&mut self, pending: &PendingSymbol<'data>) { - match self.name_to_id.entry(pending.name) { - hash_map::Entry::Occupied(entry) => { - let first_symbol_id = *entry.get(); - self.add_extra_symbol_definition(first_symbol_id, pending.symbol_id); - } - hash_map::Entry::Vacant(entry) => { - entry.insert(pending.symbol_id); - } - } - } - - fn add_versioned_symbol(&mut self, pending: &PendingVersionedSymbol<'data>) { - match self.versioned_name_to_id.entry(pending.name) { - hash_map::Entry::Occupied(entry) => { - let first_symbol_id = *entry.get(); - self.alternative_versioned_definitions - .entry(first_symbol_id) - .or_default() - .push(pending.symbol_id); - } - hash_map::Entry::Vacant(entry) => { - entry.insert(pending.symbol_id); - } - } - } - - fn add_extra_symbol_definition(&mut self, first_symbol_id: SymbolId, new_symbol_id: SymbolId) { - self.alternative_definitions - .entry(first_symbol_id) - .or_default() - .push(new_symbol_id); - } - - /// Returns the selected non-dynamic alternative to the supplied symbol, if any. - /// Among non-dynamic alternatives, selects the best one based on symbol binding: - /// strong > common (largest) > weak/gnu_unique. - fn get_non_dynamic>( - &self, - symbol_id: SymbolId, - symbol_db: &SymbolDb<'data, O>, - ) -> Option { - let alternatives = self.alternative_definitions.get(&symbol_id)?; - let mut selector = SymbolPrioritySelector::new(); - for &alt in alternatives { - let file_id = symbol_db.file_id_for_symbol(alt); - let file = symbol_db.file(file_id); - if file.is_dynamic() { - continue; - } - selector.consider(alt, file.symbol_strength(alt)); - } - selector.best() - } -} - -/// For each symbol that has multiple definitions, some of which may be weak, some strong, some -/// "common" symbols and some in archive entries that weren't loaded, resolve which version of the -/// symbol we're using. The symbol we select will be the first strongly defined symbol in a loaded -/// object, or if there are no strong definitions, then the first definition in a loaded object. If -/// a symbol definition is a common symbol, then the largest definition will be used. -pub(crate) fn resolve_alternative_symbol_definitions<'data, O: ObjectFile<'data>>( - symbol_db: &mut SymbolDb<'data, O>, - per_symbol_flags: &mut PerSymbolFlags, - resolved: &[ResolvedGroup<'data, O>], -) -> Result { - timing_phase!("Resolve alternative symbol definitions"); - - let mut buckets = take(&mut symbol_db.buckets); - let atomic_symbol_db = symbol_db.borrow_atomic(); - let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); - let error_queue = SegQueue::new(); - - buckets.par_iter_mut().for_each(|bucket| { - verbose_timing_phase!("Resolve alternative for bucket"); - - process_alternatives( - &mut bucket.alternative_definitions, - &error_queue, - &atomic_symbol_db, - &atomic_per_symbol_flags, - resolved, - ); - - process_alternatives( - &mut bucket.alternative_versioned_definitions, - &error_queue, - &atomic_symbol_db, - &atomic_per_symbol_flags, - resolved, - ); - }); - - drop(atomic_symbol_db); - - let mut duplicate_errors: Vec = error_queue.into_iter().collect(); - duplicate_errors.sort_by_key(|e| e.to_string()); - - if !duplicate_errors.is_empty() { - let error_details = duplicate_errors - .iter() - .map(|e| e.to_string()) - .collect::>() - .join("\n"); - - bail!("Duplicate symbols detected: {error_details}"); - } - - symbol_db.buckets = buckets; - - Ok(()) -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub(crate) enum Visibility { - Default, - Protected, - Hidden, -} - -impl Visibility { - pub(crate) fn from_elf_st_visibility(st_visibility: u8) -> Visibility { - match st_visibility { - object::elf::STV_PROTECTED => Visibility::Protected, - object::elf::STV_HIDDEN => Visibility::Hidden, - _ => Visibility::Default, - } - } -} - -fn process_alternatives<'data, O: ObjectFile<'data>>( - alternative_definitions: &mut HashMap>, - error_queue: &SegQueue, - symbol_db: &AtomicSymbolDb<'data, '_, O>, - per_symbol_flags: &AtomicPerSymbolFlags, - resolved: &[ResolvedGroup<'data, O>], -) { - for (first, alternatives) in std::mem::take(alternative_definitions) { - // Compute the most restrictive visibility of any of the alternative definitions. This is - // the visibility we'll use for our selected symbol. This seems like odd behaviour, but it - // matches what GNU ld appears to do and some programs will fail to link if we don't do - // this. - let visibility = alternatives - .iter() - .fold(symbol_db.input_symbol_visibility(first), |vis, id| { - vis.max(symbol_db.input_symbol_visibility(*id)) - }); - - match select_symbol(symbol_db, per_symbol_flags, first, &alternatives, resolved) { - Ok(selected) => { - symbol_db.update_definition(first, selected); - - for &alt in &alternatives { - symbol_db.update_definition(alt, selected); - } - - if visibility != Visibility::Default { - handle_non_default_visibility(per_symbol_flags, first); - - for alt in alternatives { - handle_non_default_visibility(per_symbol_flags, alt); - } - } - } - Err(err) => { - error_queue.push(err); - } - } - } -} - -/// Update value flags for `symbol_id` given that we've now changed its visibility to something -/// other than default. -fn handle_non_default_visibility(per_symbol_flags: &AtomicPerSymbolFlags, symbol_id: SymbolId) { - // TODO: Currently we only make the symbol non-interposable, but we should also actually - // change its visibility too. We need somewhere to store this information. We also need - // linker-diff to report when we get exported dynamic symbols wrong. - let flags = per_symbol_flags.get_atomic(symbol_id); - if !flags.get().contains(ValueFlags::DYNAMIC) { - flags.or_assign(ValueFlags::NON_INTERPOSABLE); - } -} - -/// Selects which version of the symbol to use. For more information on symbol priority, see -/// https://maskray.me/blog/2021-06-20-linker-symbol-resolution -#[inline(always)] -fn select_symbol<'data, O: ObjectFile<'data>>( - symbol_db: &AtomicSymbolDb<'data, '_, O>, - per_symbol_flags: &AtomicPerSymbolFlags, - first_id: SymbolId, - alternatives: &[SymbolId], - resolved: &[ResolvedGroup<'data, O>], -) -> Result { - let mut selector = SymbolPrioritySelector::new(); - - for id in std::iter::once(first_id).chain(alternatives.iter().copied()) { - let flags = per_symbol_flags.flags_for_symbol(id); - - // Dynamic symbols, even strong ones, don't override non-dynamic weak symbols, so in this - // first pass, we ignore dynamic symbols. - if flags.is_dynamic() { - continue; - } - - let strength = symbol_db.symbol_strength(id, resolved); - - // Check for duplicate strong definitions (COMDAT handling). - if matches!(strength, SymbolStrength::Strong) - && let Some(existing) = selector.first_strong - { - // We don't implement full COMDAT logic, however if we encounter duplicate - // strong definitions, then we don't emit errors if all the strong definitions - // are defined in COMDAT group sections. - if (!symbol_db.is_in_comdat_group(existing, resolved) - || !symbol_db.is_in_comdat_group(id, resolved)) - && !symbol_db.db.args.allow_multiple_definitions - { - bail!( - "{}, defined in {} and {}", - symbol_db.symbol_name_for_display(first_id), - symbol_db.file(symbol_db.file_id_for_symbol(existing)), - symbol_db.file(symbol_db.file_id_for_symbol(id)), - ); - } - } - - selector.consider(id, strength); - } - - if let Some(best) = selector.best() { - return Ok(best); - } - - // If we've made it this far, then the symbol is only defined in shared objects. Pick the first - // definition. Note, we don't check for duplicate strong definitions here because it's OK for - // multiple shared objects to define the same symbol strongly. - for alt in std::iter::once(first_id).chain(alternatives.iter().copied()) { - let strength = symbol_db.symbol_strength(alt, resolved); - if strength != SymbolStrength::Undefined { - return Ok(alt); - } - } - - Ok(first_id) -} - -#[derive(PartialEq, Eq, Clone, Copy)] -pub(crate) enum SymbolStrength { - /// The object containing this symbol wasn't loaded, so the definition can be ignored. - Undefined, - - /// The object weakly defines the symbol. - Weak, - - /// The object uses STB_GNU_UNIQUE binding. - GnuUnique, - - /// The object strongly defines the symbol. - Strong, - - /// The symbol is a "common" symbol with the specified size. The definition with the largest - /// size will be selected. - Common(u64), -} - -impl SymbolStrength { - /// Computes the binding strength of a symbol from its attributes. - pub(crate) fn of(symbol: &impl Symbol) -> Self { - if symbol.is_weak() { - SymbolStrength::Weak - } else if symbol.is_common() { - SymbolStrength::Common(symbol.size()) - } else if symbol.is_gnu_unique() { - SymbolStrength::GnuUnique - } else { - SymbolStrength::Strong - } - } -} - -/// Accumulates symbol candidates and selects the best one based on binding priority: -/// strong > common (largest) > weak/gnu_unique. -pub(crate) struct SymbolPrioritySelector { - pub(crate) first_strong: Option, - max_common: Option<(u64, SymbolId)>, - first_weak: Option, -} - -impl SymbolPrioritySelector { - pub(crate) fn new() -> Self { - Self { - first_strong: None, - max_common: None, - first_weak: None, - } - } - - /// Consider a candidate symbol with the given strength. - pub(crate) fn consider(&mut self, id: SymbolId, strength: SymbolStrength) { - match strength { - SymbolStrength::Strong => { - if self.first_strong.is_none() { - self.first_strong = Some(id); - } - } - SymbolStrength::Weak | SymbolStrength::GnuUnique => { - if self.first_weak.is_none() { - self.first_weak = Some(id); - } - } - SymbolStrength::Common(size) => match self.max_common { - Some((prev_size, _)) if size <= prev_size => {} - _ => self.max_common = Some((size, id)), - }, - SymbolStrength::Undefined => {} - } - } - - /// Returns the best symbol based on priority: strong > common (largest) > weak. - pub(crate) fn best(self) -> Option { - self.first_strong - .or(self.max_common.map(|(_, id)| id)) - .or(self.first_weak) - } -} - -/// Returns whether the supplied symbol name is for a [mapping -/// symbol](https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#mapping-symbols). -pub(crate) fn is_mapping_symbol_name(name: &[u8]) -> bool { - name.starts_with(b"$x") || name.starts_with(b"$d") || name == b"L0\x01" -} - -fn read_symbols<'data, O: ObjectFile<'data>>( - version_script: &VersionScript, - shards: &mut [SymbolWriterShard<'_, '_, 'data, O>], - args: &Args, - export_list: &Option>, - output_kind: OutputKind, -) -> Result>> { - timing_phase!("Read symbols"); - - let num_buckets = num_symbol_hash_buckets(args); - - shards - .par_iter_mut() - .map(|shard| { - read_symbols_for_group( - shard, - version_script, - export_list, - num_buckets, - args, - output_kind, - ) - }) - .collect::>>() -} - -fn read_symbols_for_group<'data, O: ObjectFile<'data>>( - shard: &mut SymbolWriterShard<'_, '_, 'data, O>, - version_script: &VersionScript, - export_list: &Option>, - num_buckets: usize, - args: &Args, - output_kind: OutputKind, -) -> Result> { - verbose_timing_phase!( - "Read group symbols", - group_id = shard.group.group_id(), - num_symbols = shard.group.num_symbols() - ); - - let mut outputs = SymbolLoadOutputs { - pending_symbols_by_bucket: vec![PendingSymbolHashBucket::default(); num_buckets], - }; - - match shard.group { - Group::Prelude(prelude) => { - prelude.load_symbols(shard, &mut outputs); - } - Group::Objects(parsed_input_objects) => { - for obj in *parsed_input_objects { - load_symbols_from_file( - obj, - version_script, - shard, - &mut outputs, - args, - export_list, - output_kind, - ) - .with_context(|| format!("Failed to load symbols from `{}`", obj.parsed.input))?; - } - } - Group::LinkerScripts(scripts) => { - for script in scripts { - load_linker_script_symbols(script, shard, &mut outputs); - } - } - Group::SyntheticSymbols(_) => { - // Custom section start/stop symbols are generated after archive handling. - } - #[cfg(feature = "plugins")] - Group::LtoInputs(lto_objects) => { - for obj in lto_objects { - load_lto_symbols(shard, &mut outputs, obj); - } - } - } - - Ok(outputs) -} - -#[cfg(feature = "plugins")] -fn load_lto_symbols<'data, O: ObjectFile<'data>>( - symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, - outputs: &mut SymbolLoadOutputs<'data>, - obj: &crate::linker_plugins::LtoInput<'data>, -) { - for (symbol_id, sym) in obj.symbols_iter() { - if sym.is_definition() { - if let Some(version) = sym.version { - outputs.add_versioned(PendingVersionedSymbol::from_prehashed( - symbol_id, - UnversionedSymbolName::prehashed(sym.name.bytes()), - version, - )); - } else { - outputs.add_non_versioned(PendingSymbol::new(symbol_id, sym.name.bytes())); - } - symbols_out.set_next(ValueFlags::empty(), symbol_id, obj.file_id); - } else { - symbols_out.set_next(ValueFlags::empty(), SymbolId::undefined(), obj.file_id); - } - } -} - -fn populate_symbol_db<'data>( - buckets: &mut [SymbolBucket<'data>], - per_group_outputs: &[SymbolLoadOutputs<'data>], -) { - timing_phase!("Populate symbol map"); - - buckets.par_iter_mut().enumerate().for_each(|(b, bucket)| { - verbose_timing_phase!("Process symbol bucket"); - - // The following approximation should be an upper bound on the number of global - // names we'll have. There will likely be at least a few global symbols with the - // same name, in which case the actual number will be slightly smaller. - let approx_num_symbols = per_group_outputs - .iter() - .map(|s| s.pending_symbols_by_bucket[b].symbols.len()) - .sum(); - bucket.name_to_id.reserve(approx_num_symbols); - - for outputs in per_group_outputs { - let pending = &outputs.pending_symbols_by_bucket[b]; - - for symbol in &pending.symbols { - bucket.add_symbol(symbol); - } - - for symbol in &pending.versioned_symbols { - bucket.add_versioned_symbol(symbol); - } - } - }); -} - -fn load_linker_script_symbols<'data, O: ObjectFile<'data>>( - script: &SequencedLinkerScript<'data>, - symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, - outputs: &mut SymbolLoadOutputs<'data>, -) { - for (offset, definition) in script.parsed.symbol_defs.iter().enumerate() { - let symbol_id = script.symbol_id_range.offset_to_id(offset); - - outputs.add_non_versioned(PendingSymbol::from_prehashed( - symbol_id, - PreHashed::new( - UnversionedSymbolName::new(definition.name), - hash_bytes(definition.name), - ), - )); - - let mut flags = ValueFlags::NON_INTERPOSABLE; - // PROVIDE_HIDDEN symbols have hidden visibility, which means they should be - // non-interposable (already set) and not exported to dynamic symbol table. - if definition.is_hidden { - flags |= ValueFlags::DOWNGRADE_TO_LOCAL; - } - symbols_out.set_next(flags, symbol_id, script.file_id); - } -} - -fn load_symbols_from_file<'data, O: ObjectFile<'data>>( - s: &SequencedInputObject<'data, O>, - version_script: &VersionScript, - symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, - outputs: &mut SymbolLoadOutputs<'data>, - args: &Args, - export_list: &Option>, - output_kind: OutputKind, -) -> Result { - if s.is_dynamic() { - DynamicObjectSymbolLoader::new(&s.parsed.object)?.load_symbols( - s.file_id, - symbols_out, - outputs, - ) - } else { - RegularObjectSymbolLoader { - object: &s.parsed.object, - args, - version_script, - archive_semantics: s.parsed.input.has_archive_semantics(), - lib_name: s.parsed.input.lib_name(), - export_list, - output_kind, - } - .load_symbols(s.file_id, symbols_out, outputs) - } -} - -struct SymbolWriterShard<'out, 'group, 'data, O: ObjectFile<'data>> { - group: &'group Group<'data, O>, - resolutions: sharded_vec_writer::Shard<'out, SymbolId>, - flags: sharded_vec_writer::Shard<'out, RawFlags>, - file_ids: sharded_vec_writer::Shard<'out, FileId>, - next: SymbolId, -} - -impl<'out, 'group, 'data, O: ObjectFile<'data>> SymbolWriterShard<'out, 'group, 'data, O> { - fn set_next(&mut self, flags: ValueFlags, resolution: SymbolId, file_id: FileId) { - self.flags.push(flags.raw()); - self.resolutions.push(resolution); - self.file_ids.push(file_id); - self.next = SymbolId::from_usize(self.next.as_usize() + 1); - } -} - -trait SymbolLoader<'data, O: ObjectFile<'data>> { - fn load_symbols( - &self, - file_id: FileId, - symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, - outputs: &mut SymbolLoadOutputs<'data>, - ) -> Result { - let base_symbol_id = symbols_out.next; - - for symbol in self.object().symbols_iter() { - let symbol_id = symbols_out.next; - let mut flags = self.compute_value_flags(symbol); - - if symbol.is_undefined() || self.should_ignore_symbol(symbol) { - symbols_out.set_next(flags, SymbolId::undefined(), file_id); - continue; - } - - let resolution = symbol_id; - - let local_index = symbol_id.offset_from(base_symbol_id); - - if symbol.is_local() { - symbols_out.set_next(flags, resolution, file_id); - continue; - } - - let info = self.get_symbol_name_and_version(symbol, local_index)?; - - let name = UnversionedSymbolName::prehashed(info.name()); - - if self.should_downgrade_to_local(&name) { - flags |= ValueFlags::DOWNGRADE_TO_LOCAL; - // If we're downgrading to a local, then we're writing a shared object. Shared - // objects should never bypass the GOT for TLS variables. However, if we're - // downgrading all symbols by default, that'd add the flag to all symbols, so we - // have to do this later. - if !self.downgrades_all() && !symbol.is_tls() { - flags |= ValueFlags::NON_INTERPOSABLE; - } - } - - if info.is_default() { - let pending = PendingSymbol::from_prehashed(symbol_id, name); - outputs.add_non_versioned(pending); - } - - if let Some(version) = info.version_name() { - let pending = PendingVersionedSymbol::from_prehashed(symbol_id, name, version); - outputs.add_versioned(pending); - } - - symbols_out.set_next(flags, resolution, file_id); - } - - Ok(()) - } - - fn object(&self) -> &O; - - fn compute_value_flags(&self, symbol: &O::Symbol) -> ValueFlags; - - /// Returns whether we should downgrade a symbol with the specified name to be a local. - fn should_downgrade_to_local(&self, _name: &PreHashed) -> bool { - false - } - - /// Returns whether we will downgrade all symbols by default and later upgrade some to global. - fn downgrades_all(&self) -> bool { - false - } - - /// Returns whether the supplied symbol should be ignore. - fn should_ignore_symbol(&self, _symbol: &O::Symbol) -> bool { - false - } - - fn get_symbol_name_and_version( - &self, - symbol: &O::Symbol, - local_index: usize, - ) -> Result; -} - -struct RegularObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { - object: &'a O, - args: &'a Args, - version_script: &'a VersionScript<'a>, - archive_semantics: bool, - lib_name: &'data [u8], - export_list: &'a Option>, - output_kind: OutputKind, -} - -struct DynamicObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { - object: &'a O, - version_names: O::VersionNames, -} - -impl<'a, 'data, O: ObjectFile<'data>> DynamicObjectSymbolLoader<'a, 'data, O> { - fn new(object: &'a O) -> Result { - let version_names = object.get_version_names()?; - Ok(Self { - object, - version_names, - }) - } -} - -impl<'data, O: ObjectFile<'data>> SymbolLoader<'data, O> - for RegularObjectSymbolLoader<'_, 'data, O> -{ - fn compute_value_flags(&self, sym: &O::Symbol) -> ValueFlags { - let is_undefined = sym.is_undefined(); - - let symbol_is_exported = || { - if let Some(export_list) = &self.export_list - && let Ok(symbol_name) = self.object.symbol_name(sym) - && !&export_list.contains(&UnversionedSymbolName::prehashed(symbol_name)) - { - return false; - } - true - }; - let non_interposable = !sym.is_interposable() - || sym.is_local() - || self.output_kind.is_static_executable() - // Symbols defined in an executable cannot be interposed since the executable is always the - // first place checked for a symbol by the dynamic loader. - || (!is_undefined && ( - self.output_kind.is_executable() - || (self.archive_semantics && self.args.exclude_libs.should_exclude(self.lib_name)) - || ( - self.args.b_symbolic == args::BSymbolicKind::All - // `-Bsymbolic-functions` - || ( - self.args.b_symbolic == args::BSymbolicKind::Functions - && sym.is_func() - ) - // `-Bsymbolic-non-weak` - || ( - self.args.b_symbolic == args::BSymbolicKind::NonWeak - && !sym.is_weak() - ) - // `-Bsymbolic-non-weak-functions` - || ( - self.args.b_symbolic == args::BSymbolicKind::NonWeakFunctions - && (sym.is_func() - && !sym.is_weak()) - ) - ) - // Bsymbolic does not affect symbols that are exported - && !(self.export_list.is_some() && symbol_is_exported()) - )); - - let mut flags: ValueFlags = if sym.is_absolute() { - ValueFlags::ABSOLUTE - } else if sym.is_ifunc() { - ValueFlags::IFUNC - } else if is_undefined { - // For undefined symbols, we tweak some of the flags later on in - // `canonicalise_undefined_symbols`. We can't make those decisions now because we don't - // know whether the symbol will remain undefined. - ValueFlags::ABSOLUTE - } else { - ValueFlags::empty() - }; - - if non_interposable { - flags |= ValueFlags::NON_INTERPOSABLE; - } - flags - } - - fn should_downgrade_to_local(&self, name: &PreHashed) -> bool { - match self.version_script { - // We first downgrade all symbols when using a Rust version script. - // We're gonna set the ones that are exported back to global later. - VersionScript::Rust(_) => true, - VersionScript::Regular(version_script) => version_script.is_local(name), - } - } - - fn downgrades_all(&self) -> bool { - matches!(self.version_script, VersionScript::Rust(_)) - } - - fn get_symbol_name_and_version( - &self, - symbol: &O::Symbol, - _local_index: usize, - ) -> Result { - Ok(::parse( - self.object.symbol_name(symbol)?, - )) - } - - fn object(&self) -> &O { - self.object - } -} - -impl<'data, O: ObjectFile<'data>> SymbolLoader<'data, O> - for DynamicObjectSymbolLoader<'_, 'data, O> -{ - fn compute_value_flags(&self, symbol: &O::Symbol) -> ValueFlags { - let mut flags = ValueFlags::DYNAMIC; - if symbol.is_func() || symbol.is_ifunc() { - flags |= ValueFlags::FUNCTION; - } - if symbol.is_undefined() { - flags |= ValueFlags::ABSOLUTE; - } - flags - } - - fn get_symbol_name_and_version( - &self, - symbol: &O::Symbol, - local_index: usize, - ) -> Result { - self.object - .get_symbol_name_and_version(symbol, local_index, &self.version_names) - } - - fn object(&self) -> &O { - self.object - } - - fn should_ignore_symbol(&self, symbol: &O::Symbol) -> bool { - // Shared objects shouldn't export hidden symbols. If for some reason they do, ignore them. - symbol.is_hidden() - } -} - -#[derive(Clone, Copy)] -pub(crate) struct SymbolDebug<'a, 'data, O: ObjectFile<'data>> { - db: &'a SymbolDb<'data, O>, - symbol_id: SymbolId, - per_symbol_flags: &'a dyn FlagsForSymbol, -} - -impl<'a, 'data, O: ObjectFile<'data>> std::fmt::Display for SymbolDebug<'a, 'data, O> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let symbol_id = self.symbol_id; - let definition = self.db.definition(symbol_id); - let file_id = self.db.file_id_for_symbol(symbol_id); - let file = self.db.file(file_id); - let symbol_id_range = file.symbol_id_range(); - - if !symbol_id_range.contains(symbol_id) { - write!( - f, - "SymbolId {symbol_id} is owned by {file_id}, but that file has range {}..{}", - symbol_id_range.start(), - symbol_id_range.start().add_usize(symbol_id_range.len()) - )?; - // If ID ranges or file mappings are wrong, then the code later in this method, e.g. - // `id_to_offset` or `symbol_name` will panic. - return Ok(()); - } - - let local_index = symbol_id.to_offset(symbol_id_range); - let symbol_name = self - .db - .symbol_name(symbol_id) - .unwrap_or_else(|_| UnversionedSymbolName::new(b"??")); - - if definition.is_undefined() { - write!(f, "undefined ")?; - } - - if symbol_name.bytes().is_empty() { - match file { - SequencedInput::Prelude(_) => write!(f, "")?, - SequencedInput::Object(o) => { - let symbol_index = symbol_id.to_input(symbol_id_range); - if let Some(section_name) = o - .parsed - .object - .symbol(symbol_index) - .ok() - .and_then(|symbol| { - o.parsed - .object - .symbol_section(symbol, symbol_index) - .ok() - .flatten() - }) - .map(|section_index| o.parsed.object.section_display_name(section_index)) - { - write!(f, "section `{section_name}`")?; - } else { - write!(f, "")?; - } - } - SequencedInput::LinkerScript(s) => { - write!(f, "Symbol from linker script `{}`", s.parsed.input)?; - } - SequencedInput::SyntheticSymbols(_) => { - write!(f, "")?; - } - #[cfg(feature = "plugins")] - SequencedInput::LtoInput(_) => write!(f, "")?, - } - } else { - write!(f, "symbol `{}`", self.db.symbol_name_for_display(symbol_id))?; - } - - write!( - f, - " ({symbol_id} local={local_index}) in file #{file_id} ({file})" - )?; - - if symbol_id != definition && !definition.is_undefined() { - let definition_file_id = self.db.file_id_for_symbol(definition); - let definition_file = self.db.file(definition_file_id); - write!( - f, - " defined as {definition} in file #{definition_file_id} ({definition_file})" - )?; - } - - let flags = self.per_symbol_flags.flags_for_symbol(symbol_id); - write!(f, " ({flags})")?; - - Ok(()) - } -} - -impl SymbolId { - pub(crate) fn undefined() -> Self { - Self(0) - } - - pub(crate) fn from_usize(value: usize) -> SymbolId { - Self::new(u32::try_from(value).expect("Symbols overflowed 32 bits")) - } - - pub(crate) fn as_usize(self) -> usize { - self.0 as usize - } - - const fn new(value: u32) -> SymbolId { - SymbolId(value) - } - - pub(crate) fn offset_from(self, base: SymbolId) -> usize { - (self.0 - base.0) as usize - } - - pub(crate) fn to_offset(self, range: SymbolIdRange) -> usize { - range.id_to_offset(self) - } - - pub(crate) fn to_input(self, range: SymbolIdRange) -> object::SymbolIndex { - range.id_to_input(self) - } - - pub(crate) fn is_undefined(self) -> bool { - self.0 == 0 - } - - pub(crate) fn next(self) -> Self { - Self(self.0 + 1) - } - - fn as_atomic(self) -> AtomicSymbolId { - AtomicSymbolId(AtomicU32::new(self.0)) - } -} - -impl AtomicSymbolId { - fn store(&self, selected: SymbolId) { - self.0.store(selected.0, Ordering::Relaxed); - } - - fn into_non_atomic(self) -> SymbolId { - SymbolId(self.0.into_inner()) - } -} - -impl TryFrom for SymbolId { - type Error = crate::error::Error; - - fn try_from(value: usize) -> std::result::Result { - Ok(SymbolId(u32::try_from(value).context("Too many symbols")?)) - } -} - -impl<'data> Prelude<'data> { - fn load_symbols>( - &self, - symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, - outputs: &mut SymbolLoadOutputs<'data>, - ) { - for definition in &self.symbol_definitions { - let symbol_id = symbols_out.next; - let mut flags = match definition.placement { - SymbolPlacement::Undefined | SymbolPlacement::ForceUndefined => { - ValueFlags::ABSOLUTE - } - SymbolPlacement::DefsymAbsolute(_) => { - outputs.add_non_versioned(PendingSymbol::new(symbol_id, definition.name)); - ValueFlags::NON_INTERPOSABLE | ValueFlags::ABSOLUTE - } - SymbolPlacement::SectionStart(_) - | SymbolPlacement::SectionEnd(_) - | SymbolPlacement::SectionGroupEnd(_) - | SymbolPlacement::DefsymSymbol(_, _) - | SymbolPlacement::LoadBaseAddress => { - outputs.add_non_versioned(PendingSymbol::new(symbol_id, definition.name)); - ValueFlags::NON_INTERPOSABLE - } - }; - if definition.is_hidden { - flags |= ValueFlags::DOWNGRADE_TO_LOCAL; - } - symbols_out.set_next(flags, symbol_id, PRELUDE_FILE_ID); - } - } -} - -impl std::fmt::Display for SymbolId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.fmt(f) - } -} - -impl InternalSymDefInfo<'_> { - pub(crate) fn section_id(self) -> Option { - match self.placement { - SymbolPlacement::Undefined - | SymbolPlacement::ForceUndefined - | SymbolPlacement::DefsymAbsolute(_) - | SymbolPlacement::DefsymSymbol(_, _) => None, - SymbolPlacement::SectionStart(i) => Some(i), - SymbolPlacement::SectionEnd(i) => Some(i), - SymbolPlacement::SectionGroupEnd(i) => Some(i), - // The other linkers attach to the closest section, but the address is nonetheless - // outside of the selected section. It's tricky for us to find the the closest section - // at this point in the code, so we pick an arbitrary section. - SymbolPlacement::LoadBaseAddress => Some(output_section_id::TEXT), - } - } -} - -impl<'data> PendingSymbol<'data> { - fn new(symbol_id: SymbolId, name: &'data [u8]) -> PendingSymbol<'data> { - Self::from_prehashed(symbol_id, UnversionedSymbolName::prehashed(name)) - } - - fn from_prehashed( - symbol_id: SymbolId, - name: PreHashed>, - ) -> PendingSymbol<'data> { - PendingSymbol { symbol_id, name } - } -} - -impl<'data> PendingVersionedSymbol<'data> { - fn from_prehashed( - symbol_id: SymbolId, - name: PreHashed>, - version: &'data [u8], - ) -> PendingVersionedSymbol<'data> { - PendingVersionedSymbol { - symbol_id, - name: VersionedSymbolName::prehashed(name, version), - } - } -} - -/// Decides how many buckets we should use for symbol names. -fn num_symbol_hash_buckets(args: &Args) -> usize { - args.available_threads.get() -} - -impl<'data> SymbolLoadOutputs<'data> { - fn add_non_versioned(&mut self, pending: PendingSymbol<'data>) { - let num_buckets = self.pending_symbols_by_bucket.len(); - - self.pending_symbols_by_bucket[pending.name.hash() as usize % num_buckets] - .symbols - .push(pending); - } - - fn add_versioned(&mut self, pending: PendingVersionedSymbol<'data>) { - let num_buckets = self.pending_symbols_by_bucket.len(); - - self.pending_symbols_by_bucket[pending.name.hash() as usize % num_buckets] - .versioned_symbols - .push(pending); - } -} - -impl<'data, 'db, O: ObjectFile<'data>> AtomicSymbolDb<'data, 'db, O> { - fn input_symbol_visibility(&self, symbol_id: SymbolId) -> Visibility { - self.db.input_symbol_visibility(symbol_id) - } - - fn update_definition(&self, to_update: SymbolId, new_definition: SymbolId) { - self.definitions[to_update.as_usize()].store(new_definition); - } - - fn symbol_strength( - &self, - symbol_id: SymbolId, - resolved: &[ResolvedGroup<'data, O>], - ) -> SymbolStrength { - self.db.symbol_strength(symbol_id, resolved) - } - - fn is_in_comdat_group( - &self, - symbol_id: SymbolId, - resolved: &[ResolvedGroup<'data, O>], - ) -> bool { - self.db.is_in_comdat_group(symbol_id, resolved) - } - - fn symbol_name_for_display(&self, symbol_id: SymbolId) -> SymbolNameDisplay<'data> { - self.db.symbol_name_for_display(symbol_id) - } - - fn file(&'db self, file_id: FileId) -> SequencedInput<'db, 'data, O> { - self.db.file(file_id) - } - - fn file_id_for_symbol(&self, symbol_id: SymbolId) -> FileId { - self.db.file_id_for_symbol(symbol_id) - } -} - -impl<'data, O: ObjectFile<'data>> Drop for AtomicSymbolDb<'data, '_, O> { - fn drop(&mut self) { - // Convert our atomic tables back to non-atomic tables and return them to the symbol-db that - // we took them from. This operation should be basically free, at least in optimised builds. - self.db.restore_definitions( - take(&mut self.definitions) - .into_iter() - .map(|id| id.into_non_atomic()) - .collect(), - ); - } -} - -impl ShardKey for SymbolId { - fn zero() -> Self { - SymbolId(0) - } - - fn add_usize(self, offset: usize) -> Self { - SymbolId( - (self.as_usize() + offset) - .try_into() - .expect("Symbol ID overflowed 32 bits"), - ) - } -} - -impl Display for RawSymbolName<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", String::from_utf8_lossy(self.name))?; - if let Some(version) = self.version_name { - if self.is_default { - write!(f, "@@")?; - } else { - write!(f, "@")?; - } - write!(f, "{}", String::from_utf8_lossy(version))?; - } - - Ok(()) - } -} - -impl Display for SymbolNameDisplay<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(name) = self.name { - if let Ok(s) = std::str::from_utf8(name.bytes()) { - if self.demangle { - Display::fmt(&symbolic_demangle::demangle(s), f) - } else { - Display::fmt(s, f) - } - } else { - write!(f, "INVALID UTF-8({:?})", name.bytes()) - } - } else { - write!(f, "SYMBOL-READ-ERROR") - } - } -} +//! Reads global symbols for each input file and builds a map from symbol names to IDs together with +//! information about where each symbol can be obtained. + +use crate::input_data::InputLinkerScript; +use crate::OutputKind; +use crate::args; +use crate::args::Args; +use crate::bail; +use crate::elf::RawSymbolName; +use crate::error; +use crate::error::Context as _; +use crate::error::Error; +use crate::error::Result; +use crate::export_list::ExportList; +use crate::grouping; +use crate::grouping::Group; +use crate::grouping::SequencedInput; +use crate::grouping::SequencedInputObject; +use crate::grouping::SequencedLinkerScript; +use crate::hash::PassThroughHashMap; +use crate::hash::PreHashed; +use crate::hash::hash_bytes; +use crate::input_data::AuxiliaryFiles; +use crate::input_data::FileId; +use crate::input_data::LoadedInputs; +use crate::input_data::PRELUDE_FILE_ID; +use crate::layout_rules::LayoutRulesBuilder; +use crate::output_section_id; +use crate::output_section_id::OutputSectionId; +use crate::output_section_id::OutputSections; +use crate::parsing; +use crate::parsing::InternalSymDefInfo; +use crate::parsing::Prelude; +use crate::parsing::SymbolPlacement; +use crate::parsing::SyntheticSymbols; +use crate::platform; +use crate::platform::ObjectFile; +use crate::platform::RawSymbolName as _; +use crate::platform::SectionFlags as _; +use crate::platform::SectionHeader; +use crate::platform::Symbol; +use crate::resolution::ResolvedFile; +use crate::resolution::ResolvedGroup; +use crate::resolution::ResolvedSyntheticSymbols; +use crate::sharding::ShardKey; +use crate::symbol::PreHashedSymbolName; +use crate::symbol::UnversionedSymbolName; +use crate::symbol::VersionedSymbolName; +use crate::timing_phase; +use crate::value_flags::AtomicPerSymbolFlags; +use crate::value_flags::FlagsForSymbol; +use crate::value_flags::PerSymbolFlags; +use crate::value_flags::RawFlags; +use crate::value_flags::ValueFlags; +use crate::verbose_timing_phase; +use crate::version_script::RustVersionScript; +use crate::version_script::VersionScript; +use crossbeam_queue::SegQueue; +use hashbrown::HashMap; +use hashbrown::hash_map; +use itertools::Itertools; +use rayon::iter::IndexedParallelIterator as _; +use rayon::iter::IntoParallelRefIterator; +use rayon::iter::IntoParallelRefMutIterator as _; +use rayon::iter::ParallelIterator; +use std::fmt::Display; +use std::mem::take; +use std::sync::atomic::AtomicU32; +use std::sync::atomic::Ordering; +use symbolic_demangle::demangle; + +#[derive(Debug)] +pub struct SymbolDb<'data, O: ObjectFile<'data>> { + pub(crate) args: &'data Args, + + pub(crate) groups: Vec>, + + buckets: Vec>, + + /// Which file each symbol ID belongs to. + symbol_file_ids: Vec, + + /// Mapping from symbol IDs to the canonical definition of that symbol. For global symbols that + /// were selected as the definition and for all locals, this will point to itself. e.g. the + /// value at index 5 will be the symbol ID 5. + symbol_definitions: Vec, + + /// The names of symbols that mark the start / stop of sections. These are indexed by the + /// offset into the SyntheticSymbols' symbol IDs. + start_stop_symbol_names: Vec>, + + pub(crate) version_script: VersionScript<'data>, + pub(crate) export_list: Option>, + + /// The name of the entry symbol if overridden by a linker script. + entry: Option<&'data [u8]>, + + pub(crate) output_kind: OutputKind, + pub(crate) herd: &'data bumpalo_herd::Herd, +} + +/// Borrows from a SymbolDb, but allows temporary atomic access to some of the tables. These tables +/// are returned to the original SymbolDb when the AtomicSymbolDb is dropped. If the AtomicSymbolDb +/// gets leaked, then the tables in the original SymbolDb will remain empty. Provides some, but not +/// all of the APIs provided by SymbolDb. +struct AtomicSymbolDb<'data, 'db, O: ObjectFile<'data>> { + db: &'db mut SymbolDb<'data, O>, + definitions: Vec, +} + +#[derive(Debug)] +struct SymbolBucket<'data> { + /// Mapping from global symbol names to a symbol ID with that name. If there are multiple + /// globals with the same name, then this will point to the one we encountered first, which may + /// not be the selected definition. In order to find the selected definition, you still need to + /// look at `symbol_definitions`. + name_to_id: PassThroughHashMap, SymbolId>, + + versioned_name_to_id: PassThroughHashMap, SymbolId>, + + /// Global symbols that have multiple definitions keyed by the first symbol with that name. + alternative_definitions: HashMap>, + + /// Alternative definitions, but only for versioned symbols. This might be more efficient with + /// a proper multi-map that doesn't need a separate Vec for each value, however we don't + /// expect many entries here. + alternative_versioned_definitions: HashMap>, +} + +/// A global symbol that hasn't been put into our database yet. +#[derive(Clone, Copy)] +struct PendingSymbol<'data> { + symbol_id: SymbolId, + name: PreHashed>, +} + +#[derive(Clone, Copy)] +struct PendingVersionedSymbol<'data> { + symbol_id: SymbolId, + name: PreHashed>, +} + +/// An ID for a symbol. All symbols from all input files are allocated a unique symbol ID. The +/// symbol ID 0 is reserved for the undefined symbol. +#[derive(Clone, Copy, derive_more::Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[debug("sym-{_0}")] +pub(crate) struct SymbolId(u32); + +struct AtomicSymbolId(AtomicU32); + +/// A range of symbol IDs that are defined by the same input file. +/// +/// This exists to translate between 3 different ways of identifying a symbol: +/// - A `SymbolId` is a globally unique identifier for a symbol. +/// - An `object::SymbolIndex` is an index into the ELF symbol table of the input file. +/// - A `usize` offset is an index into our own data structures for the file. +#[derive(Clone, Copy, Debug)] +pub(crate) struct SymbolIdRange { + start_symbol_id: SymbolId, + num_symbols: usize, +} + +pub(crate) struct SymbolNameDisplay<'data> { + name: Option>, + demangle: bool, +} + +impl SymbolIdRange { + pub(crate) fn prelude(num_symbols: usize) -> SymbolIdRange { + SymbolIdRange { + start_symbol_id: SymbolId::undefined(), + num_symbols, + } + } + + pub(crate) fn input(start_symbol_id: SymbolId, num_symbols: usize) -> SymbolIdRange { + SymbolIdRange { + start_symbol_id, + num_symbols, + } + } + + pub(crate) fn len(&self) -> usize { + self.num_symbols + } + + pub(crate) fn start(&self) -> SymbolId { + self.start_symbol_id + } + + pub(crate) fn as_usize(&self) -> std::ops::Range { + self.start_symbol_id.as_usize()..self.start_symbol_id.as_usize() + self.num_symbols + } + + pub(crate) fn offset_to_id(&self, offset: usize) -> SymbolId { + debug_assert!(offset < self.num_symbols); + self.start_symbol_id.add_usize(offset) + } + + pub(crate) fn id_to_offset(&self, symbol_id: SymbolId) -> usize { + let offset = (symbol_id.0 - self.start_symbol_id.0) as usize; + debug_assert!( + offset < self.num_symbols, + "{symbol_id} not within {}..{}", + self.start_symbol_id.0, + self.start_symbol_id.0 as usize + self.num_symbols + ); + offset + } + + pub(crate) fn offset_to_input(&self, offset: usize) -> object::SymbolIndex { + debug_assert!(offset < self.num_symbols); + object::SymbolIndex(offset) + } + + pub(crate) fn input_to_offset(&self, symbol_index: object::SymbolIndex) -> usize { + let offset = symbol_index.0; + debug_assert!(offset < self.num_symbols); + offset + } + + pub(crate) fn input_to_id(&self, symbol_index: object::SymbolIndex) -> SymbolId { + self.offset_to_id(self.input_to_offset(symbol_index)) + } + + pub(crate) fn id_to_input(&self, symbol_id: SymbolId) -> object::SymbolIndex { + self.offset_to_input(self.id_to_offset(symbol_id)) + } + + /// Returns a range that covers from the start of `a` to the end of `b`. + pub(crate) fn covering(a: SymbolIdRange, b: SymbolIdRange) -> SymbolIdRange { + SymbolIdRange { + start_symbol_id: a.start_symbol_id, + num_symbols: b.start_symbol_id.as_usize() + b.len() - a.start_symbol_id.as_usize(), + } + } + + pub(crate) fn empty() -> SymbolIdRange { + Self::input(SymbolId::from_usize(0), 0) + } + + pub(crate) fn contains(&self, id: SymbolId) -> bool { + self.start() <= id && id < self.start().add_usize(self.len()) + } +} + +impl IntoIterator for SymbolIdRange { + type Item = SymbolId; + + type IntoIter = SymbolIdRangeIterator; + + fn into_iter(self) -> Self::IntoIter { + SymbolIdRangeIterator { + remaining: self.len(), + next: self.start_symbol_id, + } + } +} + +pub(crate) struct SymbolIdRangeIterator { + remaining: usize, + next: SymbolId, +} + +impl Iterator for SymbolIdRangeIterator { + type Item = SymbolId; + + fn next(&mut self) -> Option { + self.remaining = self.remaining.checked_sub(1)?; + let value = self.next; + self.next = value.next(); + Some(value) + } +} + +struct SymbolLoadOutputs<'data> { + /// Pending non-versioned symbols, grouped by hash bucket. + pending_symbols_by_bucket: Vec>, +} + +#[derive(Default, Clone)] +struct PendingSymbolHashBucket<'data> { + symbols: Vec>, + + versioned_symbols: Vec>, +} + +impl<'data, O: ObjectFile<'data>> SymbolDb<'data, O> { + /// If the version script is optimized fur rust, we downgraded all symbols to local visibility. + /// This promotes symbols marked for global visibility in a Rust version script back to global. + /// Also adds the non-interposable flag to all local symbols. + pub(crate) fn handle_rust_version_script( + &self, + rust_vscript: &RustVersionScript<'data>, + per_symbol_flags: &mut PerSymbolFlags, + ) { + verbose_timing_phase!("Upgrade locals for export"); + let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); + + rust_vscript.global.par_iter().for_each(|symbol| { + let prehashed = UnversionedSymbolName::prehashed(symbol); + if let Some(symbol_id) = self.get_unversioned(&prehashed) { + atomic_per_symbol_flags + .get_atomic(self.definition(symbol_id)) + .remove(ValueFlags::DOWNGRADE_TO_LOCAL); + } + }); + + // Don't forget to add the non-interposable flag the local symbols. + // We coudn't do this earlier as we didn't know which symbols would remain + // local. + per_symbol_flags + .flags_mut() + .par_iter_mut() + .for_each(|flags| { + let flags_val = flags.get(); + if flags_val.is_downgraded_to_local() { + *flags = (flags_val | ValueFlags::NON_INTERPOSABLE).raw(); + } + }); + } + + pub(crate) fn new( + args: &'data Args, + output_kind: OutputKind, + auxiliary: &AuxiliaryFiles<'data>, + herd: &'data bumpalo_herd::Herd, + ) -> Result { + let version_script = auxiliary + .version_script_data + .map(VersionScript::parse) + .transpose()? + .unwrap_or_default(); + + let export_list = auxiliary + .export_list_data + .map(ExportList::parse) + .transpose()?; + + let num_buckets = num_symbol_hash_buckets(args); + let mut buckets = Vec::new(); + buckets.resize_with(num_buckets, || SymbolBucket { + name_to_id: Default::default(), + versioned_name_to_id: Default::default(), + alternative_definitions: HashMap::new(), + alternative_versioned_definitions: HashMap::new(), + }); + + let mut symbol_db = SymbolDb { + args, + buckets, + symbol_file_ids: Vec::new(), + symbol_definitions: Vec::new(), + groups: Vec::new(), + start_stop_symbol_names: Default::default(), + version_script, + export_list, + entry: None, + output_kind, + herd, + }; + + for symbol in &args.export_list { + symbol_db + .export_list + .get_or_insert_default() + .add_symbol(symbol, true)?; + } + + Ok(symbol_db) + } + + pub(crate) fn add_inputs( + &mut self, + per_symbol_flags: &mut PerSymbolFlags, + output_sections: &mut OutputSections<'data>, + layout_rules_builder: &mut LayoutRulesBuilder<'data>, + loaded: LoadedInputs<'data, O>, + ) -> Result { + timing_phase!("Load inputs into symbol DB"); + + let parsed_objects = loaded.objects.into_iter().try_collect()?; + + let processed_linker_scripts = parsing::process_linker_scripts( + &loaded.linker_scripts, + output_sections, + layout_rules_builder, + )?; + + self.add_version_script_from_linker_scripts(&loaded.linker_scripts)?; + + let pre_existing_groups = self.groups.len(); + + if self.groups.is_empty() { + self.groups + .push(Group::Prelude(crate::parsing::Prelude::new::( + self.args, + self.output_kind, + ))); + } + + grouping::create_groups(self, parsed_objects, processed_linker_scripts); + + self.create_lto_input_groups(loaded.lto_objects)?; + + let new_groups = &self.groups[pre_existing_groups..]; + + let num_symbols = new_groups.iter().map(|group| group.num_symbols()).sum(); + + self.symbol_definitions.reserve(num_symbols); + per_symbol_flags.reserve(num_symbols); + self.symbol_file_ids.reserve(num_symbols); + + let mut writers = SymbolVecWriters::new( + &mut self.symbol_definitions, + &mut per_symbol_flags.flags, + &mut self.symbol_file_ids, + ); + + let mut per_group_shards = new_groups + .iter() + .map(|group| writers.new_shard(group)) + .collect_vec(); + + let per_group_outputs = read_symbols( + &self.version_script, + &mut per_group_shards, + self.args, + &self.export_list, + self.output_kind, + )?; + + populate_symbol_db(&mut self.buckets, &per_group_outputs); + + { + verbose_timing_phase!("Return shards"); + + for shard in per_group_shards { + writers.return_shard(shard); + } + } + + rayon::join( + || { + // This can take a while, so do it in parallel with other work. + verbose_timing_phase!("Drop per-group outputs"); + drop(per_group_outputs); + }, + || { + verbose_timing_phase!("Apply linker scripts"); + + for script in &loaded.linker_scripts { + self.apply_linker_script(script); + } + }, + ); + + Ok(()) + } + + #[cfg(feature = "plugins")] + fn create_lto_input_groups( + &mut self, + lto_objects: Vec>>>, + ) -> Result { + if lto_objects.is_empty() { + return Ok(()); + } + + verbose_timing_phase!("Create LTO input groups"); + + let lto_objects = lto_objects.into_iter().collect::>>()?; + + for group_objects in lto_objects + .into_iter() + .chunks(crate::input_data::MAX_FILES_PER_GROUP as usize) + .into_iter() + { + let mut next_symbol_id = self.next_symbol_id(); + let group_index = self.next_group_index(); + + self.groups.push(Group::LtoInputs( + group_objects + .into_iter() + .enumerate() + .map(|(file_index, o)| { + let symbol_id_range = SymbolIdRange::input(next_symbol_id, o.num_symbols()); + let input_obj = o.into_input_object( + FileId::new(group_index, file_index as u32), + symbol_id_range, + ); + next_symbol_id = next_symbol_id.add_usize(symbol_id_range.len()); + input_obj + }) + .collect(), + )); + } + + Ok(()) + } + + #[cfg(not(feature = "plugins"))] + #[allow( + clippy::unused_self, + clippy::needless_pass_by_value, + clippy::needless_pass_by_ref_mut + )] + fn create_lto_input_groups( + &mut self, + lto_objects: Vec>>>, + ) -> Result { + if !lto_objects.is_empty() { + return Err(linker_plugin_disabled_error()); + } + Ok(()) + } + + /// Adds a new synthetic symbol. `syn` must have been the most recently added group. + pub(crate) fn add_synthetic_symbol( + &mut self, + per_symbol_flags: &mut PerSymbolFlags, + symbol_name: PreHashed>, + syn: &ResolvedSyntheticSymbols<'data>, + ) -> SymbolId { + debug_assert_eq!(syn.file_id.group() + 1, self.groups.len()); + + let symbol_id = SymbolId::from_usize(self.symbol_definitions.len()); + + debug_assert_eq!( + symbol_id.0, + syn.start_symbol_id.0 + syn.symbol_definitions.len() as u32 + ); + + let num_buckets = self.buckets.len(); + self.buckets[symbol_name.hash() as usize % num_buckets].add_symbol(&PendingSymbol { + symbol_id, + name: symbol_name, + }); + + self.symbol_definitions.push(symbol_id); + self.start_stop_symbol_names.push(*symbol_name); + let Group::SyntheticSymbols(s) = &mut self.groups[syn.file_id.group()] else { + panic!("Tried to add synthetic symbol to non-synthetic-symbol group"); + }; + s.symbol_id_range.num_symbols += 1; + self.symbol_file_ids.push(syn.file_id); + + per_symbol_flags.push(ValueFlags::NON_INTERPOSABLE); + + symbol_id + } + + /// Applies overrides for symbols wrapped via the --wrap= argument. Note that like GNU ld, our + /// wrapping mechanism only affects resolution of undefined symbols. Defined symbols will be + /// unaffected. This means that references to a symbol from within the compilation unit that + /// defines it will not go via the wrapper. This is in contrast to LLD where wrapping also + /// affects references to symbols in compilation units where those symbols are defined. Our main + /// reason for this choice of behaviour is that it's much simpler to implement. + pub(crate) fn apply_wrapped_symbol_overrides(&mut self) { + if self.args.wrap.is_empty() { + return; + } + + verbose_timing_phase!("Apply wrapped symbol overrides"); + + let allocator = self.herd.get(); + + for name in &self.args.wrap { + let name_bytes = allocator.alloc_slice_copy(name.as_bytes()); + let orig_id = self.get_unversioned(&UnversionedSymbolName::prehashed(name_bytes)); + let wrap_name = format!("__wrap_{name}"); + if let Some(wrap_id) = + self.get_unversioned(&UnversionedSymbolName::prehashed(wrap_name.as_bytes())) + { + self.override_name(UnversionedSymbolName::prehashed(name_bytes), wrap_id); + } + + if let Some(orig_id) = orig_id { + let real_name = allocator.alloc_slice_copy(format!("__real_{name}").as_bytes()); + self.override_name(UnversionedSymbolName::prehashed(real_name), orig_id); + } + } + } + + /// Overrides `name` to point to `symbol_id`. Returns the old symbol ID for `name`. + fn override_name( + &mut self, + name: PreHashed>, + symbol_id: SymbolId, + ) -> Option { + let num_buckets = self.buckets.len(); + self.buckets[name.hash() as usize % num_buckets] + .name_to_id + .insert(name, symbol_id) + } + + /// Reads the symbol visibility from the original object. + pub(crate) fn input_symbol_visibility(&self, symbol_id: SymbolId) -> Visibility { + let file_id = self.file_id_for_symbol(symbol_id); + debug_assert!(self.file(file_id).symbol_id_range().contains(symbol_id)); + match &self.groups[file_id.group()] { + Group::Prelude(_) => Visibility::Default, + Group::Objects(parsed_input_objects) => { + let obj = &parsed_input_objects[file_id.file()]; + let local_index = symbol_id.to_input(obj.symbol_id_range); + + let Ok(obj_symbol) = obj.parsed.object.symbol(local_index) else { + return Visibility::Default; + }; + + obj_symbol.visibility() + } + Group::LinkerScripts(_) => Visibility::Default, + Group::SyntheticSymbols(_) => Visibility::Default, + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => { + lto_objects[file_id.file()].symbol_visibility(symbol_id) + } + } + } + + /// Returns a struct that can be used to print debug information about the specified symbol. + pub(crate) fn symbol_debug<'a>( + &'a self, + per_symbol_flags: &'a dyn FlagsForSymbol, + symbol_id: SymbolId, + ) -> SymbolDebug<'a, 'data, O> { + SymbolDebug { + db: self, + symbol_id, + per_symbol_flags, + } + } + + pub(crate) fn symbol_name_for_display(&self, symbol_id: SymbolId) -> SymbolNameDisplay<'data> { + SymbolNameDisplay { + name: self.symbol_name(symbol_id).ok(), + demangle: self.args.demangle, + } + } + + pub(crate) fn symbol_name(&self, symbol_id: SymbolId) -> Result> { + let file_id = self.file_id_for_symbol(symbol_id); + match &self.groups[file_id.group()] { + Group::Prelude(prelude) => Ok(prelude.symbol_name(symbol_id)), + Group::Objects(parsed_input_objects) => { + parsed_input_objects[file_id.file()].symbol_name(symbol_id) + } + Group::LinkerScripts(scripts) => Ok(scripts[file_id.file()].symbol_name(symbol_id)), + Group::SyntheticSymbols(syn) => { + Ok(self.start_stop_symbol_names[syn.symbol_id_range.id_to_offset(symbol_id)]) + } + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => Ok(lto_objects[file_id.file()].symbol_name(symbol_id)), + } + } + + /// Get the version of a symbol. Only intended for diagnostic purposes. + pub(crate) fn symbol_version_debug(&self, symbol_id: SymbolId) -> Option { + let file_id = self.file_id_for_symbol(symbol_id); + match &self.groups[file_id.group()] { + Group::Objects(parsed_input_objects) => { + parsed_input_objects[file_id.file()].symbol_version_debug(symbol_id) + } + _ => None, + } + } + + pub(crate) fn flags_for_symbol( + &self, + per_symbol_flags: &PerSymbolFlags, + symbol_id: SymbolId, + ) -> ValueFlags { + let mut flags = per_symbol_flags.flags_for_symbol(self.definition(symbol_id)); + flags.merge(per_symbol_flags.flags_for_symbol(symbol_id)); + flags + } + + pub(crate) fn num_symbols(&self) -> usize { + self.symbol_definitions.len() + } + + pub(crate) fn num_regular_objects(&self) -> usize { + self.groups + .iter() + .map(|group| match group { + Group::Objects(objects) => objects.len(), + _ => 0, + }) + .sum() + } + + pub(crate) fn num_lto_objects(&self) -> usize { + self.groups + .iter() + .map(|group| match group { + #[cfg(feature = "plugins")] + Group::LtoInputs(objects) => objects.len(), + _ => 0, + }) + .sum() + } + + /// If we have a symbol that when demangled produces `target_name`, then return the mangled + /// name. Note, this scans every symbol, so should only be used for debugging / diagnostic + /// purposes. + pub(crate) fn find_mangled_name(&self, target_name: &str) -> Option { + for i in 1..self.num_symbols() { + let symbol_id = SymbolId(i as u32); + let Ok(name) = self.symbol_name(symbol_id) else { + continue; + }; + + let Ok(name) = std::str::from_utf8(name.bytes()) else { + continue; + }; + + if demangle(name) == target_name { + return Some(name.to_owned()); + } + } + + None + } + + /// Returns our mapping from symbol IDs to the IDs that define them. Definitions should be + /// restored later by calling `restore_definitions`. While the definitions are taken, any method + /// that requires definitions will fail. + pub(crate) fn take_definitions(&mut self) -> Vec { + take(&mut self.symbol_definitions) + } + + pub(crate) fn restore_definitions(&mut self, definitions: Vec) { + self.symbol_definitions = definitions; + } + + fn borrow_atomic<'db>(&'db mut self) -> AtomicSymbolDb<'data, 'db, O> { + let definitions = self + .take_definitions() + .into_iter() + .map(|id| id.as_atomic()) + .collect(); + + AtomicSymbolDb { + db: self, + definitions, + } + } + + pub(crate) fn file_id_for_symbol(&self, symbol_id: SymbolId) -> FileId { + self.symbol_file_ids[symbol_id.as_usize()] + } + + /// Returns whether the supplied symbol ID is the canonical ID. A symbol won't be canonical, if + /// it resolves to a different symbol. The symbol may still be undefined. + pub(crate) fn is_canonical(&self, symbol_id: SymbolId) -> bool { + let resolution = self.symbol_definitions[symbol_id.as_usize()]; + resolution == symbol_id + } + + pub(crate) fn definition(&self, symbol_id: SymbolId) -> SymbolId { + // We need to do two steps when finding the definition for a symbol, since the definition + // may have changed since we did the original name lookup. It would be possible to avoid + // this, by resolving all definitions before we resolve references, except then, due to + // archive semantics, we'd need to do two passes to resolve symbols, one to determine which + // archive members to load, then a second to determine which symbols to use. + let step1 = self.symbol_definitions[symbol_id.as_usize()]; + self.symbol_definitions[step1.as_usize()] + } + + pub(crate) fn replace_definition(&mut self, symbol_id: SymbolId, new_definition: SymbolId) { + self.symbol_definitions[symbol_id.as_usize()] = new_definition; + } + + pub(crate) fn file<'db>(&'db self, file_id: FileId) -> SequencedInput<'db, 'data, O> { + match &self.groups[file_id.group()] { + Group::Prelude(prelude) => SequencedInput::Prelude(prelude), + Group::Objects(parsed_input_objects) => { + SequencedInput::Object(&parsed_input_objects[file_id.file()]) + } + Group::LinkerScripts(scripts) => SequencedInput::LinkerScript(&scripts[file_id.file()]), + Group::SyntheticSymbols(syn) => SequencedInput::SyntheticSymbols(syn), + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => SequencedInput::LtoInput(<o_objects[file_id.file()]), + } + } + + pub(crate) fn is_mapping_symbol(&self, symbol_id: SymbolId) -> bool { + let Ok(name) = self.symbol_name(symbol_id) else { + // We don't want to bother the caller with an error here. If there's a problem getting + // the name, it will be reported elsewhere. + return false; + }; + is_mapping_symbol_name(name.bytes()) + } + + pub(crate) fn get_unversioned( + &self, + prehashed: &PreHashed, + ) -> Option { + let num_buckets = self.buckets.len(); + self.buckets[prehashed.hash() as usize % num_buckets] + .name_to_id + .get(prehashed) + .copied() + } + + #[inline(always)] + pub(crate) fn get(&self, key: &PreHashedSymbolName, allow_dynamic: bool) -> Option { + let num_buckets = self.buckets.len(); + + match key { + PreHashedSymbolName::Unversioned(key) => { + let bucket = &self.buckets[key.hash() as usize % num_buckets]; + let symbol_id = bucket.name_to_id.get(key).copied()?; + + if !allow_dynamic && self.file(self.file_id_for_symbol(symbol_id)).is_dynamic() { + return bucket.get_non_dynamic(symbol_id, self); + } + + Some(symbol_id) + } + PreHashedSymbolName::Versioned(key) => { + let bucket = &self.buckets[key.hash() as usize % num_buckets]; + let symbol_id = bucket.versioned_name_to_id.get(key).copied()?; + + if !allow_dynamic && self.file(self.file_id_for_symbol(symbol_id)).is_dynamic() { + return bucket.get_non_dynamic(symbol_id, self); + } + + Some(symbol_id) + } + } + } + + pub(crate) fn all_unversioned_symbols( + &self, + ) -> impl Iterator>, &SymbolId)> { + self.buckets.iter().flat_map(|b| b.name_to_id.iter()) + } + + #[inline(always)] + pub(crate) fn symbol_strength( + &self, + symbol_id: SymbolId, + resolved: &[ResolvedGroup<'data, O>], + ) -> SymbolStrength { + let file_id = self.file_id_for_symbol(symbol_id); + match &resolved[file_id.group()].files[file_id.file()] { + ResolvedFile::Object(obj) => obj.common.symbol_strength(symbol_id), + ResolvedFile::Dynamic(obj) => obj.common.symbol_strength(symbol_id), + #[cfg(feature = "plugins")] + ResolvedFile::LtoInput(obj) => { + use crate::linker_plugins::SymbolKind; + + let SequencedInput::LtoInput(obj) = self.file(obj.file_id) else { + unreachable!(); + }; + if !obj.enabled { + return SymbolStrength::Undefined; + } + let local_index = symbol_id.to_input(obj.symbol_id_range); + let obj_symbol = &obj.symbols[local_index.0]; + match obj_symbol.kind { + Some(SymbolKind::Def) => SymbolStrength::Strong, + Some(SymbolKind::WeakDef) => SymbolStrength::Weak, + Some(SymbolKind::Common) => SymbolStrength::Common(obj_symbol.size), + _ => SymbolStrength::Undefined, + } + } + _ => SymbolStrength::Undefined, + } + } + + /// Returns whether the specified symbol is defined in a section with the SHF_GROUP flag set. + fn is_in_comdat_group( + &self, + symbol_id: SymbolId, + resolved: &[ResolvedGroup<'data, O>], + ) -> bool { + let file_id = self.file_id_for_symbol(symbol_id); + let ResolvedFile::Object(obj) = &resolved[file_id.group()].files[file_id.file()] else { + return false; + }; + + let local_index = symbol_id.to_input(obj.common.symbol_id_range); + let Ok(obj_symbol) = obj.common.object.symbol(local_index) else { + return false; + }; + + let section_index = obj_symbol.section_index(); + let Ok(header) = obj.common.object.section(section_index) else { + return false; + }; + + let flags = header.flags(); + + flags.is_group() + } + + pub(crate) fn entry_symbol_name(&self) -> &[u8] { + // The --entry flag is used first, falling back to what the linker script says, or otherwise + // defaults to `_start`. + self.args + .entry + .as_ref() + .map(|n| n.as_bytes()) + .or(self.entry) + .unwrap_or(b"_start") + } + + pub(crate) fn defsym_defined_via_cli_option(&self, symbol_name: &[u8]) -> bool { + self.args + .defsym + .iter() + .any(|(name, _)| name.as_bytes() == symbol_name) + } + + pub(crate) fn missing_defsym_target_error( + &self, + symbol_name: &[u8], + target_name: &str, + ) -> Error { + if self.defsym_defined_via_cli_option(symbol_name) { + crate::error!( + "Symbol '{}' referenced by --defsym does not exist", + target_name + ) + } else { + crate::error!( + "Undefined symbol '{}' referenced in expression", + target_name + ) + } + } + + fn apply_linker_script(&mut self, script: &InputLinkerScript<'data>) { + for cmd in &script.script.commands { + if let crate::linker_script::Command::Entry(symbol_name) = cmd { + self.entry = Some(*symbol_name); + } + } + } + + pub(crate) fn next_symbol_id(&self) -> SymbolId { + self.groups.last().map_or(SymbolId::undefined(), |group| { + let range = group.symbol_id_range(); + range.start().add_usize(range.len()) + }) + } + + pub(crate) fn new_synthetic_symbols_group(&mut self) -> ResolvedSyntheticSymbols<'data> { + let file_id = FileId::new(self.groups.len() as u32, 0); + let start_symbol_id = self.next_symbol_id(); + + self.groups.push(Group::SyntheticSymbols(SyntheticSymbols { + file_id, + symbol_id_range: SymbolIdRange::input(start_symbol_id, 0), + })); + + ResolvedSyntheticSymbols { + file_id, + start_symbol_id, + symbol_definitions: Vec::new(), + } + } + + fn add_version_script_from_linker_scripts( + &mut self, + linker_scripts: &[InputLinkerScript<'data>], + ) -> Result { + for script in linker_scripts { + // Check if the linker script contains a VERSION command + if let Some(version_content) = script.script.get_version_script_content() { + if self.version_script != VersionScript::default() { + bail!("Multiple version scripts provided"); + } + + self.version_script = VersionScript::parse(crate::input_data::ScriptData { + raw: version_content, + })?; + } + } + + Ok(()) + } + + pub(crate) fn groups_reserve(&mut self, additional: usize) { + self.groups.reserve(additional); + } + + pub(crate) fn next_group_index(&self) -> u32 { + self.groups.len() as u32 + } + + pub(crate) fn add_group(&mut self, group: Group<'data, O>) { + self.groups.push(group); + } + + #[cfg(feature = "plugins")] + pub(crate) fn disable_lto_inputs(&mut self) { + for group in &mut self.groups { + if let Group::LtoInputs(objects) = group { + for obj in objects { + obj.enabled = false; + } + } + } + } +} + +pub(crate) fn linker_plugin_disabled_error() -> Error { + error!("Wild was compiled without linker-plugin support, but LTO inputs were detected") +} + +struct SymbolVecWriters<'out> { + symbol_definitions_writer: sharded_vec_writer::VecWriter<'out, SymbolId>, + per_symbol_flags_writer: sharded_vec_writer::VecWriter<'out, RawFlags>, + symbol_file_ids_writer: sharded_vec_writer::VecWriter<'out, FileId>, +} + +impl<'out> SymbolVecWriters<'out> { + fn new( + symbol_definitions: &'out mut Vec, + per_symbol_flags: &'out mut Vec, + symbol_file_ids: &'out mut Vec, + ) -> Self { + Self { + symbol_definitions_writer: sharded_vec_writer::VecWriter::new(symbol_definitions), + per_symbol_flags_writer: sharded_vec_writer::VecWriter::new(per_symbol_flags), + symbol_file_ids_writer: sharded_vec_writer::VecWriter::new(symbol_file_ids), + } + } + + fn new_shard<'group, 'data, O: ObjectFile<'data>>( + &mut self, + group: &'group Group<'data, O>, + ) -> SymbolWriterShard<'out, 'group, 'data, O> { + let num_symbols = group.num_symbols(); + SymbolWriterShard { + group, + next: group.start_symbol_id(), + resolutions: self.symbol_definitions_writer.take_shard(num_symbols), + flags: self.per_symbol_flags_writer.take_shard(num_symbols), + file_ids: self.symbol_file_ids_writer.take_shard(num_symbols), + } + } + + fn return_shard<'data, O: ObjectFile<'data>>( + &mut self, + shard: SymbolWriterShard<'_, '_, 'data, O>, + ) { + self.symbol_definitions_writer + .return_shard(shard.resolutions); + self.per_symbol_flags_writer.return_shard(shard.flags); + self.symbol_file_ids_writer.return_shard(shard.file_ids); + } +} + +impl<'data> SymbolBucket<'data> { + fn add_symbol(&mut self, pending: &PendingSymbol<'data>) { + match self.name_to_id.entry(pending.name) { + hash_map::Entry::Occupied(entry) => { + let first_symbol_id = *entry.get(); + self.add_extra_symbol_definition(first_symbol_id, pending.symbol_id); + } + hash_map::Entry::Vacant(entry) => { + entry.insert(pending.symbol_id); + } + } + } + + fn add_versioned_symbol(&mut self, pending: &PendingVersionedSymbol<'data>) { + match self.versioned_name_to_id.entry(pending.name) { + hash_map::Entry::Occupied(entry) => { + let first_symbol_id = *entry.get(); + self.alternative_versioned_definitions + .entry(first_symbol_id) + .or_default() + .push(pending.symbol_id); + } + hash_map::Entry::Vacant(entry) => { + entry.insert(pending.symbol_id); + } + } + } + + fn add_extra_symbol_definition(&mut self, first_symbol_id: SymbolId, new_symbol_id: SymbolId) { + self.alternative_definitions + .entry(first_symbol_id) + .or_default() + .push(new_symbol_id); + } + + /// Returns the selected non-dynamic alternative to the supplied symbol, if any. + /// Among non-dynamic alternatives, selects the best one based on symbol binding: + /// strong > common (largest) > weak/gnu_unique. + fn get_non_dynamic>( + &self, + symbol_id: SymbolId, + symbol_db: &SymbolDb<'data, O>, + ) -> Option { + let alternatives = self.alternative_definitions.get(&symbol_id)?; + let mut selector = SymbolPrioritySelector::new(); + for &alt in alternatives { + let file_id = symbol_db.file_id_for_symbol(alt); + let file = symbol_db.file(file_id); + if file.is_dynamic() { + continue; + } + selector.consider(alt, file.symbol_strength(alt)); + } + selector.best() + } +} + +/// For each symbol that has multiple definitions, some of which may be weak, some strong, some +/// "common" symbols and some in archive entries that weren't loaded, resolve which version of the +/// symbol we're using. The symbol we select will be the first strongly defined symbol in a loaded +/// object, or if there are no strong definitions, then the first definition in a loaded object. If +/// a symbol definition is a common symbol, then the largest definition will be used. +pub(crate) fn resolve_alternative_symbol_definitions<'data, O: ObjectFile<'data>>( + symbol_db: &mut SymbolDb<'data, O>, + per_symbol_flags: &mut PerSymbolFlags, + resolved: &[ResolvedGroup<'data, O>], +) -> Result { + timing_phase!("Resolve alternative symbol definitions"); + + let mut buckets = take(&mut symbol_db.buckets); + let atomic_symbol_db = symbol_db.borrow_atomic(); + let atomic_per_symbol_flags = per_symbol_flags.borrow_atomic(); + let error_queue = SegQueue::new(); + + buckets.par_iter_mut().for_each(|bucket| { + verbose_timing_phase!("Resolve alternative for bucket"); + + process_alternatives( + &mut bucket.alternative_definitions, + &error_queue, + &atomic_symbol_db, + &atomic_per_symbol_flags, + resolved, + ); + + process_alternatives( + &mut bucket.alternative_versioned_definitions, + &error_queue, + &atomic_symbol_db, + &atomic_per_symbol_flags, + resolved, + ); + }); + + drop(atomic_symbol_db); + + let mut duplicate_errors: Vec = error_queue.into_iter().collect(); + duplicate_errors.sort_by_key(|e| e.to_string()); + + if !duplicate_errors.is_empty() { + let error_details = duplicate_errors + .iter() + .map(|e| e.to_string()) + .collect::>() + .join("\n"); + + bail!("Duplicate symbols detected: {error_details}"); + } + + symbol_db.buckets = buckets; + + Ok(()) +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub(crate) enum Visibility { + Default, + Protected, + Hidden, +} + +impl Visibility { + pub(crate) fn from_elf_st_visibility(st_visibility: u8) -> Visibility { + match st_visibility { + object::elf::STV_PROTECTED => Visibility::Protected, + object::elf::STV_HIDDEN => Visibility::Hidden, + _ => Visibility::Default, + } + } +} + +fn process_alternatives<'data, O: ObjectFile<'data>>( + alternative_definitions: &mut HashMap>, + error_queue: &SegQueue, + symbol_db: &AtomicSymbolDb<'data, '_, O>, + per_symbol_flags: &AtomicPerSymbolFlags, + resolved: &[ResolvedGroup<'data, O>], +) { + for (first, alternatives) in std::mem::take(alternative_definitions) { + // Compute the most restrictive visibility of any of the alternative definitions. This is + // the visibility we'll use for our selected symbol. This seems like odd behaviour, but it + // matches what GNU ld appears to do and some programs will fail to link if we don't do + // this. + let visibility = alternatives + .iter() + .fold(symbol_db.input_symbol_visibility(first), |vis, id| { + vis.max(symbol_db.input_symbol_visibility(*id)) + }); + + match select_symbol(symbol_db, per_symbol_flags, first, &alternatives, resolved) { + Ok(selected) => { + symbol_db.update_definition(first, selected); + + for &alt in &alternatives { + symbol_db.update_definition(alt, selected); + } + + if visibility != Visibility::Default { + handle_non_default_visibility(per_symbol_flags, first); + + for alt in alternatives { + handle_non_default_visibility(per_symbol_flags, alt); + } + } + } + Err(err) => { + error_queue.push(err); + } + } + } +} + +/// Update value flags for `symbol_id` given that we've now changed its visibility to something +/// other than default. +fn handle_non_default_visibility(per_symbol_flags: &AtomicPerSymbolFlags, symbol_id: SymbolId) { + // TODO: Currently we only make the symbol non-interposable, but we should also actually + // change its visibility too. We need somewhere to store this information. We also need + // linker-diff to report when we get exported dynamic symbols wrong. + let flags = per_symbol_flags.get_atomic(symbol_id); + if !flags.get().contains(ValueFlags::DYNAMIC) { + flags.or_assign(ValueFlags::NON_INTERPOSABLE); + } +} + +/// Selects which version of the symbol to use. For more information on symbol priority, see +/// https://maskray.me/blog/2021-06-20-linker-symbol-resolution +#[inline(always)] +fn select_symbol<'data, O: ObjectFile<'data>>( + symbol_db: &AtomicSymbolDb<'data, '_, O>, + per_symbol_flags: &AtomicPerSymbolFlags, + first_id: SymbolId, + alternatives: &[SymbolId], + resolved: &[ResolvedGroup<'data, O>], +) -> Result { + let mut selector = SymbolPrioritySelector::new(); + + for id in std::iter::once(first_id).chain(alternatives.iter().copied()) { + let flags = per_symbol_flags.flags_for_symbol(id); + + // Dynamic symbols, even strong ones, don't override non-dynamic weak symbols, so in this + // first pass, we ignore dynamic symbols. + if flags.is_dynamic() { + continue; + } + + let strength = symbol_db.symbol_strength(id, resolved); + + // Check for duplicate strong definitions (COMDAT handling). + if matches!(strength, SymbolStrength::Strong) + && let Some(existing) = selector.first_strong + { + // We don't implement full COMDAT logic, however if we encounter duplicate + // strong definitions, then we don't emit errors if all the strong definitions + // are defined in COMDAT group sections. + if (!symbol_db.is_in_comdat_group(existing, resolved) + || !symbol_db.is_in_comdat_group(id, resolved)) + && !symbol_db.db.args.allow_multiple_definitions + { + bail!( + "{}, defined in {} and {}", + symbol_db.symbol_name_for_display(first_id), + symbol_db.file(symbol_db.file_id_for_symbol(existing)), + symbol_db.file(symbol_db.file_id_for_symbol(id)), + ); + } + } + + selector.consider(id, strength); + } + + if let Some(best) = selector.best() { + return Ok(best); + } + + // If we've made it this far, then the symbol is only defined in shared objects. Pick the first + // definition. Note, we don't check for duplicate strong definitions here because it's OK for + // multiple shared objects to define the same symbol strongly. + for alt in std::iter::once(first_id).chain(alternatives.iter().copied()) { + let strength = symbol_db.symbol_strength(alt, resolved); + if strength != SymbolStrength::Undefined { + return Ok(alt); + } + } + + Ok(first_id) +} + +#[derive(PartialEq, Eq, Clone, Copy)] +pub(crate) enum SymbolStrength { + /// The object containing this symbol wasn't loaded, so the definition can be ignored. + Undefined, + + /// The object weakly defines the symbol. + Weak, + + /// The object uses STB_GNU_UNIQUE binding. + GnuUnique, + + /// The object strongly defines the symbol. + Strong, + + /// The symbol is a "common" symbol with the specified size. The definition with the largest + /// size will be selected. + Common(u64), +} + +impl SymbolStrength { + /// Computes the binding strength of a symbol from its attributes. + pub(crate) fn of(symbol: &impl Symbol) -> Self { + if symbol.is_weak() { + SymbolStrength::Weak + } else if symbol.is_common() { + SymbolStrength::Common(symbol.size()) + } else if symbol.is_gnu_unique() { + SymbolStrength::GnuUnique + } else { + SymbolStrength::Strong + } + } +} + +/// Accumulates symbol candidates and selects the best one based on binding priority: +/// strong > common (largest) > weak/gnu_unique. +pub(crate) struct SymbolPrioritySelector { + pub(crate) first_strong: Option, + max_common: Option<(u64, SymbolId)>, + first_weak: Option, +} + +impl SymbolPrioritySelector { + pub(crate) fn new() -> Self { + Self { + first_strong: None, + max_common: None, + first_weak: None, + } + } + + /// Consider a candidate symbol with the given strength. + pub(crate) fn consider(&mut self, id: SymbolId, strength: SymbolStrength) { + match strength { + SymbolStrength::Strong => { + if self.first_strong.is_none() { + self.first_strong = Some(id); + } + } + SymbolStrength::Weak | SymbolStrength::GnuUnique => { + if self.first_weak.is_none() { + self.first_weak = Some(id); + } + } + SymbolStrength::Common(size) => match self.max_common { + Some((prev_size, _)) if size <= prev_size => {} + _ => self.max_common = Some((size, id)), + }, + SymbolStrength::Undefined => {} + } + } + + /// Returns the best symbol based on priority: strong > common (largest) > weak. + pub(crate) fn best(self) -> Option { + self.first_strong + .or(self.max_common.map(|(_, id)| id)) + .or(self.first_weak) + } +} + +/// Returns whether the supplied symbol name is for a [mapping +/// symbol](https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#mapping-symbols). +pub(crate) fn is_mapping_symbol_name(name: &[u8]) -> bool { + name.starts_with(b"$x") || name.starts_with(b"$d") || name == b"L0\x01" +} + +fn read_symbols<'data, O: ObjectFile<'data>>( + version_script: &VersionScript, + shards: &mut [SymbolWriterShard<'_, '_, 'data, O>], + args: &Args, + export_list: &Option>, + output_kind: OutputKind, +) -> Result>> { + timing_phase!("Read symbols"); + + let num_buckets = num_symbol_hash_buckets(args); + + shards + .par_iter_mut() + .map(|shard| { + read_symbols_for_group( + shard, + version_script, + export_list, + num_buckets, + args, + output_kind, + ) + }) + .collect::>>() +} + +fn read_symbols_for_group<'data, O: ObjectFile<'data>>( + shard: &mut SymbolWriterShard<'_, '_, 'data, O>, + version_script: &VersionScript, + export_list: &Option>, + num_buckets: usize, + args: &Args, + output_kind: OutputKind, +) -> Result> { + verbose_timing_phase!( + "Read group symbols", + group_id = shard.group.group_id(), + num_symbols = shard.group.num_symbols() + ); + + let mut outputs = SymbolLoadOutputs { + pending_symbols_by_bucket: vec![PendingSymbolHashBucket::default(); num_buckets], + }; + + match shard.group { + Group::Prelude(prelude) => { + prelude.load_symbols(shard, &mut outputs); + } + Group::Objects(parsed_input_objects) => { + for obj in *parsed_input_objects { + load_symbols_from_file( + obj, + version_script, + shard, + &mut outputs, + args, + export_list, + output_kind, + ) + .with_context(|| format!("Failed to load symbols from `{}`", obj.parsed.input))?; + } + } + Group::LinkerScripts(scripts) => { + for script in scripts { + load_linker_script_symbols(script, shard, &mut outputs); + } + } + Group::SyntheticSymbols(_) => { + // Custom section start/stop symbols are generated after archive handling. + } + #[cfg(feature = "plugins")] + Group::LtoInputs(lto_objects) => { + for obj in lto_objects { + load_lto_symbols(shard, &mut outputs, obj); + } + } + } + + Ok(outputs) +} + +#[cfg(feature = "plugins")] +fn load_lto_symbols<'data, O: ObjectFile<'data>>( + symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, + outputs: &mut SymbolLoadOutputs<'data>, + obj: &crate::linker_plugins::LtoInput<'data>, +) { + for (symbol_id, sym) in obj.symbols_iter() { + if sym.is_definition() { + if let Some(version) = sym.version { + outputs.add_versioned(PendingVersionedSymbol::from_prehashed( + symbol_id, + UnversionedSymbolName::prehashed(sym.name.bytes()), + version, + )); + } else { + outputs.add_non_versioned(PendingSymbol::new(symbol_id, sym.name.bytes())); + } + symbols_out.set_next(ValueFlags::empty(), symbol_id, obj.file_id); + } else { + symbols_out.set_next(ValueFlags::empty(), SymbolId::undefined(), obj.file_id); + } + } +} + +fn populate_symbol_db<'data>( + buckets: &mut [SymbolBucket<'data>], + per_group_outputs: &[SymbolLoadOutputs<'data>], +) { + timing_phase!("Populate symbol map"); + + buckets.par_iter_mut().enumerate().for_each(|(b, bucket)| { + verbose_timing_phase!("Process symbol bucket"); + + // The following approximation should be an upper bound on the number of global + // names we'll have. There will likely be at least a few global symbols with the + // same name, in which case the actual number will be slightly smaller. + let approx_num_symbols = per_group_outputs + .iter() + .map(|s| s.pending_symbols_by_bucket[b].symbols.len()) + .sum(); + bucket.name_to_id.reserve(approx_num_symbols); + + for outputs in per_group_outputs { + let pending = &outputs.pending_symbols_by_bucket[b]; + + for symbol in &pending.symbols { + bucket.add_symbol(symbol); + } + + for symbol in &pending.versioned_symbols { + bucket.add_versioned_symbol(symbol); + } + } + }); +} + +fn load_linker_script_symbols<'data, O: ObjectFile<'data>>( + script: &SequencedLinkerScript<'data>, + symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, + outputs: &mut SymbolLoadOutputs<'data>, +) { + for (offset, definition) in script.parsed.symbol_defs.iter().enumerate() { + let symbol_id = script.symbol_id_range.offset_to_id(offset); + + outputs.add_non_versioned(PendingSymbol::from_prehashed( + symbol_id, + PreHashed::new( + UnversionedSymbolName::new(definition.name), + hash_bytes(definition.name), + ), + )); + + let mut flags = ValueFlags::NON_INTERPOSABLE; + // PROVIDE_HIDDEN symbols have hidden visibility, which means they should be + // non-interposable (already set) and not exported to dynamic symbol table. + if definition.is_hidden { + flags |= ValueFlags::DOWNGRADE_TO_LOCAL; + } + symbols_out.set_next(flags, symbol_id, script.file_id); + } +} + +fn load_symbols_from_file<'data, O: ObjectFile<'data>>( + s: &SequencedInputObject<'data, O>, + version_script: &VersionScript, + symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, + outputs: &mut SymbolLoadOutputs<'data>, + args: &Args, + export_list: &Option>, + output_kind: OutputKind, +) -> Result { + if s.is_dynamic() { + DynamicObjectSymbolLoader::new(&s.parsed.object)?.load_symbols( + s.file_id, + symbols_out, + outputs, + ) + } else { + RegularObjectSymbolLoader { + object: &s.parsed.object, + args, + version_script, + archive_semantics: s.parsed.input.has_archive_semantics(), + lib_name: s.parsed.input.lib_name(), + export_list, + output_kind, + } + .load_symbols(s.file_id, symbols_out, outputs) + } +} + +struct SymbolWriterShard<'out, 'group, 'data, O: ObjectFile<'data>> { + group: &'group Group<'data, O>, + resolutions: sharded_vec_writer::Shard<'out, SymbolId>, + flags: sharded_vec_writer::Shard<'out, RawFlags>, + file_ids: sharded_vec_writer::Shard<'out, FileId>, + next: SymbolId, +} + +impl<'out, 'group, 'data, O: ObjectFile<'data>> SymbolWriterShard<'out, 'group, 'data, O> { + fn set_next(&mut self, flags: ValueFlags, resolution: SymbolId, file_id: FileId) { + self.flags.push(flags.raw()); + self.resolutions.push(resolution); + self.file_ids.push(file_id); + self.next = SymbolId::from_usize(self.next.as_usize() + 1); + } +} + +trait SymbolLoader<'data, O: ObjectFile<'data>> { + fn load_symbols( + &self, + file_id: FileId, + symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, + outputs: &mut SymbolLoadOutputs<'data>, + ) -> Result { + let base_symbol_id = symbols_out.next; + + for symbol in self.object().symbols_iter() { + let symbol_id = symbols_out.next; + let mut flags = self.compute_value_flags(symbol); + + if symbol.is_undefined() || self.should_ignore_symbol(symbol) { + symbols_out.set_next(flags, SymbolId::undefined(), file_id); + continue; + } + + let resolution = symbol_id; + + let local_index = symbol_id.offset_from(base_symbol_id); + + if symbol.is_local() { + symbols_out.set_next(flags, resolution, file_id); + continue; + } + + let info = self.get_symbol_name_and_version(symbol, local_index)?; + + let name = UnversionedSymbolName::prehashed(info.name()); + + if self.should_downgrade_to_local(&name) { + flags |= ValueFlags::DOWNGRADE_TO_LOCAL; + // If we're downgrading to a local, then we're writing a shared object. Shared + // objects should never bypass the GOT for TLS variables. However, if we're + // downgrading all symbols by default, that'd add the flag to all symbols, so we + // have to do this later. + if !self.downgrades_all() && !symbol.is_tls() { + flags |= ValueFlags::NON_INTERPOSABLE; + } + } + + if info.is_default() { + let pending = PendingSymbol::from_prehashed(symbol_id, name); + outputs.add_non_versioned(pending); + } + + if let Some(version) = info.version_name() { + let pending = PendingVersionedSymbol::from_prehashed(symbol_id, name, version); + outputs.add_versioned(pending); + } + + symbols_out.set_next(flags, resolution, file_id); + } + + Ok(()) + } + + fn object(&self) -> &O; + + fn compute_value_flags(&self, symbol: &O::Symbol) -> ValueFlags; + + /// Returns whether we should downgrade a symbol with the specified name to be a local. + fn should_downgrade_to_local(&self, _name: &PreHashed) -> bool { + false + } + + /// Returns whether we will downgrade all symbols by default and later upgrade some to global. + fn downgrades_all(&self) -> bool { + false + } + + /// Returns whether the supplied symbol should be ignore. + fn should_ignore_symbol(&self, _symbol: &O::Symbol) -> bool { + false + } + + fn get_symbol_name_and_version( + &self, + symbol: &O::Symbol, + local_index: usize, + ) -> Result; +} + +struct RegularObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { + object: &'a O, + args: &'a Args, + version_script: &'a VersionScript<'a>, + archive_semantics: bool, + lib_name: &'data [u8], + export_list: &'a Option>, + output_kind: OutputKind, +} + +struct DynamicObjectSymbolLoader<'a, 'data, O: ObjectFile<'data>> { + object: &'a O, + version_names: O::VersionNames, +} + +impl<'a, 'data, O: ObjectFile<'data>> DynamicObjectSymbolLoader<'a, 'data, O> { + fn new(object: &'a O) -> Result { + let version_names = object.get_version_names()?; + Ok(Self { + object, + version_names, + }) + } +} + +impl<'data, O: ObjectFile<'data>> SymbolLoader<'data, O> + for RegularObjectSymbolLoader<'_, 'data, O> +{ + fn compute_value_flags(&self, sym: &O::Symbol) -> ValueFlags { + let is_undefined = sym.is_undefined(); + + let symbol_is_exported = || { + if let Some(export_list) = &self.export_list + && let Ok(symbol_name) = self.object.symbol_name(sym) + && !&export_list.contains(&UnversionedSymbolName::prehashed(symbol_name)) + { + return false; + } + true + }; + let non_interposable = !sym.is_interposable() + || sym.is_local() + || self.output_kind.is_static_executable() + // Symbols defined in an executable cannot be interposed since the executable is always the + // first place checked for a symbol by the dynamic loader. + || (!is_undefined && ( + self.output_kind.is_executable() + || (self.archive_semantics && self.args.exclude_libs.should_exclude(self.lib_name)) + || ( + self.args.b_symbolic == args::BSymbolicKind::All + // `-Bsymbolic-functions` + || ( + self.args.b_symbolic == args::BSymbolicKind::Functions + && sym.is_func() + ) + // `-Bsymbolic-non-weak` + || ( + self.args.b_symbolic == args::BSymbolicKind::NonWeak + && !sym.is_weak() + ) + // `-Bsymbolic-non-weak-functions` + || ( + self.args.b_symbolic == args::BSymbolicKind::NonWeakFunctions + && (sym.is_func() + && !sym.is_weak()) + ) + ) + // Bsymbolic does not affect symbols that are exported + && !(self.export_list.is_some() && symbol_is_exported()) + )); + + let mut flags: ValueFlags = if sym.is_absolute() { + ValueFlags::ABSOLUTE + } else if sym.is_ifunc() { + ValueFlags::IFUNC + } else if is_undefined { + // For undefined symbols, we tweak some of the flags later on in + // `canonicalise_undefined_symbols`. We can't make those decisions now because we don't + // know whether the symbol will remain undefined. + ValueFlags::ABSOLUTE + } else { + ValueFlags::empty() + }; + + if non_interposable { + flags |= ValueFlags::NON_INTERPOSABLE; + } + flags + } + + fn should_downgrade_to_local(&self, name: &PreHashed) -> bool { + match self.version_script { + // We first downgrade all symbols when using a Rust version script. + // We're gonna set the ones that are exported back to global later. + VersionScript::Rust(_) => true, + VersionScript::Regular(version_script) => version_script.is_local(name), + } + } + + fn downgrades_all(&self) -> bool { + matches!(self.version_script, VersionScript::Rust(_)) + } + + fn get_symbol_name_and_version( + &self, + symbol: &O::Symbol, + _local_index: usize, + ) -> Result { + Ok(::parse( + self.object.symbol_name(symbol)?, + )) + } + + fn object(&self) -> &O { + self.object + } +} + +impl<'data, O: ObjectFile<'data>> SymbolLoader<'data, O> + for DynamicObjectSymbolLoader<'_, 'data, O> +{ + fn compute_value_flags(&self, symbol: &O::Symbol) -> ValueFlags { + let mut flags = ValueFlags::DYNAMIC; + if symbol.is_func() || symbol.is_ifunc() { + flags |= ValueFlags::FUNCTION; + } + if symbol.is_undefined() { + flags |= ValueFlags::ABSOLUTE; + } + flags + } + + fn get_symbol_name_and_version( + &self, + symbol: &O::Symbol, + local_index: usize, + ) -> Result { + self.object + .get_symbol_name_and_version(symbol, local_index, &self.version_names) + } + + fn object(&self) -> &O { + self.object + } + + fn should_ignore_symbol(&self, symbol: &O::Symbol) -> bool { + // Shared objects shouldn't export hidden symbols. If for some reason they do, ignore them. + symbol.is_hidden() + } +} + +#[derive(Clone, Copy)] +pub(crate) struct SymbolDebug<'a, 'data, O: ObjectFile<'data>> { + db: &'a SymbolDb<'data, O>, + symbol_id: SymbolId, + per_symbol_flags: &'a dyn FlagsForSymbol, +} + +impl<'a, 'data, O: ObjectFile<'data>> std::fmt::Display for SymbolDebug<'a, 'data, O> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let symbol_id = self.symbol_id; + let definition = self.db.definition(symbol_id); + let file_id = self.db.file_id_for_symbol(symbol_id); + let file = self.db.file(file_id); + let symbol_id_range = file.symbol_id_range(); + + if !symbol_id_range.contains(symbol_id) { + write!( + f, + "SymbolId {symbol_id} is owned by {file_id}, but that file has range {}..{}", + symbol_id_range.start(), + symbol_id_range.start().add_usize(symbol_id_range.len()) + )?; + // If ID ranges or file mappings are wrong, then the code later in this method, e.g. + // `id_to_offset` or `symbol_name` will panic. + return Ok(()); + } + + let local_index = symbol_id.to_offset(symbol_id_range); + let symbol_name = self + .db + .symbol_name(symbol_id) + .unwrap_or_else(|_| UnversionedSymbolName::new(b"??")); + + if definition.is_undefined() { + write!(f, "undefined ")?; + } + + if symbol_name.bytes().is_empty() { + match file { + SequencedInput::Prelude(_) => write!(f, "")?, + SequencedInput::Object(o) => { + let symbol_index = symbol_id.to_input(symbol_id_range); + if let Some(section_name) = o + .parsed + .object + .symbol(symbol_index) + .ok() + .and_then(|symbol| { + o.parsed + .object + .symbol_section(symbol, symbol_index) + .ok() + .flatten() + }) + .map(|section_index| o.parsed.object.section_display_name(section_index)) + { + write!(f, "section `{section_name}`")?; + } else { + write!(f, "")?; + } + } + SequencedInput::LinkerScript(s) => { + write!(f, "Symbol from linker script `{}`", s.parsed.input)?; + } + SequencedInput::SyntheticSymbols(_) => { + write!(f, "")?; + } + #[cfg(feature = "plugins")] + SequencedInput::LtoInput(_) => write!(f, "")?, + } + } else { + write!(f, "symbol `{}`", self.db.symbol_name_for_display(symbol_id))?; + } + + write!( + f, + " ({symbol_id} local={local_index}) in file #{file_id} ({file})" + )?; + + if symbol_id != definition && !definition.is_undefined() { + let definition_file_id = self.db.file_id_for_symbol(definition); + let definition_file = self.db.file(definition_file_id); + write!( + f, + " defined as {definition} in file #{definition_file_id} ({definition_file})" + )?; + } + + let flags = self.per_symbol_flags.flags_for_symbol(symbol_id); + write!(f, " ({flags})")?; + + Ok(()) + } +} + +impl SymbolId { + pub(crate) fn undefined() -> Self { + Self(0) + } + + pub(crate) fn from_usize(value: usize) -> SymbolId { + Self::new(u32::try_from(value).expect("Symbols overflowed 32 bits")) + } + + pub(crate) fn as_usize(self) -> usize { + self.0 as usize + } + + const fn new(value: u32) -> SymbolId { + SymbolId(value) + } + + pub(crate) fn offset_from(self, base: SymbolId) -> usize { + (self.0 - base.0) as usize + } + + pub(crate) fn to_offset(self, range: SymbolIdRange) -> usize { + range.id_to_offset(self) + } + + pub(crate) fn to_input(self, range: SymbolIdRange) -> object::SymbolIndex { + range.id_to_input(self) + } + + pub(crate) fn is_undefined(self) -> bool { + self.0 == 0 + } + + pub(crate) fn next(self) -> Self { + Self(self.0 + 1) + } + + fn as_atomic(self) -> AtomicSymbolId { + AtomicSymbolId(AtomicU32::new(self.0)) + } +} + +impl AtomicSymbolId { + fn store(&self, selected: SymbolId) { + self.0.store(selected.0, Ordering::Relaxed); + } + + fn into_non_atomic(self) -> SymbolId { + SymbolId(self.0.into_inner()) + } +} + +impl TryFrom for SymbolId { + type Error = crate::error::Error; + + fn try_from(value: usize) -> std::result::Result { + Ok(SymbolId(u32::try_from(value).context("Too many symbols")?)) + } +} + +impl<'data> Prelude<'data> { + fn load_symbols>( + &self, + symbols_out: &mut SymbolWriterShard<'_, '_, 'data, O>, + outputs: &mut SymbolLoadOutputs<'data>, + ) { + for definition in &self.symbol_definitions { + let symbol_id = symbols_out.next; + let mut flags = match definition.placement { + SymbolPlacement::Undefined | SymbolPlacement::ForceUndefined => { + ValueFlags::ABSOLUTE + } + SymbolPlacement::DefsymAbsolute(_) => { + outputs.add_non_versioned(PendingSymbol::new(symbol_id, definition.name)); + ValueFlags::NON_INTERPOSABLE | ValueFlags::ABSOLUTE + } + SymbolPlacement::SectionStart(_) + | SymbolPlacement::SectionEnd(_) + | SymbolPlacement::SectionGroupEnd(_) + | SymbolPlacement::DefsymSymbol(_, _) + | SymbolPlacement::LoadBaseAddress => { + outputs.add_non_versioned(PendingSymbol::new(symbol_id, definition.name)); + ValueFlags::NON_INTERPOSABLE + } + }; + if definition.is_hidden { + flags |= ValueFlags::DOWNGRADE_TO_LOCAL; + } + symbols_out.set_next(flags, symbol_id, PRELUDE_FILE_ID); + } + } +} + +impl std::fmt::Display for SymbolId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl InternalSymDefInfo<'_> { + pub(crate) fn section_id(self) -> Option { + match self.placement { + SymbolPlacement::Undefined + | SymbolPlacement::ForceUndefined + | SymbolPlacement::DefsymAbsolute(_) + | SymbolPlacement::DefsymSymbol(_, _) => None, + SymbolPlacement::SectionStart(i) => Some(i), + SymbolPlacement::SectionEnd(i) => Some(i), + SymbolPlacement::SectionGroupEnd(i) => Some(i), + // The other linkers attach to the closest section, but the address is nonetheless + // outside of the selected section. It's tricky for us to find the the closest section + // at this point in the code, so we pick an arbitrary section. + SymbolPlacement::LoadBaseAddress => Some(output_section_id::TEXT), + } + } +} + +impl<'data> PendingSymbol<'data> { + fn new(symbol_id: SymbolId, name: &'data [u8]) -> PendingSymbol<'data> { + Self::from_prehashed(symbol_id, UnversionedSymbolName::prehashed(name)) + } + + fn from_prehashed( + symbol_id: SymbolId, + name: PreHashed>, + ) -> PendingSymbol<'data> { + PendingSymbol { symbol_id, name } + } +} + +impl<'data> PendingVersionedSymbol<'data> { + fn from_prehashed( + symbol_id: SymbolId, + name: PreHashed>, + version: &'data [u8], + ) -> PendingVersionedSymbol<'data> { + PendingVersionedSymbol { + symbol_id, + name: VersionedSymbolName::prehashed(name, version), + } + } +} + +/// Decides how many buckets we should use for symbol names. +fn num_symbol_hash_buckets(args: &Args) -> usize { + args.available_threads.get() +} + +impl<'data> SymbolLoadOutputs<'data> { + fn add_non_versioned(&mut self, pending: PendingSymbol<'data>) { + let num_buckets = self.pending_symbols_by_bucket.len(); + + self.pending_symbols_by_bucket[pending.name.hash() as usize % num_buckets] + .symbols + .push(pending); + } + + fn add_versioned(&mut self, pending: PendingVersionedSymbol<'data>) { + let num_buckets = self.pending_symbols_by_bucket.len(); + + self.pending_symbols_by_bucket[pending.name.hash() as usize % num_buckets] + .versioned_symbols + .push(pending); + } +} + +impl<'data, 'db, O: ObjectFile<'data>> AtomicSymbolDb<'data, 'db, O> { + fn input_symbol_visibility(&self, symbol_id: SymbolId) -> Visibility { + self.db.input_symbol_visibility(symbol_id) + } + + fn update_definition(&self, to_update: SymbolId, new_definition: SymbolId) { + self.definitions[to_update.as_usize()].store(new_definition); + } + + fn symbol_strength( + &self, + symbol_id: SymbolId, + resolved: &[ResolvedGroup<'data, O>], + ) -> SymbolStrength { + self.db.symbol_strength(symbol_id, resolved) + } + + fn is_in_comdat_group( + &self, + symbol_id: SymbolId, + resolved: &[ResolvedGroup<'data, O>], + ) -> bool { + self.db.is_in_comdat_group(symbol_id, resolved) + } + + fn symbol_name_for_display(&self, symbol_id: SymbolId) -> SymbolNameDisplay<'data> { + self.db.symbol_name_for_display(symbol_id) + } + + fn file(&'db self, file_id: FileId) -> SequencedInput<'db, 'data, O> { + self.db.file(file_id) + } + + fn file_id_for_symbol(&self, symbol_id: SymbolId) -> FileId { + self.db.file_id_for_symbol(symbol_id) + } +} + +impl<'data, O: ObjectFile<'data>> Drop for AtomicSymbolDb<'data, '_, O> { + fn drop(&mut self) { + // Convert our atomic tables back to non-atomic tables and return them to the symbol-db that + // we took them from. This operation should be basically free, at least in optimised builds. + self.db.restore_definitions( + take(&mut self.definitions) + .into_iter() + .map(|id| id.into_non_atomic()) + .collect(), + ); + } +} + +impl ShardKey for SymbolId { + fn zero() -> Self { + SymbolId(0) + } + + fn add_usize(self, offset: usize) -> Self { + SymbolId( + (self.as_usize() + offset) + .try_into() + .expect("Symbol ID overflowed 32 bits"), + ) + } +} + +impl Display for RawSymbolName<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", String::from_utf8_lossy(self.name))?; + if let Some(version) = self.version_name { + if self.is_default { + write!(f, "@@")?; + } else { + write!(f, "@")?; + } + write!(f, "{}", String::from_utf8_lossy(version))?; + } + + Ok(()) + } +} + +impl Display for SymbolNameDisplay<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(name) = self.name { + if let Ok(s) = std::str::from_utf8(name.bytes()) { + if self.demangle { + Display::fmt(&symbolic_demangle::demangle(s), f) + } else { + Display::fmt(s, f) + } + } else { + write!(f, "INVALID UTF-8({:?})", name.bytes()) + } + } else { + write!(f, "SYMBOL-READ-ERROR") + } + } +}