From 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:43 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/addr2line/.cargo-checksum.json | 2 +- vendor/addr2line/CHANGELOG.md | 27 +++ vendor/addr2line/Cargo.lock | 180 ++++++++++++-------- vendor/addr2line/Cargo.toml | 72 +++++--- vendor/addr2line/examples/addr2line.rs | 212 +++++++++++------------ vendor/addr2line/src/function.rs | 30 +++- vendor/addr2line/src/lazy.rs | 24 ++- vendor/addr2line/src/lib.rs | 246 ++++++++++++++++----------- vendor/addr2line/tests/correctness.rs | 11 +- vendor/addr2line/tests/output_equivalence.rs | 1 + vendor/addr2line/tests/parse.rs | 4 +- 11 files changed, 470 insertions(+), 339 deletions(-) (limited to 'vendor/addr2line') diff --git a/vendor/addr2line/.cargo-checksum.json b/vendor/addr2line/.cargo-checksum.json index b43ad3bbf..43f25b3ba 100644 --- a/vendor/addr2line/.cargo-checksum.json +++ b/vendor/addr2line/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"d4ef249a0a4eff26a34a1f847a3c367dfd9988b4da972ac9c16b1d258b62ad87","Cargo.lock":"290a48d58d1ebfef0f5eaec66191f6c1a41080b89e10e931c6984052008479ab","Cargo.toml":"68243a813e2e6ba40d3e939b9ade5489b3f39a58d7dc391ae447a60591315f4a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"e99d88d232bf57d70f0fb87f6b496d44b6653f99f8a63d250a54c61ea4bcde40","README.md":"76d28502bd2e83f6a9e3576bd45e9a7fe5308448c4b5384b0d249515b5f67a5c","bench.plot.r":"6a5d7a4d36ed6b3d9919be703a479bef47698bf947818b483ff03951df2d4e01","benchmark.sh":"b35f89b1ca2c1dc0476cdd07f0284b72d41920d1c7b6054072f50ffba296d78d","coverage.sh":"4677e81922d08a82e83068a911717a247c66af12e559f37b78b6be3337ac9f07","examples/addr2line.rs":"75ef29e1d07d49d247990ad970892d64f629766bafa36afddff5a88976e58060","rustfmt.toml":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","src/function.rs":"395f37cdf03201d416d66bc11abeea627be0abb4585104acd927224a26cb9369","src/lazy.rs":"14ec61761369c21d426673f549c21394221533f444b68cd2a8370952eb19f345","src/lib.rs":"5696c0aee67df576f78935c66bb124f4e5fa19cbc9b25faf8f750e7e8dda113c","tests/correctness.rs":"c9325ffdec577bf5e56f5dd72fdff4927153d0a4c34c0fda5aefaeb44a8d26fd","tests/output_equivalence.rs":"38d7b585b7a2ca43b07eef6b34c11f489d1deae138a010123c33188dfb881c11","tests/parse.rs":"9e421ea9d9348721f6c6533cdba1db5b84287fc685f870c7905dea06b596b4db"},"package":"b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"} \ No newline at end of file +{"files":{"CHANGELOG.md":"59733fc6186af0929ca4b6508e10ea1777f757c333a355d8154498332aee259f","Cargo.lock":"0b30594b7d3f093b44ca9c53366bbcb3f28a97ed24da65e56fe9961e7250c3c2","Cargo.toml":"c68ebf21efe63bb706716dd7b4bb7d33734629f13db36014d6be49fed6c8d731","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"e99d88d232bf57d70f0fb87f6b496d44b6653f99f8a63d250a54c61ea4bcde40","README.md":"76d28502bd2e83f6a9e3576bd45e9a7fe5308448c4b5384b0d249515b5f67a5c","bench.plot.r":"6a5d7a4d36ed6b3d9919be703a479bef47698bf947818b483ff03951df2d4e01","benchmark.sh":"b35f89b1ca2c1dc0476cdd07f0284b72d41920d1c7b6054072f50ffba296d78d","coverage.sh":"4677e81922d08a82e83068a911717a247c66af12e559f37b78b6be3337ac9f07","examples/addr2line.rs":"624548450eda1c8491fe4de60f0a96d20ef9c0d70770de2d76d803850319c876","rustfmt.toml":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","src/function.rs":"caa2458f48509a0e0e2c4920719383997e9ccab44efceeabcf3019587f438a57","src/lazy.rs":"21bc1a7d8593c11e93577f1f17163705dbbadf752a007fae4401a4150ec9e473","src/lib.rs":"41d575590b9a683349552d7c4c845ef9a2739e7a4a9e01d53d4e0f4a4947fc45","tests/correctness.rs":"0bd7f9bc9d333cca0649d7bb85e07ebc14855ec2f2b9082f4ec752ccea77e1d6","tests/output_equivalence.rs":"9b637de957f4760ed8bdbfac9e1bacf57f0123c54ed0fbfeb8c2c3b7077f3d81","tests/parse.rs":"f0b2437d0c0b204f6527975b10015a62636a61e5b6e20661824c6ddbdfe3eefe"},"package":"a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"} \ No newline at end of file diff --git a/vendor/addr2line/CHANGELOG.md b/vendor/addr2line/CHANGELOG.md index 914139400..ed47aa90d 100644 --- a/vendor/addr2line/CHANGELOG.md +++ b/vendor/addr2line/CHANGELOG.md @@ -1,3 +1,30 @@ +## 0.19.0 (2022/11/24) + +### Breaking changes + +* Updated `gimli` and `object` dependencies. + +-------------------------------------------------------------------------------- + +## 0.18.0 (2022/07/16) + +### Breaking changes + +* Updated `object` dependency. + +### Changed + +* Fixed handling of relative path for `DW_AT_comp_dir`. + [#239](https://github.com/gimli-rs/addr2line/pull/239) + +* Fixed handling of `DW_FORM_addrx` for DWARF 5 support. + [#243](https://github.com/gimli-rs/addr2line/pull/243) + +* Fixed handling of units that are missing range information. + [#249](https://github.com/gimli-rs/addr2line/pull/249) + +-------------------------------------------------------------------------------- + ## 0.17.0 (2021/10/24) ### Breaking changes diff --git a/vendor/addr2line/Cargo.lock b/vendor/addr2line/Cargo.lock index 630d72438..330f3f544 100644 --- a/vendor/addr2line/Cargo.lock +++ b/vendor/addr2line/Cargo.lock @@ -4,16 +4,16 @@ version = 3 [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ - "gimli 0.25.0", + "gimli 0.26.2", ] [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" dependencies = [ "backtrace", "clap", @@ -21,9 +21,9 @@ dependencies = [ "cpp_demangle", "fallible-iterator", "findshlibs", - "gimli 0.26.0", - "memmap", - "object", + "gimli 0.27.0", + "memmap2", + "object 0.30.0", "rustc-demangle", "rustc-std-workspace-alloc", "rustc-std-workspace-core", @@ -38,15 +38,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "atty" version = "0.2.14" @@ -60,22 +51,22 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.62" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091bcdf2da9950f96aa522681ce805e6857f6ca8df73833d35736ab2dc78e152" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ - "addr2line 0.16.0", + "addr2line 0.17.0", "cc", "cfg-if", "libc", "miniz_oxide", - "object", + "object 0.29.0", "rustc-demangle", ] @@ -87,9 +78,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.71" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -99,39 +90,48 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.33.3" +version = "3.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "ab8b79fe3946ceb4a0b1c080b4018992b8d27e9ff363644c1c9b6387c854614d" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_lex", + "indexmap", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", ] [[package]] name = "compiler_builtins" -version = "0.1.51" +version = "0.1.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3587b3669d6f2c1cfd34c475272dabcfef29d52703933f6f72ebb36d6bd81a97" +checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784" [[package]] name = "cpp_demangle" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea47428dc9d2237f3c6bc134472edfd63ebba0af932e783506dcfd66f10d18a" +checksum = "b446fd40bcc17eddd6a4a78f24315eb90afdb3334999ddfd4909985c47722442" dependencies = [ "cfg-if", ] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] @@ -144,9 +144,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "findshlibs" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d691fdb3f817632d259d09220d4cf0991dbb2c9e59e044a02a59194bf6e14484" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" dependencies = [ "cc", "lazy_static", @@ -156,13 +156,11 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -177,15 +175,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" [[package]] name = "gimli" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a03ce013ffccead76c11a15751231f777d9295b845cc1266ed4d34fcbd7977" +checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" dependencies = [ "compiler_builtins", "fallible-iterator", @@ -194,6 +192,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hashbrown" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -203,6 +207,16 @@ dependencies = [ "libc", ] +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -221,46 +235,59 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.105" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869d572136620d55835903746bcb5cdc54cb2851fd0aeec53220b4bb65ef3013" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "memmap" -version = "0.7.0" +name = "memmap2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" dependencies = [ "libc", - "winapi 0.3.9", ] [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" dependencies = [ "adler", - "autocfg", ] [[package]] name = "object" -version = "0.27.1" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "object" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" dependencies = [ "flate2", "memchr", ] +[[package]] +name = "os_str_bytes" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -325,9 +352,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "stable_deref_trait" @@ -337,9 +364,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "term" @@ -352,14 +379,20 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ - "unicode-width", + "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "time" version = "0.1.44" @@ -383,12 +416,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -423,6 +450,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/vendor/addr2line/Cargo.toml b/vendor/addr2line/Cargo.toml index 358995e53..2b51239b8 100644 --- a/vendor/addr2line/Cargo.toml +++ b/vendor/addr2line/Cargo.toml @@ -3,38 +3,40 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] name = "addr2line" -version = "0.17.0" -exclude = ["/benches/*", "/fixtures/*", ".github"] +version = "0.19.0" +exclude = [ + "/benches/*", + "/fixtures/*", + ".github", +] description = "A cross-platform symbolication library written in Rust, using `gimli`" documentation = "https://docs.rs/addr2line" readme = "./README.md" -keywords = ["DWARF", "debug", "elf", "symbolicate", "atos"] +keywords = [ + "DWARF", + "debug", + "elf", + "symbolicate", + "atos", +] categories = ["development-tools::debugging"] license = "Apache-2.0 OR MIT" repository = "https://github.com/gimli-rs/addr2line" + [profile.bench] codegen-units = 1 debug = true -split-debuginfo = "packed" - -[profile.dev] -split-debuginfo = "packed" [profile.release] debug = true -split-debuginfo = "packed" - -[profile.test] -split-debuginfo = "packed" [[example]] name = "addr2line" @@ -52,6 +54,7 @@ required-features = ["default"] [[test]] name = "parse" required-features = ["std-object"] + [dependencies.alloc] version = "1.0.0" optional = true @@ -67,7 +70,8 @@ optional = true package = "rustc-std-workspace-core" [dependencies.cpp_demangle] -version = "0.3" +version = "0.4" +features = ["alloc"] optional = true default-features = false @@ -77,12 +81,12 @@ optional = true default-features = false [dependencies.gimli] -version = "0.26" +version = "0.27.0" features = ["read"] default-features = false [dependencies.object] -version = "0.27.1" +version = "0.30.0" features = ["read"] optional = true default-features = false @@ -95,17 +99,18 @@ optional = true version = "1" optional = true default-features = false + [dev-dependencies.backtrace] version = "0.3.13" [dev-dependencies.clap] -version = "2" +version = "3.1.6" [dev-dependencies.findshlibs] version = "0.10" -[dev-dependencies.memmap] -version = "0.7" +[dev-dependencies.memmap2] +version = "0.5.5" [dev-dependencies.rustc-test] version = "0.3" @@ -114,7 +119,24 @@ version = "0.3" version = "2" [features] -default = ["rustc-demangle", "cpp_demangle", "std-object", "fallible-iterator", "smallvec"] -rustc-dep-of-std = ["core", "alloc", "compiler_builtins", "gimli/rustc-dep-of-std"] +default = [ + "rustc-demangle", + "cpp_demangle", + "std-object", + "fallible-iterator", + "smallvec", +] +rustc-dep-of-std = [ + "core", + "alloc", + "compiler_builtins", + "gimli/rustc-dep-of-std", +] std = ["gimli/std"] -std-object = ["std", "object", "object/std", "object/compression", "gimli/endian-reader"] +std-object = [ + "std", + "object", + "object/std", + "object/compression", + "gimli/endian-reader", +] diff --git a/vendor/addr2line/examples/addr2line.rs b/vendor/addr2line/examples/addr2line.rs index 4b228a706..fa4d8e457 100644 --- a/vendor/addr2line/examples/addr2line.rs +++ b/vendor/addr2line/examples/addr2line.rs @@ -2,7 +2,7 @@ extern crate addr2line; extern crate clap; extern crate fallible_iterator; extern crate gimli; -extern crate memmap; +extern crate memmap2; extern crate object; extern crate typed_arena; @@ -11,18 +11,18 @@ use std::fs::File; use std::io::{BufRead, Lines, StdinLock, Write}; use std::path::Path; -use clap::{App, Arg, Values}; +use clap::{Arg, Command, Values}; use fallible_iterator::FallibleIterator; -use object::{Object, ObjectSection}; +use object::{Object, ObjectSection, SymbolMap, SymbolMapName}; use typed_arena::Arena; use addr2line::{Context, Location}; -fn parse_uint_from_hex_string(string: &str) -> u64 { +fn parse_uint_from_hex_string(string: &str) -> Option { if string.len() > 2 && string.starts_with("0x") { - u64::from_str_radix(&string[2..], 16).expect("Failed to parse address") + u64::from_str_radix(&string[2..], 16).ok() } else { - u64::from_str_radix(string, 16).expect("Failed to parse address") + u64::from_str_radix(string, 16).ok() } } @@ -32,9 +32,9 @@ enum Addrs<'a> { } impl<'a> Iterator for Addrs<'a> { - type Item = u64; + type Item = Option; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { let text = match *self { Addrs::Args(ref mut vals) => vals.next().map(Cow::from), Addrs::Stdin(ref mut lines) => lines.next().map(Result::unwrap).map(Cow::from), @@ -45,15 +45,18 @@ impl<'a> Iterator for Addrs<'a> { } } -fn print_loc(loc: &Option, basenames: bool, llvm: bool) { - if let Some(ref loc) = *loc { - let file = loc.file.as_ref().unwrap(); - let path = if basenames { - Path::new(Path::new(file).file_name().unwrap()) +fn print_loc(loc: Option<&Location>, basenames: bool, llvm: bool) { + if let Some(ref loc) = loc { + if let Some(ref file) = loc.file.as_ref() { + let path = if basenames { + Path::new(Path::new(file).file_name().unwrap()) + } else { + Path::new(file) + }; + print!("{}:", path.display()); } else { - Path::new(file) - }; - print!("{}:", path.display()); + print!("??:"); + } if llvm { print!("{}:{}", loc.line.unwrap_or(0), loc.column.unwrap_or(0)); } else if let Some(line) = loc.line { @@ -65,15 +68,19 @@ fn print_loc(loc: &Option, basenames: bool, llvm: bool) { } else if llvm { println!("??:0:0"); } else { - println!("??:?"); + println!("??:0"); } } -fn print_function(name: &str, language: Option, demangle: bool) { - if demangle { - print!("{}", addr2line::demangle_auto(Cow::from(name), language)); +fn print_function(name: Option<&str>, language: Option, demangle: bool) { + if let Some(name) = name { + if demangle { + print!("{}", addr2line::demangle_auto(Cow::from(name), language)); + } else { + print!("{}", name); + } } else { - print!("{}", name); + print!("??"); } } @@ -94,77 +101,61 @@ fn load_file_section<'input, 'arena, Endian: gimli::Endianity>( } } +fn find_name_from_symbols<'a>( + symbols: &'a SymbolMap, + probe: u64, +) -> Option<&'a str> { + symbols.get(probe).map(|x| x.name()) +} + fn main() { - let matches = App::new("hardliner") + let matches = Command::new("addr2line") .version("0.1") - .about("A fast addr2line clone") - .arg( - Arg::with_name("exe") - .short("e") + .about("A fast addr2line Rust port") + .args(&[ + Arg::new("exe") + .short('e') .long("exe") .value_name("filename") .help( "Specify the name of the executable for which addresses should be translated.", ) .required(true), - ) - .arg( - Arg::with_name("sup") + Arg::new("sup") .long("sup") .value_name("filename") .help("Path to supplementary object file."), - ) - .arg( - Arg::with_name("functions") - .short("f") + Arg::new("functions") + .short('f') .long("functions") .help("Display function names as well as file and line number information."), - ) - .arg( - Arg::with_name("pretty") - .short("p") - .long("pretty-print") - .help( - "Make the output more human friendly: each location are printed on \ - one line.", - ), - ) - .arg(Arg::with_name("inlines").short("i").long("inlines").help( - "If the address belongs to a function that was inlined, the source \ - information for all enclosing scopes back to the first non-inlined \ - function will also be printed.", - )) - .arg( - Arg::with_name("addresses") - .short("a") - .long("addresses") - .help( - "Display the address before the function name, file and line \ - number information.", - ), - ) - .arg( - Arg::with_name("basenames") - .short("s") + Arg::new("pretty").short('p').long("pretty-print").help( + "Make the output more human friendly: each location are printed on one line.", + ), + Arg::new("inlines").short('i').long("inlines").help( + "If the address belongs to a function that was inlined, the source information for \ + all enclosing scopes back to the first non-inlined function will also be printed.", + ), + Arg::new("addresses").short('a').long("addresses").help( + "Display the address before the function name, file and line number information.", + ), + Arg::new("basenames") + .short('s') .long("basenames") .help("Display only the base of each file name."), - ) - .arg(Arg::with_name("demangle").short("C").long("demangle").help( - "Demangle function names. \ - Specifying a specific demangling style (like GNU addr2line) \ - is not supported. (TODO)", - )) - .arg( - Arg::with_name("llvm") + Arg::new("demangle").short('C').long("demangle").help( + "Demangle function names. \ + Specifying a specific demangling style (like GNU addr2line) is not supported. \ + (TODO)" + ), + Arg::new("llvm") .long("llvm") .help("Display output in the same format as llvm-symbolizer."), - ) - .arg( - Arg::with_name("addrs") + Arg::new("addrs") .takes_value(true) - .multiple(true) + .multiple_occurrences(true) .help("Addresses to use instead of reading from stdin."), - ) + ]) .get_matches(); let arena_data = Arena::new(); @@ -179,7 +170,7 @@ fn main() { let path = matches.value_of("exe").unwrap(); let file = File::open(path).unwrap(); - let map = unsafe { memmap::Mmap::map(&file).unwrap() }; + let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let object = &object::File::parse(&*map).unwrap(); let endian = if object.is_little_endian() { @@ -195,7 +186,7 @@ fn main() { let sup_map; let sup_object = if let Some(sup_path) = matches.value_of("sup") { let sup_file = File::open(sup_path).unwrap(); - sup_map = unsafe { memmap::Mmap::map(&sup_file).unwrap() }; + sup_map = unsafe { memmap2::Mmap::map(&sup_file).unwrap() }; Some(object::File::parse(&*sup_map).unwrap()) } else { None @@ -220,10 +211,11 @@ fn main() { for probe in addrs { if print_addrs { + let addr = probe.unwrap_or(0); if llvm { - print!("0x{:x}", probe); + print!("0x{:x}", addr); } else { - print!("0x{:016x}", probe); + print!("0x{:016x}", addr); } if pretty { print!(": "); @@ -234,44 +226,46 @@ fn main() { if do_functions || do_inlines { let mut printed_anything = false; - let mut frames = ctx.find_frames(probe).unwrap().enumerate(); - while let Some((i, frame)) = frames.next().unwrap() { - if pretty && i != 0 { - print!(" (inlined by) "); - } - - if do_functions { - if let Some(func) = frame.function { - print_function(&func.raw_name().unwrap(), func.language, demangle); - } else if let Some(name) = symbols.get(probe).map(|x| x.name()) { - print_function(name, None, demangle); - } else { - print!("??"); + if let Some(probe) = probe { + let mut frames = ctx.find_frames(probe).unwrap().enumerate(); + while let Some((i, frame)) = frames.next().unwrap() { + if pretty && i != 0 { + print!(" (inlined by) "); } - if pretty { - print!(" at "); - } else { - println!(); + if do_functions { + if let Some(func) = frame.function { + print_function( + func.raw_name().ok().as_ref().map(AsRef::as_ref), + func.language, + demangle, + ); + } else { + let name = find_name_from_symbols(&symbols, probe); + print_function(name, None, demangle); + } + + if pretty { + print!(" at "); + } else { + println!(); + } } - } - print_loc(&frame.location, basenames, llvm); + print_loc(frame.location.as_ref(), basenames, llvm); - printed_anything = true; + printed_anything = true; - if !do_inlines { - break; + if !do_inlines { + break; + } } } if !printed_anything { if do_functions { - if let Some(name) = symbols.get(probe).map(|x| x.name()) { - print_function(name, None, demangle); - } else { - print!("??"); - } + let name = probe.and_then(|probe| find_name_from_symbols(&symbols, probe)); + print_function(name, None, demangle); if pretty { print!(" at "); @@ -280,15 +274,11 @@ fn main() { } } - if llvm { - println!("??:0:0"); - } else { - println!("??:?"); - } + print_loc(None, basenames, llvm); } } else { - let loc = ctx.find_location(probe).unwrap(); - print_loc(&loc, basenames, llvm); + let loc = probe.and_then(|probe| ctx.find_location(probe).unwrap()); + print_loc(loc.as_ref(), basenames, llvm); } if llvm { diff --git a/vendor/addr2line/src/function.rs b/vendor/addr2line/src/function.rs index 1589acdbe..44dc73f24 100644 --- a/vendor/addr2line/src/function.rs +++ b/vendor/addr2line/src/function.rs @@ -68,15 +68,24 @@ impl Functions { match entries.read_attribute(*spec) { Ok(ref attr) => { match attr.name() { - gimli::DW_AT_low_pc => { - if let gimli::AttributeValue::Addr(val) = attr.value() { - ranges.low_pc = Some(val); + gimli::DW_AT_low_pc => match attr.value() { + gimli::AttributeValue::Addr(val) => { + ranges.low_pc = Some(val) } - } + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.low_pc = + Some(dwarf.sections.address(unit, index)?); + } + _ => {} + }, gimli::DW_AT_high_pc => match attr.value() { gimli::AttributeValue::Addr(val) => { ranges.high_pc = Some(val) } + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.high_pc = + Some(dwarf.sections.address(unit, index)?); + } gimli::AttributeValue::Udata(val) => { ranges.size = Some(val) } @@ -352,13 +361,18 @@ impl InlinedFunction { for spec in abbrev.attributes() { match entries.read_attribute(*spec) { Ok(ref attr) => match attr.name() { - gimli::DW_AT_low_pc => { - if let gimli::AttributeValue::Addr(val) = attr.value() { - ranges.low_pc = Some(val); + gimli::DW_AT_low_pc => match attr.value() { + gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val), + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.low_pc = Some(dwarf.sections.address(unit, index)?); } - } + _ => {} + }, gimli::DW_AT_high_pc => match attr.value() { gimli::AttributeValue::Addr(val) => ranges.high_pc = Some(val), + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.high_pc = Some(dwarf.sections.address(unit, index)?); + } gimli::AttributeValue::Udata(val) => ranges.size = Some(val), _ => {} }, diff --git a/vendor/addr2line/src/lazy.rs b/vendor/addr2line/src/lazy.rs index 280c76b46..a34ed176a 100644 --- a/vendor/addr2line/src/lazy.rs +++ b/vendor/addr2line/src/lazy.rs @@ -11,19 +11,17 @@ impl LazyCell { } pub fn borrow_with(&self, closure: impl FnOnce() -> T) -> &T { - unsafe { - // First check if we're already initialized... - let ptr = self.contents.get(); - if let Some(val) = &*ptr { - return val; - } - // Note that while we're executing `closure` our `borrow_with` may - // be called recursively. This means we need to check again after - // the closure has executed. For that we use the `get_or_insert` - // method which will only perform mutation if we aren't already - // `Some`. - let val = closure(); - (*ptr).get_or_insert(val) + // First check if we're already initialized... + let ptr = self.contents.get(); + if let Some(val) = unsafe { &*ptr } { + return val; } + // Note that while we're executing `closure` our `borrow_with` may + // be called recursively. This means we need to check again after + // the closure has executed. For that we use the `get_or_insert` + // method which will only perform mutation if we aren't already + // `Some`. + let val = closure(); + unsafe { (*ptr).get_or_insert(val) } } } diff --git a/vendor/addr2line/src/lib.rs b/vendor/addr2line/src/lib.rs index b46a98393..3afa37f8f 100644 --- a/vendor/addr2line/src/lib.rs +++ b/vendor/addr2line/src/lib.rs @@ -181,6 +181,7 @@ impl Context { ranges: gimli::RangeLists::new(debug_ranges, debug_rnglists), file_type: gimli::DwarfFileType::Main, sup: None, + abbreviations_cache: gimli::AbbreviationsCache::new(), }) } @@ -404,6 +405,7 @@ impl ResDwarf { }; let mut lang = None; + let mut have_unit_range = false; { let mut entries = dw_unit.entries_raw(None)?; @@ -416,13 +418,18 @@ impl ResDwarf { for spec in abbrev.attributes() { let attr = entries.read_attribute(*spec)?; match attr.name() { - gimli::DW_AT_low_pc => { - if let gimli::AttributeValue::Addr(val) = attr.value() { - ranges.low_pc = Some(val); + gimli::DW_AT_low_pc => match attr.value() { + gimli::AttributeValue::Addr(val) => ranges.low_pc = Some(val), + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.low_pc = Some(sections.address(&dw_unit, index)?); } - } + _ => {} + }, gimli::DW_AT_high_pc => match attr.value() { gimli::AttributeValue::Addr(val) => ranges.high_pc = Some(val), + gimli::AttributeValue::DebugAddrIndex(index) => { + ranges.high_pc = Some(sections.address(&dw_unit, index)?); + } gimli::AttributeValue::Udata(val) => ranges.size = Some(val), _ => {} }, @@ -472,11 +479,12 @@ impl ResDwarf { unit_id, max_end: 0, }); + have_unit_range = true; } } } } else { - ranges.for_each_range(§ions, &dw_unit, |range| { + have_unit_range |= ranges.for_each_range(§ions, &dw_unit, |range| { unit_ranges.push(UnitRange { range, unit_id, @@ -486,11 +494,34 @@ impl ResDwarf { } } + let lines = LazyCell::new(); + if !have_unit_range { + // The unit did not declare any ranges. + // Try to get some ranges from the line program sequences. + if let Some(ref ilnp) = dw_unit.line_program { + if let Ok(lines) = lines + .borrow_with(|| Lines::parse(&dw_unit, ilnp.clone(), &*sections)) + .as_ref() + { + for sequence in lines.sequences.iter() { + unit_ranges.push(UnitRange { + range: gimli::Range { + begin: sequence.start, + end: sequence.end, + }, + unit_id, + max_end: 0, + }) + } + } + } + } + res_units.push(ResUnit { offset, dw_unit, lang, - lines: LazyCell::new(), + lines, funcs: LazyCell::new(), }); } @@ -531,6 +562,111 @@ struct Lines { sequences: Box<[LineSequence]>, } +impl Lines { + fn parse( + dw_unit: &gimli::Unit, + ilnp: gimli::IncompleteLineProgram, + sections: &gimli::Dwarf, + ) -> Result { + let mut sequences = Vec::new(); + let mut sequence_rows = Vec::::new(); + let mut rows = ilnp.rows(); + while let Some((_, row)) = rows.next_row()? { + if row.end_sequence() { + if let Some(start) = sequence_rows.first().map(|x| x.address) { + let end = row.address(); + let mut rows = Vec::new(); + mem::swap(&mut rows, &mut sequence_rows); + sequences.push(LineSequence { + start, + end, + rows: rows.into_boxed_slice(), + }); + } + continue; + } + + let address = row.address(); + let file_index = row.file_index(); + let line = row.line().map(NonZeroU64::get).unwrap_or(0) as u32; + let column = match row.column() { + gimli::ColumnType::LeftEdge => 0, + gimli::ColumnType::Column(x) => x.get() as u32, + }; + + if let Some(last_row) = sequence_rows.last_mut() { + if last_row.address == address { + last_row.file_index = file_index; + last_row.line = line; + last_row.column = column; + continue; + } + } + + sequence_rows.push(LineRow { + address, + file_index, + line, + column, + }); + } + sequences.sort_by_key(|x| x.start); + + let mut files = Vec::new(); + let header = rows.header(); + match header.file(0) { + Some(file) => files.push(render_file(dw_unit, file, header, sections)?), + None => files.push(String::from("")), // DWARF version <= 4 may not have 0th index + } + let mut index = 1; + while let Some(file) = header.file(index) { + files.push(render_file(dw_unit, file, header, sections)?); + index += 1; + } + + Ok(Self { + files: files.into_boxed_slice(), + sequences: sequences.into_boxed_slice(), + }) + } +} + +fn render_file( + dw_unit: &gimli::Unit, + file: &gimli::FileEntry, + header: &gimli::LineProgramHeader, + sections: &gimli::Dwarf, +) -> Result { + let mut path = if let Some(ref comp_dir) = dw_unit.comp_dir { + comp_dir.to_string_lossy()?.into_owned() + } else { + String::new() + }; + + // The directory index 0 is defined to correspond to the compilation unit directory. + if file.directory_index() != 0 { + if let Some(directory) = file.directory(header) { + path_push( + &mut path, + sections + .attr_string(dw_unit, directory)? + .to_string_lossy()? + .as_ref(), + ); + } + } + + path_push( + &mut path, + sections + .attr_string(dw_unit, file.path_name())? + .to_string_lossy()? + .as_ref(), + ); + + Ok(path) +} + struct LineSequence { start: u64, end: u64, @@ -559,68 +695,7 @@ impl ResUnit { None => return Ok(None), }; self.lines - .borrow_with(|| { - let mut sequences = Vec::new(); - let mut sequence_rows = Vec::::new(); - let mut rows = ilnp.clone().rows(); - while let Some((_, row)) = rows.next_row()? { - if row.end_sequence() { - if let Some(start) = sequence_rows.first().map(|x| x.address) { - let end = row.address(); - let mut rows = Vec::new(); - mem::swap(&mut rows, &mut sequence_rows); - sequences.push(LineSequence { - start, - end, - rows: rows.into_boxed_slice(), - }); - } - continue; - } - - let address = row.address(); - let file_index = row.file_index(); - let line = row.line().map(NonZeroU64::get).unwrap_or(0) as u32; - let column = match row.column() { - gimli::ColumnType::LeftEdge => 0, - gimli::ColumnType::Column(x) => x.get() as u32, - }; - - if let Some(last_row) = sequence_rows.last_mut() { - if last_row.address == address { - last_row.file_index = file_index; - last_row.line = line; - last_row.column = column; - continue; - } - } - - sequence_rows.push(LineRow { - address, - file_index, - line, - column, - }); - } - sequences.sort_by_key(|x| x.start); - - let mut files = Vec::new(); - let header = ilnp.header(); - match header.file(0) { - Some(file) => files.push(self.render_file(file, header, sections)?), - None => files.push(String::from("")), // DWARF version <= 4 may not have 0th index - } - let mut index = 1; - while let Some(file) = header.file(index) { - files.push(self.render_file(file, header, sections)?); - index += 1; - } - - Ok(Lines { - files: files.into_boxed_slice(), - sequences: sequences.into_boxed_slice(), - }) - }) + .borrow_with(|| Lines::parse(&self.dw_unit, ilnp.clone(), sections)) .as_ref() .map(Some) .map_err(Error::clone) @@ -688,39 +763,6 @@ impl ResUnit { let location = self.find_location(probe, &dwarf.sections)?; Ok((function, location)) } - - fn render_file( - &self, - file: &gimli::FileEntry, - header: &gimli::LineProgramHeader, - sections: &gimli::Dwarf, - ) -> Result { - let mut path = if let Some(ref comp_dir) = self.dw_unit.comp_dir { - comp_dir.to_string_lossy()?.into_owned() - } else { - String::new() - }; - - if let Some(directory) = file.directory(header) { - path_push( - &mut path, - sections - .attr_string(&self.dw_unit, directory)? - .to_string_lossy()? - .as_ref(), - ); - } - - path_push( - &mut path, - sections - .attr_string(&self.dw_unit, file.path_name())? - .to_string_lossy()? - .as_ref(), - ); - - Ok(path) - } } /// Iterator over `Location`s in a range of addresses, returned by `Context::find_location_range`. @@ -928,7 +970,7 @@ fn path_push(path: &mut String, p: &str) { '/' }; - if !path.ends_with(dir_separator) { + if !path.is_empty() && !path.ends_with(dir_separator) { path.push(dir_separator); } *path += p; diff --git a/vendor/addr2line/tests/correctness.rs b/vendor/addr2line/tests/correctness.rs index 3f7b43373..955e2b831 100644 --- a/vendor/addr2line/tests/correctness.rs +++ b/vendor/addr2line/tests/correctness.rs @@ -2,7 +2,7 @@ extern crate addr2line; extern crate fallible_iterator; extern crate findshlibs; extern crate gimli; -extern crate memmap; +extern crate memmap2; extern crate object; use addr2line::Context; @@ -11,10 +11,10 @@ use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary}; use object::Object; use std::fs::File; -fn find_debuginfo() -> memmap::Mmap { +fn find_debuginfo() -> memmap2::Mmap { let path = std::env::current_exe().unwrap(); let file = File::open(&path).unwrap(); - let map = unsafe { memmap::Mmap::map(&file).unwrap() }; + let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let file = &object::File::parse(&*map).unwrap(); if let Ok(uuid) = file.mach_uuid() { for candidate in path.parent().unwrap().read_dir().unwrap() { @@ -25,7 +25,7 @@ fn find_debuginfo() -> memmap::Mmap { for candidate in path.join("Contents/Resources/DWARF").read_dir().unwrap() { let path = candidate.unwrap().path(); let file = File::open(&path).unwrap(); - let map = unsafe { memmap::Mmap::map(&file).unwrap() }; + let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let file = &object::File::parse(&*map).unwrap(); if file.mach_uuid().unwrap() == uuid { return map; @@ -41,11 +41,12 @@ fn find_debuginfo() -> memmap::Mmap { fn correctness() { let map = find_debuginfo(); let file = &object::File::parse(&*map).unwrap(); + let module_base = file.relative_address_base(); let ctx = Context::new(file).unwrap(); let mut bias = None; TargetSharedLibrary::each(|lib| { - bias = Some(lib.virtual_memory_bias().0 as u64); + bias = Some((lib.virtual_memory_bias().0 as u64).wrapping_sub(module_base)); IterationControl::Break }); diff --git a/vendor/addr2line/tests/output_equivalence.rs b/vendor/addr2line/tests/output_equivalence.rs index 9dc366672..c0e1f8335 100644 --- a/vendor/addr2line/tests/output_equivalence.rs +++ b/vendor/addr2line/tests/output_equivalence.rs @@ -11,6 +11,7 @@ use backtrace::Backtrace; use findshlibs::{IterationControl, SharedLibrary, TargetSharedLibrary}; use test::{ShouldPanic, TestDesc, TestDescAndFn, TestFn, TestName}; +#[inline(never)] fn make_trace() -> Vec { fn foo() -> Backtrace { bar() diff --git a/vendor/addr2line/tests/parse.rs b/vendor/addr2line/tests/parse.rs index 91d66e382..60b2300b5 100644 --- a/vendor/addr2line/tests/parse.rs +++ b/vendor/addr2line/tests/parse.rs @@ -1,5 +1,5 @@ extern crate addr2line; -extern crate memmap; +extern crate memmap2; extern crate object; use std::borrow::Cow; @@ -25,7 +25,7 @@ fn release_fixture_path() -> PathBuf { fn with_file(target: &path::Path, f: F) { let file = File::open(target).unwrap(); - let map = unsafe { memmap::Mmap::map(&file).unwrap() }; + let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let file = object::File::parse(&*map).unwrap(); f(&file) } -- cgit v1.2.3