summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSymbolication
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-09-04 20:29:06 +0200
committerAndreas Kling <kling@serenityos.org>2021-09-04 20:30:56 +0200
commit24ef8b118ad69c3e7a8f00509ea0175f8d9fb2da (patch)
tree544cc85223be3e7f542a14b7b39517edc726b280 /Userland/Libraries/LibSymbolication
parentb7ee0191ea8a238a2607258a9c75809615680372 (diff)
downloadserenity-24ef8b118ad69c3e7a8f00509ea0175f8d9fb2da.zip
LibSymbolication: Unbreak symbolication with `-z separate-code` linking
We were incorrectly assuming that the mapped .text segment for an ELF image was always at the base of the image mapping. Now that we have .rodata mappings as well, it's possible for one of them to come before the .text.
Diffstat (limited to 'Userland/Libraries/LibSymbolication')
-rw-r--r--Userland/Libraries/LibSymbolication/Symbolication.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/Userland/Libraries/LibSymbolication/Symbolication.cpp b/Userland/Libraries/LibSymbolication/Symbolication.cpp
index f9adaa05e0..459c91bf63 100644
--- a/Userland/Libraries/LibSymbolication/Symbolication.cpp
+++ b/Userland/Libraries/LibSymbolication/Symbolication.cpp
@@ -169,7 +169,7 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
String path;
if (name == "/usr/lib/Loader.so") {
path = name;
- } else if (name.ends_with(": .text")) {
+ } else if (name.ends_with(": .text") || name.ends_with(": .rodata")) {
auto parts = name.split_view(':');
path = parts[0];
if (!path.starts_with('/'))
@@ -208,7 +208,19 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
continue;
}
- FlatPtr adjusted_address = address - found_region->base;
+ // We found an address inside of a region, but the base of that region
+ // may not be the base of the ELF image. For example, there could be an
+ // .rodata mapping at a lower address than the first .text mapping from
+ // the same image. look for the lowest address region with the same path.
+ RegionWithSymbols const* base_region = nullptr;
+ for (auto& region : regions) {
+ if (region.path != found_region->path)
+ continue;
+ if (!base_region || region.base <= base_region->base)
+ base_region = &region;
+ }
+
+ FlatPtr adjusted_address = address - base_region->base;
// We're subtracting 1 from the address because this is the return address,
// i.e. it is one instruction past the call instruction.