Skip to content

Commit 90c96ea

Browse files
committed
Update gimli to 0.17.0
1 parent 1813bf0 commit 90c96ea

File tree

8 files changed

+82
-93
lines changed

8 files changed

+82
-93
lines changed

unwind/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "0.1.0"
44
authors = ["main() <[email protected]>"]
55

66
[dependencies]
7-
gimli = "0.16.1"
7+
gimli = "0.17"
88
libc = "0.2"
99
fallible-iterator = "0.1"
1010
log = "0.4"

unwind/src/find_cfi/baremetal.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@ pub fn find_cfi_sections() -> Vec<EhRef> {
1414
unsafe {
1515
// Safety: None of those are actual accesses - we only get the address
1616
// of those values.
17-
let text_start = &__text_start as *const _ as u64;
18-
let text_end = &__text_end as *const _ as u64;
19-
let cfi_start = &__ehframehdr_start as *const _ as u64;
20-
let cfi_end = &__ehframehdr_end as *const _ as u64;
21-
let ehframe_end = &__ehframe_end as *const _ as u64;
17+
let text = AddrRange {
18+
start: &__text_start as *const _ as u64,
19+
end: &__text_end as *const _ as u64,
20+
};
21+
let eh_frame_hdr = AddrRange {
22+
start: &__ehframehdr_start as *const _ as u64,
23+
end: &__ehframehdr_end as *const _ as u64,
24+
};
25+
let eh_frame_end = &__ehframe_end as *const _ as u64;
2226

2327
cfi.push(EhRef {
2428
obj_base: 0,
25-
text: AddrRange { start: text_start, end: text_end },
26-
cfi: AddrRange { start: cfi_start, end: cfi_end },
27-
ehframe_end,
29+
text,
30+
eh_frame_hdr,
31+
eh_frame_end,
2832
});
2933
}
3034
trace!("CFI sections: {:?}", cfi);

unwind/src/find_cfi/ld.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ extern "C" fn callback(info: *const DlPhdrInfo, size: usize, data: *mut c_void)
5858
let phdr = slice::from_raw_parts((*info).phdr, (*info).phnum as usize);
5959

6060
if let Some(text) = phdr.iter().filter(|x| x.type_ == PT_LOAD && x.flags & PF_X != 0).next() {
61-
if let Some(eh_frame) = phdr.iter().filter(|x| x.type_ == PT_GNU_EH_FRAME).next() {
61+
if let Some(eh_frame_hdr) = phdr.iter().filter(|x| x.type_ == PT_GNU_EH_FRAME).next() {
6262
let start_addr = (*info).addr + text.vaddr;
63-
let cfi_start = (*info).addr + eh_frame.vaddr;
63+
let eh_frame_hdr_start = (*info).addr + eh_frame_hdr.vaddr;
6464
let max_vaddr = phdr.iter().filter(|x| x.type_ == PT_LOAD)
6565
.fold(0, |vaddr, x| cmp::max(vaddr, x.vaddr + x.memsz));
6666
// This is an upper bound, not the exact address.
67-
let ehframe_end = (*info).addr + max_vaddr;
67+
let eh_frame_end = (*info).addr + max_vaddr;
6868
(*data).push(EhRef {
6969
obj_base: (*info).addr,
7070
text: AddrRange { start: start_addr, end: start_addr + text.memsz },
71-
cfi: AddrRange { start: cfi_start, end: cfi_start + eh_frame.memsz },
72-
ehframe_end,
71+
eh_frame_hdr: AddrRange { start: eh_frame_hdr_start, end: eh_frame_hdr_start + eh_frame_hdr.memsz },
72+
eh_frame_end,
7373
});
7474
}
7575
}

unwind/src/find_cfi/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use range::AddrRange;
44
pub struct EhRef {
55
pub obj_base: u64,
66
pub text: AddrRange,
7-
pub cfi: AddrRange,
8-
pub ehframe_end: u64,
7+
pub eh_frame_hdr: AddrRange,
8+
pub eh_frame_end: u64,
99
}
1010

1111
#[cfg(unix)]

unwind/src/glue.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use gimli::X86_64;
12
use super::{UnwindPayload, StackFrames};
2-
use registers::{Registers, DwarfRegister};
3+
use registers::Registers;
34

45
#[allow(improper_ctypes)] // trampoline just forwards the ptr
56
extern "C" {
@@ -96,14 +97,14 @@ pub unsafe extern "C" fn unwind_recorder(payload: *mut UnwindPayload, stack: u64
9697
let saved_regs = &*saved_regs;
9798

9899
let mut registers = Registers::default();
99-
registers[DwarfRegister::Rbx] = Some(saved_regs.rbx);
100-
registers[DwarfRegister::Rbp] = Some(saved_regs.rbp);
101-
registers[DwarfRegister::SP] = Some(stack + 8);
102-
registers[DwarfRegister::R12] = Some(saved_regs.r12);
103-
registers[DwarfRegister::R13] = Some(saved_regs.r13);
104-
registers[DwarfRegister::R14] = Some(saved_regs.r14);
105-
registers[DwarfRegister::R15] = Some(saved_regs.r15);
106-
registers[DwarfRegister::IP] = Some(*(stack as *const u64));
100+
registers[X86_64::RBX] = Some(saved_regs.rbx);
101+
registers[X86_64::RBP] = Some(saved_regs.rbp);
102+
registers[X86_64::RSP] = Some(stack + 8);
103+
registers[X86_64::R12] = Some(saved_regs.r12);
104+
registers[X86_64::R13] = Some(saved_regs.r13);
105+
registers[X86_64::R14] = Some(saved_regs.r14);
106+
registers[X86_64::R15] = Some(saved_regs.r15);
107+
registers[X86_64::RA] = Some(*(stack as *const u64));
107108

108109
let mut frames = StackFrames {
109110
unwinder: payload.unwinder,
@@ -116,24 +117,24 @@ pub unsafe extern "C" fn unwind_recorder(payload: *mut UnwindPayload, stack: u64
116117

117118
pub unsafe fn land(regs: &Registers) {
118119
let mut lr = LandingRegisters {
119-
rax: regs[DwarfRegister::Rax].unwrap_or(0),
120-
rbx: regs[DwarfRegister::Rbx].unwrap_or(0),
121-
rcx: regs[DwarfRegister::Rcx].unwrap_or(0),
122-
rdx: regs[DwarfRegister::Rdx].unwrap_or(0),
123-
rdi: regs[DwarfRegister::Rdi].unwrap_or(0),
124-
rsi: regs[DwarfRegister::Rsi].unwrap_or(0),
125-
rbp: regs[DwarfRegister::Rbp].unwrap_or(0),
126-
r8: regs[DwarfRegister::R8 ].unwrap_or(0),
127-
r9: regs[DwarfRegister::R9 ].unwrap_or(0),
128-
r10: regs[DwarfRegister::R10].unwrap_or(0),
129-
r11: regs[DwarfRegister::R11].unwrap_or(0),
130-
r12: regs[DwarfRegister::R12].unwrap_or(0),
131-
r13: regs[DwarfRegister::R13].unwrap_or(0),
132-
r14: regs[DwarfRegister::R14].unwrap_or(0),
133-
r15: regs[DwarfRegister::R15].unwrap_or(0),
134-
rsp: regs[DwarfRegister::SP].unwrap(),
120+
rax: regs[X86_64::RAX].unwrap_or(0),
121+
rbx: regs[X86_64::RBX].unwrap_or(0),
122+
rcx: regs[X86_64::RCX].unwrap_or(0),
123+
rdx: regs[X86_64::RDX].unwrap_or(0),
124+
rdi: regs[X86_64::RDI].unwrap_or(0),
125+
rsi: regs[X86_64::RSI].unwrap_or(0),
126+
rbp: regs[X86_64::RBP].unwrap_or(0),
127+
r8: regs[X86_64::R8 ].unwrap_or(0),
128+
r9: regs[X86_64::R9 ].unwrap_or(0),
129+
r10: regs[X86_64::R10].unwrap_or(0),
130+
r11: regs[X86_64::R11].unwrap_or(0),
131+
r12: regs[X86_64::R12].unwrap_or(0),
132+
r13: regs[X86_64::R13].unwrap_or(0),
133+
r14: regs[X86_64::R14].unwrap_or(0),
134+
r15: regs[X86_64::R15].unwrap_or(0),
135+
rsp: regs[X86_64::RSP].unwrap(),
135136
};
136137
lr.rsp -= 8;
137-
*(lr.rsp as *mut u64) = regs[DwarfRegister::IP].unwrap();
138+
*(lr.rsp as *mut u64) = regs[X86_64::RA].unwrap();
138139
unwind_lander(&lr);
139140
}

unwind/src/lib.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ extern crate libc;
55
extern crate fallible_iterator;
66
#[macro_use] extern crate log;
77

8-
use gimli::{UnwindSection, UnwindTable, UnwindTableRow, EhFrame, BaseAddresses, UninitializedUnwindContext, Pointer, Reader, EndianSlice, NativeEndian, CfaRule, RegisterRule, EhFrameHdr, ParsedEhFrameHdr};
8+
use gimli::{UnwindSection, UnwindTable, UnwindTableRow, EhFrame, BaseAddresses, UninitializedUnwindContext, Pointer, Reader, EndianSlice, NativeEndian, CfaRule, RegisterRule, EhFrameHdr, ParsedEhFrameHdr, X86_64};
99
use fallible_iterator::FallibleIterator;
1010

1111
mod registers;
1212
mod find_cfi;
1313
mod range;
1414
pub mod libunwind_shim;
1515
pub mod glue;
16-
use registers::{Registers, DwarfRegister};
16+
use registers::Registers;
1717
use find_cfi::EhRef;
1818

1919

@@ -53,20 +53,23 @@ impl Default for DwarfUnwinder {
5353
fn default() -> DwarfUnwinder {
5454
let cfi = find_cfi::find_cfi_sections().into_iter().map(|er| {
5555
unsafe {
56-
let bases = BaseAddresses::default().set_cfi(er.cfi.start);
56+
// TODO: set_got()
57+
let bases = BaseAddresses::default()
58+
.set_eh_frame_hdr(er.eh_frame_hdr.start)
59+
.set_text(er.text.start);
5760

58-
let eh_frame_hdr: &'static [u8] = std::slice::from_raw_parts(er.cfi.start as *const u8, er.cfi.len() as usize);
61+
let eh_frame_hdr: &'static [u8] = std::slice::from_raw_parts(er.eh_frame_hdr.start as *const u8, er.eh_frame_hdr.len() as usize);
5962

6063
let eh_frame_hdr = EhFrameHdr::new(eh_frame_hdr, NativeEndian).parse(&bases, 8).unwrap();
6164

62-
let cfi_addr = deref_ptr(eh_frame_hdr.eh_frame_ptr());
63-
let cfi_sz = er.ehframe_end.saturating_sub(cfi_addr);
65+
let eh_frame_addr = deref_ptr(eh_frame_hdr.eh_frame_ptr());
66+
let eh_frame_sz = er.eh_frame_end.saturating_sub(eh_frame_addr);
6467

65-
let eh_frame: &'static [u8] = std::slice::from_raw_parts(cfi_addr as *const u8, cfi_sz as usize);
66-
trace!("cfi at {:p} sz {:x}", cfi_addr as *const u8, cfi_sz);
68+
let eh_frame: &'static [u8] = std::slice::from_raw_parts(eh_frame_addr as *const u8, eh_frame_sz as usize);
69+
trace!("eh_frame at {:p} sz {:x}", eh_frame_addr as *const u8, eh_frame_sz);
6770
let eh_frame = EhFrame::new(eh_frame, NativeEndian);
6871

69-
let bases = bases.set_cfi(cfi_addr).set_data(er.cfi.start);
72+
let bases = bases.set_eh_frame(eh_frame_addr);
7073

7174
ObjectRecord { er, eh_frame_hdr, eh_frame, bases }
7275
}
@@ -167,10 +170,10 @@ impl<'a> FallibleIterator for StackFrames<'a> {
167170

168171
if let Some((row, cfa)) = self.state.take() {
169172
let mut newregs = registers.clone();
170-
newregs[DwarfRegister::IP] = None;
173+
newregs[X86_64::RA] = None;
171174
for &(reg, ref rule) in row.registers() {
172-
trace!("rule {} {:?}", reg, rule);
173-
assert!(reg != 7); // stack = cfa
175+
trace!("rule {:?} {:?}", reg, rule);
176+
assert!(reg != X86_64::RSP); // stack = cfa
174177
newregs[reg] = match *rule {
175178
RegisterRule::Undefined => unreachable!(), // registers[reg],
176179
RegisterRule::SameValue => Some(registers[reg].unwrap()), // not sure why this exists
@@ -189,7 +192,7 @@ impl<'a> FallibleIterator for StackFrames<'a> {
189192
}
190193

191194

192-
if let Some(mut caller) = registers[DwarfRegister::IP] {
195+
if let Some(mut caller) = registers[X86_64::RA] {
193196
caller -= 1; // THIS IS NECESSARY
194197
debug!("caller is 0x{:x}", caller);
195198

unwind/src/libunwind_shim.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
use libc::{c_void, c_int};
44
use fallible_iterator::FallibleIterator;
5+
use gimli::X86_64;
56

6-
use registers::{Registers, DwarfRegister};
7+
use registers::Registers;
78
use super::{DwarfUnwinder, Unwinder};
89

910
#[repr(C)]
@@ -87,12 +88,12 @@ pub unsafe extern "C" fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Conte
8788

8889
#[no_mangle]
8990
pub unsafe extern "C" fn _Unwind_SetGR(ctx: *mut _Unwind_Context, reg_index: c_int, value: _Unwind_Word) {
90-
(*(*ctx).registers)[reg_index as u8] = Some(value as u64);
91+
(*(*ctx).registers)[reg_index as u16] = Some(value as u64);
9192
}
9293

9394
#[no_mangle]
9495
pub unsafe extern "C" fn _Unwind_SetIP(ctx: *mut _Unwind_Context, value: _Unwind_Word) {
95-
(*(*ctx).registers)[DwarfRegister::IP] = Some(value as u64);
96+
(*(*ctx).registers)[X86_64::RA] = Some(value as u64);
9697
}
9798

9899
#[no_mangle]
@@ -118,7 +119,7 @@ unsafe fn unwind_tracer(frames: &mut ::StackFrames, exception: *mut _Unwind_Exce
118119
if let Some(contptr) = (*exception).private_contptr {
119120
loop {
120121
if let Some(frame) = frames.next().unwrap() {
121-
if frames.registers()[DwarfRegister::SP].unwrap() == contptr {
122+
if frames.registers()[X86_64::RSP].unwrap() == contptr {
122123
break;
123124
}
124125
} else {
@@ -134,12 +135,12 @@ unsafe fn unwind_tracer(frames: &mut ::StackFrames, exception: *mut _Unwind_Exce
134135

135136
let mut ctx = _Unwind_Context {
136137
lsda: frame.lsda.unwrap(),
137-
ip: frames.registers()[DwarfRegister::IP].unwrap(),
138+
ip: frames.registers()[X86_64::RA].unwrap(),
138139
initial_address: frame.initial_address,
139140
registers: frames.registers(),
140141
};
141142

142-
(*exception).private_contptr = frames.registers()[DwarfRegister::SP];
143+
(*exception).private_contptr = frames.registers()[X86_64::RSP];
143144

144145
// ABI specifies that phase 1 is optional, so we just run phase 2 (CLEANUP_PHASE)
145146
match personality(1, _Unwind_Action::_UA_CLEANUP_PHASE as c_int, (*exception).exception_class,
@@ -160,7 +161,7 @@ pub unsafe extern "C" fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
160161
while let Some(frame) = frames.next().unwrap() {
161162
let mut ctx = _Unwind_Context {
162163
lsda: frame.lsda.unwrap_or(0),
163-
ip: frames.registers()[DwarfRegister::IP].unwrap(),
164+
ip: frames.registers()[X86_64::RA].unwrap(),
164165
initial_address: frame.initial_address,
165166
registers: frames.registers(),
166167
};

unwind/src/registers.rs

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use gimli;
12
use std::fmt::{Debug, Formatter, Result as FmtResult};
23
use std::ops::{Index, IndexMut};
34

@@ -18,51 +19,30 @@ impl Debug for Registers {
1819
}
1920
}
2021

21-
impl Index<u8> for Registers {
22+
impl Index<u16> for Registers {
2223
type Output = Option<u64>;
2324

24-
fn index(&self, index: u8) -> &Option<u64> {
25+
fn index(&self, index: u16) -> &Option<u64> {
2526
&self.registers[index as usize]
2627
}
2728
}
2829

29-
impl IndexMut<u8> for Registers {
30-
fn index_mut(&mut self, index: u8) -> &mut Option<u64> {
30+
impl IndexMut<u16> for Registers {
31+
fn index_mut(&mut self, index: u16) -> &mut Option<u64> {
3132
&mut self.registers[index as usize]
3233
}
3334
}
3435

35-
impl Index<DwarfRegister> for Registers {
36+
impl Index<gimli::Register> for Registers {
3637
type Output = Option<u64>;
3738

38-
fn index(&self, reg: DwarfRegister) -> &Option<u64> {
39-
&self[reg as u8]
39+
fn index(&self, reg: gimli::Register) -> &Option<u64> {
40+
&self[reg.0]
4041
}
4142
}
4243

43-
impl IndexMut<DwarfRegister> for Registers {
44-
fn index_mut(&mut self, reg: DwarfRegister) -> &mut Option<u64> {
45-
&mut self[reg as u8]
44+
impl IndexMut<gimli::Register> for Registers {
45+
fn index_mut(&mut self, reg: gimli::Register) -> &mut Option<u64> {
46+
&mut self[reg.0]
4647
}
4748
}
48-
49-
pub enum DwarfRegister {
50-
SP = 7,
51-
IP = 16,
52-
53-
Rax = 0,
54-
Rbx = 3,
55-
Rcx = 2,
56-
Rdx = 1,
57-
Rdi = 5,
58-
Rsi = 4,
59-
Rbp = 6,
60-
R8 = 8,
61-
R9 = 9,
62-
R10 = 10,
63-
R11 = 11,
64-
R12 = 12,
65-
R13 = 13,
66-
R14 = 14,
67-
R15 = 15,
68-
}

0 commit comments

Comments
 (0)