Skip to content

Commit 6bb00e1

Browse files
author
Kai Luo
committed
Add AIX support
1 parent 8ad84ca commit 6bb00e1

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

src/symbolize/gimli.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ cfg_if::cfg_if! {
4141
target_os = "openbsd",
4242
target_os = "solaris",
4343
target_os = "illumos",
44+
target_os = "aix",
4445
))] {
4546
#[path = "gimli/mmap_unix.rs"]
4647
mod mmap;
@@ -151,6 +152,9 @@ cfg_if::cfg_if! {
151152
))] {
152153
mod macho;
153154
use self::macho::Object;
155+
} else if #[cfg(target_os = "aix")] {
156+
mod xcoff;
157+
use self::xcoff::Object;
154158
} else {
155159
mod elf;
156160
use self::elf::Object;
@@ -192,6 +196,9 @@ cfg_if::cfg_if! {
192196
} else if #[cfg(target_os = "haiku")] {
193197
mod libs_haiku;
194198
use libs_haiku::native_libraries;
199+
} else if #[cfg(target_os = "aix")] {
200+
mod libs_aix;
201+
use libs_aix::native_libraries;
195202
} else {
196203
// Everything else should doesn't know how to load native libraries.
197204
fn native_libraries() -> Vec<Library> {

src/symbolize/gimli/libs_aix.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use super::mystd::borrow::ToOwned;
2+
use super::mystd::ffi::{CStr, OsStr};
3+
use super::mystd::os::unix::prelude::*;
4+
use super::{Library, LibrarySegment, Vec};
5+
6+
pub(super) fn native_libraries() -> Vec<Library> {
7+
let mut ret = Vec::new();
8+
unsafe {
9+
const BUFFER_SIZE: usize = 4 << 20;
10+
let mut buffer = vec![0i8; BUFFER_SIZE];
11+
if libc::loadquery(libc::L_GETINFO, buffer.as_mut_ptr(), BUFFER_SIZE as u32) < 0 {
12+
panic!("loadquery failed");
13+
}
14+
let mut current = buffer.as_ptr() as *mut libc::ld_info;
15+
loop {
16+
let text_base = (*current).ldinfo_textorg as usize;
17+
if text_base != 0 {
18+
let text_size = (*current).ldinfo_textsize as usize;
19+
let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes();
20+
let name = OsStr::from_bytes(bytes).to_owned();
21+
ret.push(Library {
22+
name,
23+
segments: vec![LibrarySegment {
24+
stated_virtual_memory_address: text_base,
25+
len: text_size,
26+
}],
27+
bias: 0,
28+
});
29+
}
30+
if (*current).ldinfo_next == 0 {
31+
break;
32+
}
33+
current = ((current as i64) + ((*current).ldinfo_next) as i64) as *mut libc::ld_info;
34+
}
35+
}
36+
return ret;
37+
}

src/symbolize/gimli/xcoff.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use super::{Context, Mapping, Path, Stash, Vec};
2+
use object::read::xcoff::XcoffFile64;
3+
use object::Object as _;
4+
use object::ObjectSection as _;
5+
use object::ObjectSymbol as _;
6+
7+
impl Mapping {
8+
pub fn new(path: &Path) -> Option<Mapping> {
9+
let map = super::mmap(path)?;
10+
Mapping::mk(map, |data, stash| {
11+
Context::new(stash, Object::parse(data)?, None)
12+
})
13+
}
14+
}
15+
16+
struct ParsedSym<'a> {
17+
address: u64,
18+
size: u64,
19+
name: &'a str,
20+
}
21+
22+
pub struct Object<'a> {
23+
syms: Vec<ParsedSym<'a>>,
24+
file: XcoffFile64<'a>,
25+
}
26+
27+
impl<'a> Object<'a> {
28+
fn parse(data: &'a [u8]) -> Option<Object<'a>> {
29+
let file = XcoffFile64::parse(data).ok()?;
30+
let mut syms = file
31+
.symbols()
32+
.map(|sym| {
33+
let address = sym.address();
34+
let size = sym.size();
35+
let name = sym.name().map_or("", |v| v);
36+
ParsedSym {
37+
address,
38+
size,
39+
name,
40+
}
41+
})
42+
.collect::<Vec<_>>();
43+
syms.sort_unstable_by_key(|s| s.address);
44+
return Some(Object { syms, file });
45+
}
46+
47+
pub fn section(&self, _: &Stash, name: &str) -> Option<&'a [u8]> {
48+
Some(self.file.section_by_name(name)?.data().ok()?)
49+
}
50+
51+
pub fn search_symtab<'b>(&'b self, addr: u64) -> Option<&'b [u8]> {
52+
let i = match self.syms.binary_search_by_key(&addr, |sym| sym.address) {
53+
Ok(i) => i,
54+
Err(i) => i.checked_sub(1)?,
55+
};
56+
let sym = self.syms.get(i)?;
57+
if sym.address <= addr && addr <= sym.address + sym.size {
58+
Some(sym.name.strip_prefix(".")?.as_bytes())
59+
} else {
60+
None
61+
}
62+
}
63+
64+
pub(super) fn search_object_map(&self, _addr: u64) -> Option<(&Context<'_>, u64)> {
65+
None
66+
}
67+
}

tests/accuracy/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ fn doit() {
3131
dir.push("dylib_dep.dll");
3232
} else if cfg!(target_os = "macos") {
3333
dir.push("libdylib_dep.dylib");
34+
} else if cfg!(target_os = "aix") {
35+
dir.push("libdylib_dep.a");
3436
} else {
3537
dir.push("libdylib_dep.so");
3638
}

0 commit comments

Comments
 (0)