Browse Source

Resolve symbol address for PIE executables

See https://github.com/foniod/redbpf/pull/308 for a similar change.
ajwerner 2 năm trước cách đây
mục cha
commit
1a22792ee7
1 tập tin đã thay đổi với 30 bổ sung4 xóa
  1. 30 4
      aya/src/programs/uprobe.rs

+ 30 - 4
aya/src/programs/uprobe.rs

@@ -1,6 +1,6 @@
 //! User space probes.
 use libc::pid_t;
-use object::{Object, ObjectSymbol};
+use object::{Object, ObjectSection, ObjectSymbol};
 use std::{
     error::Error,
     ffi::CStr,
@@ -319,15 +319,41 @@ enum ResolveSymbolError {
 
     #[error("unknown symbol `{0}`")]
     Unknown(String),
+
+    #[error("symbol `{0}` does not appear in section")]
+    NotInSection(String),
+
+    #[error("symbol `{0}` in section `{1:?}` which has no offset")]
+    SectionFileRangeNone(String, Result<String, object::Error>),
 }
 
 fn resolve_symbol(path: &str, symbol: &str) -> Result<u64, ResolveSymbolError> {
     let data = fs::read(path)?;
     let obj = object::read::File::parse(&*data)?;
 
-    obj.dynamic_symbols()
+    let sym = obj
+        .dynamic_symbols()
         .chain(obj.symbols())
         .find(|sym| sym.name().map(|name| name == symbol).unwrap_or(false))
-        .map(|s| s.address())
-        .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string()))
+        .ok_or_else(|| ResolveSymbolError::Unknown(symbol.to_string()))?;
+
+    let needs_addr_translation = matches!(
+        obj.kind(),
+        object::ObjectKind::Dynamic | object::ObjectKind::Executable
+    );
+    if !needs_addr_translation {
+        Ok(sym.address())
+    } else {
+        let index = sym
+            .section_index()
+            .ok_or_else(|| ResolveSymbolError::NotInSection(symbol.to_string()))?;
+        let section = obj.section_by_index(index)?;
+        let (offset, _size) = section.file_range().ok_or_else(|| {
+            ResolveSymbolError::SectionFileRangeNone(
+                symbol.to_string(),
+                section.name().map(str::to_owned),
+            )
+        })?;
+        Ok(sym.address() - section.address() + offset)
+    }
 }