summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSymbolication
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-07-22 18:41:52 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-22 21:38:23 +0200
commit60d6137e7345f05cc94462ac1d873a28d5c672fc (patch)
treec9df537235346a74152a74841d437f7b9b9fcf1a /Userland/Libraries/LibSymbolication
parent6115258a5c6fc12c7d8276938a14a2b6b2339fb4 (diff)
downloadserenity-60d6137e7345f05cc94462ac1d873a28d5c672fc.zip
Userland: Use /proc/kernel_base to determine the kernel base address
This removes all the hard-coded kernel base addresses from userspace tools. One downside for this is that e.g. Profiler no longer uses a different color for kernel symbols when run as a non-root user.
Diffstat (limited to 'Userland/Libraries/LibSymbolication')
-rw-r--r--Userland/Libraries/LibSymbolication/Symbolication.cpp54
-rw-r--r--Userland/Libraries/LibSymbolication/Symbolication.h1
2 files changed, 45 insertions, 10 deletions
diff --git a/Userland/Libraries/LibSymbolication/Symbolication.cpp b/Userland/Libraries/LibSymbolication/Symbolication.cpp
index 40983c1988..4199790ecc 100644
--- a/Userland/Libraries/LibSymbolication/Symbolication.cpp
+++ b/Userland/Libraries/LibSymbolication/Symbolication.cpp
@@ -21,6 +21,42 @@ struct CachedELF {
static HashMap<String, OwnPtr<CachedELF>> s_cache;
+enum class KernelBaseState {
+ Uninitialized,
+ Valid,
+ Invalid,
+};
+
+static FlatPtr s_kernel_base;
+static KernelBaseState s_kernel_base_state = KernelBaseState::Uninitialized;
+
+Optional<FlatPtr> kernel_base()
+{
+ if (s_kernel_base_state == KernelBaseState::Uninitialized) {
+ auto file = Core::File::open("/proc/kernel_base", Core::OpenMode::ReadOnly);
+ if (file.is_error()) {
+ s_kernel_base_state = KernelBaseState::Invalid;
+ return {};
+ }
+ auto kernel_base_str = String { file.value()->read_all(), NoChomp };
+#if ARCH(I386)
+ using AddressType = u32;
+#else
+ using AddressType = u64;
+#endif
+ auto maybe_kernel_base = kernel_base_str.to_uint<AddressType>();
+ if (!maybe_kernel_base.has_value()) {
+ s_kernel_base_state = KernelBaseState::Invalid;
+ return {};
+ }
+ s_kernel_base = maybe_kernel_base.value();
+ s_kernel_base_state = KernelBaseState::Valid;
+ }
+ if (s_kernel_base_state == KernelBaseState::Invalid)
+ return {};
+ return s_kernel_base;
+}
+
Optional<Symbol> symbolicate(String const& path, FlatPtr address)
{
if (!s_cache.contains(path)) {
@@ -81,16 +117,14 @@ Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid)
Vector<FlatPtr> stack;
Vector<RegionWithSymbols> regions;
- regions.append(RegionWithSymbols {
- // FIXME: Use /proc for this
-#if ARCH(I386)
- .base = 0xc0000000,
-#else
- .base = 0x2000000000,
-#endif
- .size = 0x3fffffff,
- .path = "/boot/Kernel.debug",
- .is_relative = false });
+ if (auto maybe_kernel_base = kernel_base(); maybe_kernel_base.has_value()) {
+ regions.append(RegionWithSymbols {
+ .base = maybe_kernel_base.value(),
+ .size = 0x3fffffff,
+ .path = "/boot/Kernel.debug",
+ .is_relative = false,
+ });
+ }
{
auto stack_path = String::formatted("/proc/{}/stacks/{}", pid, tid);
diff --git a/Userland/Libraries/LibSymbolication/Symbolication.h b/Userland/Libraries/LibSymbolication/Symbolication.h
index 346dedd3a2..a5a128ecad 100644
--- a/Userland/Libraries/LibSymbolication/Symbolication.h
+++ b/Userland/Libraries/LibSymbolication/Symbolication.h
@@ -18,6 +18,7 @@ struct Symbol {
Vector<Debug::DebugInfo::SourcePosition> source_positions;
};
+Optional<FlatPtr> kernel_base();
Vector<Symbol> symbolicate_thread(pid_t pid, pid_t tid);
Optional<Symbol> symbolicate(String const& path, FlatPtr address);