+ pub fn dynsym(&self) -> Dynsym {
+ let header = self.header();
+ let id = self.id();
+ let names = self.names(id.data, &header).unwrap();
+ for i in 0..header.shnum(id.data) {
+ let s = self.section(i as usize).unwrap();
+ let name = names.name(s.name(id.data) as usize).unwrap();
+ if name.to_bytes() == b".dynsym" {
+ let offset = s.offset(id.data) as usize;
+ let size = s.size(id.data) as usize;
+ if id.class == Bits::B32 {
+ return Dynsym::B32(unsafe {
+ std::slice::from_raw_parts(
+ self.map.as_ptr().add(offset) as *const u8 as *const Elf32Sym,
+ size / std::mem::size_of::<Elf32Sym>(),
+ )
+ })
+ } else if id.class == Bits::B64 {
+ return Dynsym::B64(unsafe {
+ std::slice::from_raw_parts(
+ self.map.as_ptr().add(offset) as *const u8 as *const Elf64Sym,
+ size / std::mem::size_of::<Elf64Sym>(),
+ )
+ })
+ }
+ }
+ }
+ Dynsym::B64(&[])
+ }
+
+ pub fn verneed(&self) -> Vec<(Verneed, Vec<Vernaux>)> {
+ let header = self.header();
+ let id = self.id();
+ let names = self.names(id.data, &header).unwrap();
+ let mut result = Vec::new();
+ for i in 0..header.shnum(id.data) {
+ let s = self.section(i as usize).unwrap();
+ let name = names.name(s.name(id.data) as usize).unwrap();
+ if name.to_bytes() == b".gnu.version_r" {
+ let offset = s.offset(id.data) as usize;
+ let size = s.size(id.data) as usize;
+ unsafe {
+ let mut current = self.map.as_ptr().add(offset) as *const u8;
+ loop {
+ assert!((current as usize) < offset + size);
+ let mut aux = Vec::new();
+ let mut aux_ptr = current.add((&*(current as *const Verneed)).aux as usize) as *const u8;
+ loop {
+ assert!((aux_ptr as usize) < offset + size);
+ aux.push(*(aux_ptr as *const Vernaux));
+ let next = (&*(aux_ptr as *const Vernaux)).next as usize;
+ if next == 0 {
+ break
+ }
+ aux_ptr = aux_ptr.add(next);
+ }
+ result.push((*(current as *const Verneed), aux));
+ let next = (&*(current as *const Vernaux)).next as usize;
+ if next == 0 {
+ break
+ }
+ current = current.add(next);
+ }
+ }
+ }
+ }
+ result
+ }
+