firmware: create and apply rustfmt policy
Co-authored-by: Egor Savkin <es@m-labs.hk> Co-committed-by: Egor Savkin <es@m-labs.hk>
This commit was merged in pull request #221.
This commit is contained in:
@@ -1451,8 +1451,7 @@ pub const R_AARCH64_TLSDESC_CALL: usize = 569;
|
||||
pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12: usize = 570;
|
||||
pub const R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: usize = 571;
|
||||
pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12: usize = 572;
|
||||
pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: usize =
|
||||
573;
|
||||
pub const R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC: usize = 573;
|
||||
pub const R_AARCH64_COPY: usize = 1024;
|
||||
pub const R_AARCH64_GLOB_DAT: usize = 1025;
|
||||
pub const R_AARCH64_JUMP_SLOT: usize = 1026;
|
||||
@@ -2267,7 +2266,9 @@ pub struct Elf32_Ehdr {
|
||||
pub e_shstrndx: Elf32_Half,
|
||||
}
|
||||
impl Clone for Elf32_Ehdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2288,7 +2289,9 @@ pub struct Elf64_Ehdr {
|
||||
pub e_shstrndx: Elf64_Half,
|
||||
}
|
||||
impl Clone for Elf64_Ehdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2305,7 +2308,9 @@ pub struct Elf32_Shdr {
|
||||
pub sh_entsize: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Shdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2322,7 +2327,9 @@ pub struct Elf64_Shdr {
|
||||
pub sh_entsize: Elf64_Xword,
|
||||
}
|
||||
impl Clone for Elf64_Shdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2335,7 +2342,9 @@ pub struct Elf32_Sym {
|
||||
pub st_shndx: Elf32_Section,
|
||||
}
|
||||
impl Clone for Elf32_Sym {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2348,7 +2357,9 @@ pub struct Elf64_Sym {
|
||||
pub st_size: Elf64_Xword,
|
||||
}
|
||||
impl Clone for Elf64_Sym {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2357,7 +2368,9 @@ pub struct Elf32_Syminfo {
|
||||
pub si_flags: Elf32_Half,
|
||||
}
|
||||
impl Clone for Elf32_Syminfo {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2366,7 +2379,9 @@ pub struct Elf64_Syminfo {
|
||||
pub si_flags: Elf64_Half,
|
||||
}
|
||||
impl Clone for Elf64_Syminfo {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2375,7 +2390,9 @@ pub struct Elf32_Rel {
|
||||
pub r_info: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Rel {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2384,7 +2401,9 @@ pub struct Elf64_Rel {
|
||||
pub r_info: Elf64_Xword,
|
||||
}
|
||||
impl Clone for Elf64_Rel {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2394,7 +2413,9 @@ pub struct Elf32_Rela {
|
||||
pub r_addend: Elf32_Sword,
|
||||
}
|
||||
impl Clone for Elf32_Rela {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2404,7 +2425,9 @@ pub struct Elf64_Rela {
|
||||
pub r_addend: Elf64_Sxword,
|
||||
}
|
||||
impl Clone for Elf64_Rela {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2419,7 +2442,9 @@ pub struct Elf32_Phdr {
|
||||
pub p_align: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Phdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2434,7 +2459,9 @@ pub struct Elf64_Phdr {
|
||||
pub p_align: Elf64_Xword,
|
||||
}
|
||||
impl Clone for Elf64_Phdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)]
|
||||
@@ -2449,10 +2476,14 @@ pub union Elf32_Dyn__bindgen_ty_1 {
|
||||
pub d_ptr: Elf32_Addr,
|
||||
}
|
||||
impl Clone for Elf32_Dyn__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl Clone for Elf32_Dyn {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)]
|
||||
@@ -2467,10 +2498,14 @@ pub union Elf64_Dyn__bindgen_ty_1 {
|
||||
pub d_ptr: Elf64_Addr,
|
||||
}
|
||||
impl Clone for Elf64_Dyn__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl Clone for Elf64_Dyn {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2484,7 +2519,9 @@ pub struct Elf32_Verdef {
|
||||
pub vd_next: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Verdef {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2498,7 +2535,9 @@ pub struct Elf64_Verdef {
|
||||
pub vd_next: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Verdef {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2507,7 +2546,9 @@ pub struct Elf32_Verdaux {
|
||||
pub vda_next: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Verdaux {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2516,7 +2557,9 @@ pub struct Elf64_Verdaux {
|
||||
pub vda_next: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Verdaux {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2528,7 +2571,9 @@ pub struct Elf32_Verneed {
|
||||
pub vn_next: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Verneed {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2540,7 +2585,9 @@ pub struct Elf64_Verneed {
|
||||
pub vn_next: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Verneed {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2552,7 +2599,9 @@ pub struct Elf32_Vernaux {
|
||||
pub vna_next: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Vernaux {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2564,7 +2613,9 @@ pub struct Elf64_Vernaux {
|
||||
pub vna_next: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Vernaux {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)]
|
||||
@@ -2578,10 +2629,14 @@ pub union Elf32_auxv_t__bindgen_ty_1 {
|
||||
pub a_val: u32,
|
||||
}
|
||||
impl Clone for Elf32_auxv_t__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl Clone for Elf32_auxv_t {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)]
|
||||
@@ -2595,10 +2650,14 @@ pub union Elf64_auxv_t__bindgen_ty_1 {
|
||||
pub a_val: u64,
|
||||
}
|
||||
impl Clone for Elf64_auxv_t__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl Clone for Elf64_auxv_t {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2608,7 +2667,9 @@ pub struct Elf32_Nhdr {
|
||||
pub n_type: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Nhdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2618,7 +2679,9 @@ pub struct Elf64_Nhdr {
|
||||
pub n_type: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Nhdr {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2630,7 +2693,9 @@ pub struct Elf32_Move {
|
||||
pub m_stride: Elf32_Half,
|
||||
}
|
||||
impl Clone for Elf32_Move {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2642,7 +2707,9 @@ pub struct Elf64_Move {
|
||||
pub m_stride: Elf64_Half,
|
||||
}
|
||||
impl Clone for Elf64_Move {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)]
|
||||
@@ -2657,7 +2724,9 @@ pub struct Elf32_gptab__bindgen_ty_1 {
|
||||
pub gt_unused: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_gptab__bindgen_ty_1 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2666,10 +2735,14 @@ pub struct Elf32_gptab__bindgen_ty_2 {
|
||||
pub gt_bytes: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_gptab__bindgen_ty_2 {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl Clone for Elf32_gptab {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2679,7 +2752,9 @@ pub struct Elf32_RegInfo {
|
||||
pub ri_gp_value: Elf32_Sword,
|
||||
}
|
||||
impl Clone for Elf32_RegInfo {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2690,7 +2765,9 @@ pub struct Elf_Options {
|
||||
pub info: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf_Options {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2699,7 +2776,9 @@ pub struct Elf_Options_Hw {
|
||||
pub hwp_flags2: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf_Options_Hw {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2711,7 +2790,9 @@ pub struct Elf32_Lib {
|
||||
pub l_flags: Elf32_Word,
|
||||
}
|
||||
impl Clone for Elf32_Lib {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy)]
|
||||
@@ -2723,17 +2804,31 @@ pub struct Elf64_Lib {
|
||||
pub l_flags: Elf64_Word,
|
||||
}
|
||||
impl Clone for Elf64_Lib {
|
||||
fn clone(&self) -> Self { *self }
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
pub type Elf32_Conflict = Elf32_Addr;
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EXIDX_Entry(u32, u32);
|
||||
|
||||
pub fn ELF32_R_SYM(info: Elf32_Word) -> Elf32_Word { info >> 8 }
|
||||
pub fn ELF32_R_TYPE(info: Elf32_Word) -> u8 { info as u8 }
|
||||
pub fn ELF32_R_INFO(sym: Elf32_Word, ty: u8) -> Elf32_Word { sym << 8 | ty as Elf32_Word }
|
||||
pub fn ELF32_R_SYM(info: Elf32_Word) -> Elf32_Word {
|
||||
info >> 8
|
||||
}
|
||||
pub fn ELF32_R_TYPE(info: Elf32_Word) -> u8 {
|
||||
info as u8
|
||||
}
|
||||
pub fn ELF32_R_INFO(sym: Elf32_Word, ty: u8) -> Elf32_Word {
|
||||
sym << 8 | ty as Elf32_Word
|
||||
}
|
||||
|
||||
pub fn ELF32_ST_BIND(info: u8) -> u8 { info >> 4 }
|
||||
pub fn ELF32_ST_TYPE(info: u8) -> u8 { info & 0xf }
|
||||
pub fn ELF32_ST_INFO(bind: u8, ty: u8) -> u8 { (bind << 4) | (ty & 0xf) }
|
||||
pub fn ELF32_ST_BIND(info: u8) -> u8 {
|
||||
info >> 4
|
||||
}
|
||||
pub fn ELF32_ST_TYPE(info: u8) -> u8 {
|
||||
info & 0xf
|
||||
}
|
||||
pub fn ELF32_ST_INFO(bind: u8, ty: u8) -> u8 {
|
||||
(bind << 4) | (ty & 0xf)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use core::{mem, ptr, ops::{Deref, Range}};
|
||||
use super::{
|
||||
Arch,
|
||||
elf::*,
|
||||
};
|
||||
use core::{mem,
|
||||
ops::{Deref, Range},
|
||||
ptr};
|
||||
|
||||
use super::{elf::*, Arch};
|
||||
|
||||
fn read_unaligned<T: Copy>(data: &[u8], offset: usize) -> Option<T> {
|
||||
if data.len() < offset + mem::size_of::<T>() {
|
||||
@@ -31,14 +31,40 @@ impl<'a> File<'a> {
|
||||
|
||||
pub fn arch(&self) -> Option<Arch> {
|
||||
const IDENT_OPENRISC: [u8; EI_NIDENT] = [
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
|
||||
ELFCLASS32, ELFDATA2MSB, EV_CURRENT, ELFOSABI_NONE,
|
||||
/* ABI version */ 0, /* padding */ 0, 0, 0, 0, 0, 0, 0
|
||||
ELFMAG0,
|
||||
ELFMAG1,
|
||||
ELFMAG2,
|
||||
ELFMAG3,
|
||||
ELFCLASS32,
|
||||
ELFDATA2MSB,
|
||||
EV_CURRENT,
|
||||
ELFOSABI_NONE,
|
||||
/* ABI version */ 0,
|
||||
/* padding */ 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
];
|
||||
const IDENT_ARM: [u8; EI_NIDENT] = [
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
|
||||
ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE,
|
||||
/* ABI version */ 0, /* padding */ 0, 0, 0, 0, 0, 0, 0
|
||||
ELFMAG0,
|
||||
ELFMAG1,
|
||||
ELFMAG2,
|
||||
ELFMAG3,
|
||||
ELFCLASS32,
|
||||
ELFDATA2LSB,
|
||||
EV_CURRENT,
|
||||
ELFOSABI_NONE,
|
||||
/* ABI version */ 0,
|
||||
/* padding */ 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
];
|
||||
|
||||
match (self.ehdr.e_ident, self.ehdr.e_machine) {
|
||||
@@ -48,16 +74,14 @@ impl<'a> File<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn program_headers<'b>(&'b self) -> impl Iterator<Item = Option<Elf32_Phdr>> + 'b
|
||||
{
|
||||
pub fn program_headers<'b>(&'b self) -> impl Iterator<Item = Option<Elf32_Phdr>> + 'b {
|
||||
(0..self.ehdr.e_phnum).map(move |i| {
|
||||
let phdr_off = self.ehdr.e_phoff as usize + mem::size_of::<Elf32_Phdr>() * i as usize;
|
||||
self.read_unaligned::<Elf32_Phdr>(phdr_off)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn section_headers<'b>(&'b self) -> impl Iterator<Item = Option<Elf32_Shdr>> + 'b
|
||||
{
|
||||
pub fn section_headers<'b>(&'b self) -> impl Iterator<Item = Option<Elf32_Shdr>> + 'b {
|
||||
(0..self.ehdr.e_shnum).map(move |i| {
|
||||
let shdr_off = self.ehdr.e_shoff as usize + mem::size_of::<Elf32_Shdr>() * i as usize;
|
||||
self.read_unaligned::<Elf32_Shdr>(shdr_off)
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
use core::{
|
||||
ops::{Deref, DerefMut, Range},
|
||||
mem,
|
||||
slice,
|
||||
};
|
||||
use alloc::alloc::{alloc_zeroed, dealloc, Layout, LayoutError};
|
||||
use super::{
|
||||
elf::*,
|
||||
Error,
|
||||
};
|
||||
use core::{mem,
|
||||
ops::{Deref, DerefMut, Range},
|
||||
slice};
|
||||
|
||||
use super::{elf::*, Error};
|
||||
|
||||
pub struct DynamicSection {
|
||||
pub strtab: Range<usize>,
|
||||
@@ -34,17 +30,12 @@ impl Image {
|
||||
slice::from_raw_parts_mut(ptr, size)
|
||||
};
|
||||
|
||||
Ok(Image {
|
||||
layout,
|
||||
data,
|
||||
})
|
||||
Ok(Image { layout, data })
|
||||
}
|
||||
|
||||
/// assumes that self.data is properly aligned
|
||||
pub(crate) fn get_ref<T>(&self, offset: usize) -> Option<&T>
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
where T: Copy {
|
||||
if self.data.len() < offset + mem::size_of::<T>() {
|
||||
None
|
||||
} else if (self.data.as_ptr() as usize + offset) & (mem::align_of::<T>() - 1) != 0 {
|
||||
@@ -66,55 +57,53 @@ impl Image {
|
||||
unsafe { slice::from_raw_parts(ptr, len) }
|
||||
}
|
||||
|
||||
fn dyn_headers<'a>(&'a self, range: Range<usize>) ->
|
||||
impl Iterator<Item = &'a Elf32_Dyn> + 'a
|
||||
{
|
||||
fn dyn_headers<'a>(&'a self, range: Range<usize>) -> impl Iterator<Item = &'a Elf32_Dyn> + 'a {
|
||||
range
|
||||
.step_by(mem::size_of::<Elf32_Dyn>())
|
||||
.filter_map(move |offset| {
|
||||
self.get_ref::<Elf32_Dyn>(offset)
|
||||
})
|
||||
.filter_map(move |offset| self.get_ref::<Elf32_Dyn>(offset))
|
||||
.take_while(|d| unsafe { d.d_un.d_val } as i32 != DT_NULL)
|
||||
}
|
||||
|
||||
pub fn dyn_section(&self, range: Range<usize>) -> Result<DynamicSection, Error> {
|
||||
let (mut strtab_off, mut strtab_sz) = (0, 0);
|
||||
let (mut rel_off, mut rel_sz) = (0, 0);
|
||||
let (mut rela_off, mut rela_sz) = (0, 0);
|
||||
let (mut rel_off, mut rel_sz) = (0, 0);
|
||||
let (mut rela_off, mut rela_sz) = (0, 0);
|
||||
let (mut pltrel_off, mut pltrel_sz) = (0, 0);
|
||||
let (mut hash_off, mut hash_sz) = (0, 0);
|
||||
let (mut hash_off, mut hash_sz) = (0, 0);
|
||||
let mut symtab_off = 0;
|
||||
let mut sym_ent = 0;
|
||||
let mut rel_ent = 0;
|
||||
let mut rela_ent = 0;
|
||||
let mut nbucket = 0;
|
||||
let mut nchain = 0;
|
||||
let mut sym_ent = 0;
|
||||
let mut rel_ent = 0;
|
||||
let mut rela_ent = 0;
|
||||
let mut nbucket = 0;
|
||||
let mut nchain = 0;
|
||||
|
||||
for dyn_header in self.dyn_headers(range) {
|
||||
let val = unsafe { dyn_header.d_un.d_val } as usize;
|
||||
match dyn_header.d_tag {
|
||||
DT_NULL => break,
|
||||
DT_STRTAB => strtab_off = val,
|
||||
DT_STRSZ => strtab_sz = val,
|
||||
DT_SYMTAB => symtab_off = val,
|
||||
DT_SYMENT => sym_ent = val,
|
||||
DT_REL => rel_off = val,
|
||||
DT_RELSZ => rel_sz = val,
|
||||
DT_RELENT => rel_ent = val,
|
||||
DT_RELA => rela_off = val,
|
||||
DT_RELASZ => rela_sz = val,
|
||||
DT_RELAENT => rela_ent = val,
|
||||
DT_JMPREL => pltrel_off = val,
|
||||
DT_PLTRELSZ => pltrel_sz = val,
|
||||
DT_HASH => {
|
||||
nbucket = *self.get_ref::<Elf32_Word>(val + 0)
|
||||
DT_NULL => break,
|
||||
DT_STRTAB => strtab_off = val,
|
||||
DT_STRSZ => strtab_sz = val,
|
||||
DT_SYMTAB => symtab_off = val,
|
||||
DT_SYMENT => sym_ent = val,
|
||||
DT_REL => rel_off = val,
|
||||
DT_RELSZ => rel_sz = val,
|
||||
DT_RELENT => rel_ent = val,
|
||||
DT_RELA => rela_off = val,
|
||||
DT_RELASZ => rela_sz = val,
|
||||
DT_RELAENT => rela_ent = val,
|
||||
DT_JMPREL => pltrel_off = val,
|
||||
DT_PLTRELSZ => pltrel_sz = val,
|
||||
DT_HASH => {
|
||||
nbucket = *self
|
||||
.get_ref::<Elf32_Word>(val + 0)
|
||||
.ok_or("cannot read hash bucket count")? as usize;
|
||||
nchain = *self.get_ref::<Elf32_Word>(val + 4)
|
||||
nchain = *self
|
||||
.get_ref::<Elf32_Word>(val + 4)
|
||||
.ok_or("cannot read hash chain count")? as usize;
|
||||
hash_off = val + 8;
|
||||
hash_sz = (nbucket + nchain) * mem::size_of::<Elf32_Word>();
|
||||
hash_sz = (nbucket + nchain) * mem::size_of::<Elf32_Word>();
|
||||
}
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,28 +112,28 @@ impl Image {
|
||||
let symtab_sz = nchain * mem::size_of::<Elf32_Sym>();
|
||||
|
||||
if strtab_off + strtab_sz > self.data.len() {
|
||||
return Err("invalid strtab offset/size")?
|
||||
return Err("invalid strtab offset/size")?;
|
||||
}
|
||||
if symtab_off + symtab_sz > self.data.len() {
|
||||
return Err("invalid symtab offset/size")?
|
||||
return Err("invalid symtab offset/size")?;
|
||||
}
|
||||
if sym_ent != mem::size_of::<Elf32_Sym>() {
|
||||
return Err("incorrect symbol entry size")?
|
||||
return Err("incorrect symbol entry size")?;
|
||||
}
|
||||
if rel_off + rel_sz > self.data.len() {
|
||||
return Err("invalid rel offset/size")?
|
||||
return Err("invalid rel offset/size")?;
|
||||
}
|
||||
if rel_ent != 0 && rel_ent != mem::size_of::<Elf32_Rel>() {
|
||||
return Err("incorrect relocation entry size")?
|
||||
return Err("incorrect relocation entry size")?;
|
||||
}
|
||||
if rela_off + rela_sz > self.data.len() {
|
||||
return Err("invalid rela offset/size")?
|
||||
return Err("invalid rela offset/size")?;
|
||||
}
|
||||
if rela_ent != 0 && rela_ent != mem::size_of::<Elf32_Rela>() {
|
||||
return Err("incorrect relocation entry size")?
|
||||
return Err("incorrect relocation entry size")?;
|
||||
}
|
||||
if pltrel_off + pltrel_sz > self.data.len() {
|
||||
return Err("invalid pltrel offset/size")?
|
||||
return Err("invalid pltrel offset/size")?;
|
||||
}
|
||||
|
||||
Ok(DynamicSection {
|
||||
@@ -165,7 +154,7 @@ impl Image {
|
||||
|
||||
pub fn write(&self, offset: usize, value: Elf32_Word) -> Result<(), Error> {
|
||||
if offset + mem::size_of::<Elf32_Addr>() > self.data.len() {
|
||||
return Err("relocation out of image bounds")?
|
||||
return Err("relocation out of image bounds")?;
|
||||
}
|
||||
|
||||
let ptr = (self.data.as_ptr() as usize + offset) as *mut Elf32_Addr;
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
extern crate log;
|
||||
extern crate libcortex_a9;
|
||||
extern crate log;
|
||||
|
||||
use core::{convert, fmt, ops::Range, str};
|
||||
use alloc::string::String;
|
||||
use log::{debug, trace};
|
||||
use core::{convert, fmt, ops::Range, str};
|
||||
|
||||
use elf::*;
|
||||
use log::{debug, trace};
|
||||
|
||||
pub mod elf;
|
||||
mod file;
|
||||
@@ -21,11 +22,10 @@ pub enum Arch {
|
||||
OpenRisc,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Parsing(&'static str),
|
||||
Lookup(String)
|
||||
Lookup(String),
|
||||
}
|
||||
|
||||
impl convert::From<&'static str> for Error {
|
||||
@@ -37,10 +37,8 @@ impl convert::From<&'static str> for Error {
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&Error::Parsing(desc) =>
|
||||
write!(f, "parse error: {}", desc),
|
||||
&Error::Lookup(ref sym) =>
|
||||
write!(f, "symbol lookup error: {}", sym),
|
||||
&Error::Parsing(desc) => write!(f, "parse error: {}", desc),
|
||||
&Error::Lookup(ref sym) => write!(f, "symbol lookup error: {}", sym),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,20 +101,22 @@ impl Library {
|
||||
let mut index = self.hash_bucket()[hash as usize % self.hash_bucket().len()] as usize;
|
||||
|
||||
loop {
|
||||
if index == STN_UNDEF { return None }
|
||||
if index == STN_UNDEF {
|
||||
return None;
|
||||
}
|
||||
|
||||
let sym = &self.symtab()[index];
|
||||
let sym_name_off = sym.st_name as usize;
|
||||
match self.strtab().get(sym_name_off..sym_name_off + name.len()) {
|
||||
Some(sym_name) if sym_name == name => {
|
||||
if ELF32_ST_BIND(sym.st_info) & STB_GLOBAL == 0 {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
|
||||
match sym.st_shndx {
|
||||
SHN_UNDEF => return None,
|
||||
SHN_ABS => return Some(self.image.ptr() as u32 + sym.st_value),
|
||||
_ => return Some(self.image.ptr() as u32 + sym.st_value)
|
||||
_ => return Some(self.image.ptr() as u32 + sym.st_value),
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
@@ -127,10 +127,16 @@ impl Library {
|
||||
}
|
||||
|
||||
pub fn name_starting_at(&self, offset: usize) -> Result<&[u8], Error> {
|
||||
let size = self.strtab().iter().skip(offset).position(|&x| x == 0)
|
||||
.ok_or("symbol in symbol table not null-terminated")?;
|
||||
Ok(self.strtab().get(offset..offset + size)
|
||||
.ok_or("cannot read symbol name")?)
|
||||
let size = self
|
||||
.strtab()
|
||||
.iter()
|
||||
.skip(offset)
|
||||
.position(|&x| x == 0)
|
||||
.ok_or("symbol in symbol table not null-terminated")?;
|
||||
Ok(self
|
||||
.strtab()
|
||||
.get(offset..offset + size)
|
||||
.ok_or("cannot read symbol name")?)
|
||||
}
|
||||
|
||||
/// Rebind Rela by `name` to a new `addr`
|
||||
@@ -143,53 +149,59 @@ impl Library {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
data: &[u8],
|
||||
resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>
|
||||
) -> Result<Library, Error> {
|
||||
pub fn load(data: &[u8], resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>) -> Result<Library, Error> {
|
||||
// validate ELF file
|
||||
let file = file::File::new(data)
|
||||
.ok_or("cannot read ELF header")?;
|
||||
let file = file::File::new(data).ok_or("cannot read ELF header")?;
|
||||
if file.ehdr.e_type != ET_DYN {
|
||||
return Err("not a shared library")?
|
||||
return Err("not a shared library")?;
|
||||
}
|
||||
let arch = file.arch()
|
||||
.ok_or("not for a supported architecture")?;
|
||||
let arch = file.arch().ok_or("not for a supported architecture")?;
|
||||
|
||||
// prepare target memory
|
||||
let image_size = file.program_headers()
|
||||
let image_size = file
|
||||
.program_headers()
|
||||
.filter_map(|phdr| phdr.map(|phdr| phdr.p_vaddr + phdr.p_memsz))
|
||||
.max()
|
||||
.unwrap_or(0) as usize;
|
||||
let image_align = file.program_headers()
|
||||
.filter_map(|phdr| phdr.and_then(|phdr| {
|
||||
if phdr.p_type == PT_LOAD {
|
||||
Some(phdr.p_align)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}))
|
||||
let image_align = file
|
||||
.program_headers()
|
||||
.filter_map(|phdr| {
|
||||
phdr.and_then(|phdr| {
|
||||
if phdr.p_type == PT_LOAD {
|
||||
Some(phdr.p_align)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(4) as usize;
|
||||
// 1 image for all segments
|
||||
let mut image = image::Image::new(image_size, image_align)
|
||||
.map_err(|_| "cannot allocate target image")?;
|
||||
debug!("ELF target: {} bytes, align to {:X}, allocated at {:08X}", image_size, image_align, image.ptr() as usize);
|
||||
let mut image = image::Image::new(image_size, image_align).map_err(|_| "cannot allocate target image")?;
|
||||
debug!(
|
||||
"ELF target: {} bytes, align to {:X}, allocated at {:08X}",
|
||||
image_size,
|
||||
image_align,
|
||||
image.ptr() as usize
|
||||
);
|
||||
|
||||
// LOAD
|
||||
for phdr in file.program_headers() {
|
||||
let phdr = phdr.ok_or("cannot read program header")?;
|
||||
trace!("Program header: {:08X}+{:08X} to {:08X}",
|
||||
phdr.p_offset, phdr.p_filesz,
|
||||
image.ptr() as u32
|
||||
trace!(
|
||||
"Program header: {:08X}+{:08X} to {:08X}",
|
||||
phdr.p_offset,
|
||||
phdr.p_filesz,
|
||||
image.ptr() as u32
|
||||
);
|
||||
let file_range = phdr.p_offset as usize..(phdr.p_offset + phdr.p_filesz) as usize;
|
||||
match phdr.p_type {
|
||||
PT_LOAD => {
|
||||
let src = file.get(file_range)
|
||||
let src = file
|
||||
.get(file_range)
|
||||
.ok_or("program header requests an out of bounds load (in file)")?;
|
||||
let dst = image.get_mut(phdr.p_vaddr as usize..
|
||||
(phdr.p_vaddr + phdr.p_filesz) as usize)
|
||||
let dst = image
|
||||
.get_mut(phdr.p_vaddr as usize..(phdr.p_vaddr + phdr.p_filesz) as usize)
|
||||
.ok_or("program header requests an out of bounds load (in target)")?;
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
@@ -203,9 +215,9 @@ pub fn load(
|
||||
let shdr = shdr.ok_or("cannot read section header")?;
|
||||
match shdr.sh_type as usize {
|
||||
SHT_ARM_EXIDX => {
|
||||
let range = shdr.sh_addr as usize..
|
||||
(shdr.sh_addr + shdr.sh_size) as usize;
|
||||
let _ = image.get(range.clone())
|
||||
let range = shdr.sh_addr as usize..(shdr.sh_addr + shdr.sh_size) as usize;
|
||||
let _ = image
|
||||
.get(range.clone())
|
||||
.ok_or("section header specifies EXIDX outside of image (in target)")?;
|
||||
exidx = Some(range);
|
||||
}
|
||||
@@ -214,11 +226,14 @@ pub fn load(
|
||||
}
|
||||
|
||||
// relocate DYNAMIC
|
||||
let dyn_range = file.dyn_header_vaddr()
|
||||
.ok_or("cannot find a dynamic header")?;
|
||||
let dyn_range = file.dyn_header_vaddr().ok_or("cannot find a dynamic header")?;
|
||||
let dyn_section = image.dyn_section(dyn_range.clone())?;
|
||||
debug!("Relocating {} rela, {} rel, {} pltrel",
|
||||
dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len());
|
||||
debug!(
|
||||
"Relocating {} rela, {} rel, {} pltrel",
|
||||
dyn_section.rela.len(),
|
||||
dyn_section.rel.len(),
|
||||
dyn_section.pltrel.len()
|
||||
);
|
||||
let lib = Library {
|
||||
arch,
|
||||
image,
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
use alloc::string::String;
|
||||
|
||||
use libcortex_a9::{asm::{dsb, isb},
|
||||
cache::{bpiall, dcci_slice, iciallu}};
|
||||
use log::trace;
|
||||
use super::{
|
||||
Arch,
|
||||
elf::*,
|
||||
Error,
|
||||
image::Image,
|
||||
Library,
|
||||
};
|
||||
use libcortex_a9::{
|
||||
cache::{dcci_slice, iciallu, bpiall},
|
||||
asm::{dsb, isb},
|
||||
};
|
||||
|
||||
use super::{elf::*, image::Image, Arch, Error, Library};
|
||||
|
||||
pub trait Relocatable {
|
||||
fn offset(&self) -> usize;
|
||||
@@ -66,25 +60,18 @@ enum RelType {
|
||||
impl RelType {
|
||||
pub fn new(arch: Arch, type_info: u8) -> Option<Self> {
|
||||
match type_info {
|
||||
R_OR1K_NONE if arch == Arch::OpenRisc =>
|
||||
Some(RelType::None),
|
||||
R_ARM_NONE if arch == Arch::Arm =>
|
||||
Some(RelType::None),
|
||||
R_OR1K_NONE if arch == Arch::OpenRisc => Some(RelType::None),
|
||||
R_ARM_NONE if arch == Arch::Arm => Some(RelType::None),
|
||||
|
||||
R_OR1K_RELATIVE if arch == Arch::OpenRisc =>
|
||||
Some(RelType::Relative),
|
||||
R_ARM_RELATIVE if arch == Arch::Arm =>
|
||||
Some(RelType::Relative),
|
||||
R_OR1K_RELATIVE if arch == Arch::OpenRisc => Some(RelType::Relative),
|
||||
R_ARM_RELATIVE if arch == Arch::Arm => Some(RelType::Relative),
|
||||
|
||||
R_OR1K_32 | R_OR1K_GLOB_DAT | R_OR1K_JMP_SLOT
|
||||
if arch == Arch::OpenRisc => Some(RelType::LookupAbs),
|
||||
R_ARM_GLOB_DAT | R_ARM_JUMP_SLOT | R_ARM_ABS32
|
||||
if arch == Arch::Arm => Some(RelType::LookupAbs),
|
||||
R_OR1K_32 | R_OR1K_GLOB_DAT | R_OR1K_JMP_SLOT if arch == Arch::OpenRisc => Some(RelType::LookupAbs),
|
||||
R_ARM_GLOB_DAT | R_ARM_JUMP_SLOT | R_ARM_ABS32 if arch == Arch::Arm => Some(RelType::LookupAbs),
|
||||
|
||||
R_ARM_PREL31 if arch == Arch::Arm => Some(RelType::LookupRel),
|
||||
|
||||
_ =>
|
||||
None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,22 +83,25 @@ fn format_sym_name(sym_name: &[u8]) -> String {
|
||||
}
|
||||
|
||||
pub fn relocate<R: Relocatable>(
|
||||
arch: Arch, lib: &Library,
|
||||
rel: &R, resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>
|
||||
arch: Arch,
|
||||
lib: &Library,
|
||||
rel: &R,
|
||||
resolve: &dyn Fn(&[u8]) -> Option<Elf32_Word>,
|
||||
) -> Result<(), Error> {
|
||||
let sym;
|
||||
if rel.sym_info() == 0 {
|
||||
sym = None;
|
||||
} else {
|
||||
sym = Some(lib.symtab().get(rel.sym_info() as usize)
|
||||
.ok_or("symbol out of bounds of symbol table")?)
|
||||
sym = Some(
|
||||
lib.symtab()
|
||||
.get(rel.sym_info() as usize)
|
||||
.ok_or("symbol out of bounds of symbol table")?,
|
||||
)
|
||||
}
|
||||
|
||||
let rel_type = RelType::new(arch, rel.type_info())
|
||||
.ok_or("unsupported relocation type")?;
|
||||
let rel_type = RelType::new(arch, rel.type_info()).ok_or("unsupported relocation type")?;
|
||||
let value = match rel_type {
|
||||
RelType::None =>
|
||||
return Ok(()),
|
||||
RelType::None => return Ok(()),
|
||||
|
||||
RelType::Relative => {
|
||||
let addend = rel.addend(&lib.image);
|
||||
@@ -132,42 +122,48 @@ pub fn relocate<R: Relocatable>(
|
||||
addr
|
||||
} else {
|
||||
// We couldn't find it anywhere.
|
||||
return Err(Error::Lookup(format_sym_name(sym_name)))
|
||||
return Err(Error::Lookup(format_sym_name(sym_name)));
|
||||
};
|
||||
|
||||
match rel_type {
|
||||
RelType::LookupAbs => sym_addr,
|
||||
RelType::LookupRel =>
|
||||
sym_addr.wrapping_sub(
|
||||
lib.image.ptr().wrapping_offset(rel.offset() as isize) as Elf32_Addr),
|
||||
_ => unreachable!()
|
||||
RelType::LookupRel => {
|
||||
sym_addr.wrapping_sub(lib.image.ptr().wrapping_offset(rel.offset() as isize) as Elf32_Addr)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match rel.type_info() {
|
||||
R_ARM_PREL31 => {
|
||||
let reloc_word = lib.image.get_ref::<Elf32_Word>(rel.offset())
|
||||
.ok_or("relocation offset cannot be read")?;
|
||||
lib.image.write(rel.offset(), (reloc_word & 0x80000000) | (value & 0x7FFFFFFF))
|
||||
},
|
||||
let reloc_word = lib
|
||||
.image
|
||||
.get_ref::<Elf32_Word>(rel.offset())
|
||||
.ok_or("relocation offset cannot be read")?;
|
||||
lib.image
|
||||
.write(rel.offset(), (reloc_word & 0x80000000) | (value & 0x7FFFFFFF))
|
||||
}
|
||||
|
||||
_ => lib.image.write(rel.offset(), value),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rebind(
|
||||
arch: Arch, lib: &Library, name: &[u8], value: Elf32_Word
|
||||
) -> Result<(), Error> {
|
||||
pub fn rebind(arch: Arch, lib: &Library, name: &[u8], value: Elf32_Word) -> Result<(), Error> {
|
||||
fn rebind_symbol_to_value<R: Relocatable>(
|
||||
arch: Arch, lib: &Library,name: &[u8], value: Elf32_Word, relocs: &[R]
|
||||
arch: Arch,
|
||||
lib: &Library,
|
||||
name: &[u8],
|
||||
value: Elf32_Word,
|
||||
relocs: &[R],
|
||||
) -> Result<(), Error> {
|
||||
for reloc in relocs {
|
||||
let rel_type = RelType::new(arch, reloc.type_info())
|
||||
.ok_or("unsupported relocation type")?;
|
||||
let rel_type = RelType::new(arch, reloc.type_info()).ok_or("unsupported relocation type")?;
|
||||
match rel_type {
|
||||
RelType::LookupAbs => {
|
||||
let sym = lib.symtab().get(reloc.sym_info() as usize)
|
||||
let sym = lib
|
||||
.symtab()
|
||||
.get(reloc.sym_info() as usize)
|
||||
.ok_or("symbol out of bounds of symbol table")?;
|
||||
let sym_name = lib.name_starting_at(sym.st_name as usize)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user