Skip to content

Commit 057ffb5

Browse files
committed
read: add DebugAranges::header
1 parent 890cc89 commit 057ffb5

File tree

2 files changed

+95
-12
lines changed

2 files changed

+95
-12
lines changed

src/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ pub struct DebugAddrBase<T = usize>(pub T);
9999
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
100100
pub struct DebugAddrIndex<T = usize>(pub T);
101101

102+
/// An offset into the `.debug_aranges` section.
103+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104+
pub struct DebugArangesOffset<T = usize>(pub T);
105+
102106
/// An offset into the `.debug_info` section.
103107
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
104108
pub struct DebugInfoOffset<T = usize>(pub T);

src/read/aranges.rs

Lines changed: 91 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::common::{DebugInfoOffset, Encoding, SectionId};
1+
use crate::common::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId};
22
use crate::endianity::Endianity;
33
use crate::read::{EndianSlice, Error, Reader, ReaderOffset, Result, Section};
44

@@ -42,8 +42,16 @@ impl<R: Reader> DebugAranges<R> {
4242
pub fn headers(&self) -> ArangeHeaderIter<R> {
4343
ArangeHeaderIter {
4444
input: self.section.clone(),
45+
offset: DebugArangesOffset(R::Offset::from_u8(0)),
4546
}
4647
}
48+
49+
/// Get the header at the given offset.
50+
pub fn header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>> {
51+
let mut input = self.section.clone();
52+
input.skip(offset.0)?;
53+
ArangeHeader::parse(&mut input, offset)
54+
}
4755
}
4856

4957
impl<T> DebugAranges<T> {
@@ -90,6 +98,7 @@ impl<R> From<R> for DebugAranges<R> {
9098
#[derive(Clone, Debug)]
9199
pub struct ArangeHeaderIter<R: Reader> {
92100
input: R,
101+
offset: DebugArangesOffset<R::Offset>,
93102
}
94103

95104
impl<R: Reader> ArangeHeaderIter<R> {
@@ -99,8 +108,12 @@ impl<R: Reader> ArangeHeaderIter<R> {
99108
return Ok(None);
100109
}
101110

102-
match ArangeHeader::parse(&mut self.input) {
103-
Ok(header) => Ok(Some(header)),
111+
let len = self.input.len();
112+
match ArangeHeader::parse(&mut self.input, self.offset) {
113+
Ok(header) => {
114+
self.offset.0 += len - self.input.len();
115+
Ok(Some(header))
116+
}
104117
Err(e) => {
105118
self.input.empty();
106119
Err(e)
@@ -128,9 +141,10 @@ where
128141
R: Reader<Offset = Offset>,
129142
Offset: ReaderOffset,
130143
{
144+
offset: DebugArangesOffset<Offset>,
131145
encoding: Encoding,
132146
length: Offset,
133-
offset: DebugInfoOffset<Offset>,
147+
debug_info_offset: DebugInfoOffset<Offset>,
134148
segment_size: u8,
135149
entries: R,
136150
}
@@ -140,7 +154,7 @@ where
140154
R: Reader<Offset = Offset>,
141155
Offset: ReaderOffset,
142156
{
143-
fn parse(input: &mut R) -> Result<Self> {
157+
fn parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self> {
144158
let (length, format) = input.read_initial_length()?;
145159
let mut rest = input.split(length)?;
146160

@@ -149,7 +163,7 @@ where
149163
return Err(Error::UnknownVersion(u64::from(version)));
150164
}
151165

152-
let offset = rest.read_offset(format).map(DebugInfoOffset)?;
166+
let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?;
153167
let address_size = rest.read_u8()?;
154168
let segment_size = rest.read_u8()?;
155169

@@ -180,14 +194,21 @@ where
180194
// TODO: segment_size
181195
};
182196
Ok(ArangeHeader {
197+
offset,
183198
encoding,
184199
length,
185-
offset,
200+
debug_info_offset,
186201
segment_size,
187202
entries: rest,
188203
})
189204
}
190205

206+
/// Return the offset of this header within the `.debug_aranges` section.
207+
#[inline]
208+
pub fn offset(&self) -> DebugArangesOffset<Offset> {
209+
self.offset
210+
}
211+
191212
/// Return the length of this set of entries, including the header.
192213
#[inline]
193214
pub fn length(&self) -> Offset {
@@ -209,7 +230,7 @@ where
209230
/// Return the offset into the .debug_info section for this set of arange entries.
210231
#[inline]
211232
pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> {
212-
self.offset
233+
self.debug_info_offset
213234
}
214235

215236
/// Return the arange entries in this set.
@@ -344,6 +365,60 @@ mod tests {
344365
use crate::endianity::LittleEndian;
345366
use crate::read::EndianSlice;
346367

368+
#[test]
369+
fn test_iterate_headers() {
370+
#[rustfmt::skip]
371+
let buf = [
372+
// 32-bit length = 28.
373+
0x1c, 0x00, 0x00, 0x00,
374+
// Version.
375+
0x02, 0x00,
376+
// Offset.
377+
0x01, 0x02, 0x03, 0x04,
378+
// Address size.
379+
0x04,
380+
// Segment size.
381+
0x00,
382+
// Dummy padding and arange tuples.
383+
0x00, 0x00, 0x00, 0x00,
384+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386+
387+
// 32-bit length = 36.
388+
0x24, 0x00, 0x00, 0x00,
389+
// Version.
390+
0x02, 0x00,
391+
// Offset.
392+
0x11, 0x12, 0x13, 0x14,
393+
// Address size.
394+
0x04,
395+
// Segment size.
396+
0x00,
397+
// Dummy padding and arange tuples.
398+
0x00, 0x00, 0x00, 0x00,
399+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402+
];
403+
404+
let debug_aranges = DebugAranges::new(&buf, LittleEndian);
405+
let mut headers = debug_aranges.headers();
406+
407+
let header = headers
408+
.next()
409+
.expect("should parse header ok")
410+
.expect("should have a header");
411+
assert_eq!(header.offset(), DebugArangesOffset(0));
412+
assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201));
413+
414+
let header = headers
415+
.next()
416+
.expect("should parse header ok")
417+
.expect("should have a header");
418+
assert_eq!(header.offset(), DebugArangesOffset(0x20));
419+
assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211));
420+
}
421+
347422
#[test]
348423
fn test_parse_header_ok() {
349424
#[rustfmt::skip]
@@ -378,7 +453,8 @@ mod tests {
378453

379454
let rest = &mut EndianSlice::new(&buf, LittleEndian);
380455

381-
let header = ArangeHeader::parse(rest).expect("should parse header ok");
456+
let header =
457+
ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok");
382458

383459
assert_eq!(
384460
*rest,
@@ -387,13 +463,14 @@ mod tests {
387463
assert_eq!(
388464
header,
389465
ArangeHeader {
466+
offset: DebugArangesOffset(0x10),
390467
encoding: Encoding {
391468
format: Format::Dwarf32,
392469
version: 2,
393470
address_size: 8,
394471
},
395472
length: 0x20,
396-
offset: DebugInfoOffset(0x0403_0201),
473+
debug_info_offset: DebugInfoOffset(0x0403_0201),
397474
segment_size: 4,
398475
entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian),
399476
}
@@ -434,7 +511,8 @@ mod tests {
434511

435512
let rest = &mut EndianSlice::new(&buf, LittleEndian);
436513

437-
let error = ArangeHeader::parse(rest).expect_err("should fail to parse header");
514+
let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
515+
.expect_err("should fail to parse header");
438516
assert_eq!(error, Error::InvalidAddressRange);
439517
}
440518

@@ -473,7 +551,8 @@ mod tests {
473551

474552
let rest = &mut EndianSlice::new(&buf, LittleEndian);
475553

476-
let error = ArangeHeader::parse(rest).expect_err("should fail to parse header");
554+
let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10))
555+
.expect_err("should fail to parse header");
477556
assert_eq!(error, Error::InvalidAddressRange);
478557
}
479558

0 commit comments

Comments
 (0)