Skip to content

Commit ddeb873

Browse files
committed
Remove Debug bound from various traits
Remove `Debug` bound from `Reader`, `ReaderOffset`, `UnwindSection` and `UnwindOffset`. This isn't necessary for their operation, and users can define their own trait if they require it. There's a bit of complexity to get the derived Debug implementations to work correctly with associated types. We already had this sort of thing in a lot of places because it helps with lifetime variance too. Also reduce the places where the dwarfdump example uses Debug to print.
1 parent 366f567 commit ddeb873

File tree

15 files changed

+252
-173
lines changed

15 files changed

+252
-173
lines changed

crates/examples/src/bin/convert.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
use gimli::write::Writer;
1010
use object::{Object, ObjectSection};
1111
use std::io::Write;
12-
use std::{borrow, env, error, fs, io};
12+
use std::{borrow, env, error, fmt, fs, io};
13+
14+
trait Reader: gimli::Reader<Offset = usize> + fmt::Debug {}
15+
impl<T: gimli::Reader<Offset = usize> + fmt::Debug> Reader for T {}
1316

1417
fn main() -> Result<(), Box<dyn error::Error>> {
1518
let mut args = env::args_os();
@@ -126,7 +129,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
126129
Ok(())
127130
}
128131

129-
fn convert_dwarf<R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
132+
fn convert_dwarf<R: Reader, W: gimli::write::Writer>(
130133
read_dwarf: &gimli::Dwarf<R>,
131134
dwp: Option<&gimli::DwarfPackage<R>>,
132135
write_sections: &mut gimli::write::Sections<W>,
@@ -169,7 +172,7 @@ fn convert_dwarf<R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
169172
Ok(())
170173
}
171174

172-
fn convert_unit<'a, R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
175+
fn convert_unit<'a, R: Reader, W: gimli::write::Writer>(
173176
unit: &mut gimli::write::ConvertUnit<'a, R>,
174177
root_entry: gimli::write::ConvertUnitEntry<'a, R>,
175178
skeleton_root_entry: Option<&gimli::write::ConvertUnitEntry<'_, R>>,
@@ -210,7 +213,7 @@ fn convert_unit<'a, R: gimli::Reader<Offset = usize>, W: gimli::write::Writer>(
210213
Ok(())
211214
}
212215

213-
fn convert_attributes<R: gimli::Reader<Offset = usize>>(
216+
fn convert_attributes<R: Reader>(
214217
unit: &mut gimli::write::ConvertUnit<'_, R>,
215218
id: gimli::write::UnitEntryId,
216219
entry: &gimli::write::ConvertUnitEntry<'_, R>,
@@ -234,7 +237,7 @@ fn convert_attributes<R: gimli::Reader<Offset = usize>>(
234237
}
235238
}
236239

237-
fn filter_dwarf<R: gimli::Reader<Offset = usize>>(
240+
fn filter_dwarf<R: Reader>(
238241
dwarf: &gimli::read::Dwarf<R>,
239242
) -> gimli::write::ConvertResult<gimli::write::FilterUnitSection<'_, R>> {
240243
// Walk the DIE tree. This will automatically record relationships between DIEs based
@@ -256,7 +259,7 @@ fn filter_dwarf<R: gimli::Reader<Offset = usize>>(
256259
}
257260

258261
/// Use heuristics to determine if an entry is dead code.
259-
fn need_entry<R: gimli::Reader<Offset = usize>>(
262+
fn need_entry<R: Reader>(
260263
entry: &gimli::write::FilterUnitEntry<'_, R>,
261264
) -> gimli::write::ConvertResult<bool> {
262265
match entry.parent_tag {
@@ -371,7 +374,7 @@ fn need_entry<R: gimli::Reader<Offset = usize>>(
371374
Ok(false)
372375
}
373376

374-
fn is_tombstone_address<R: gimli::Reader<Offset = usize>>(
377+
fn is_tombstone_address<R: Reader>(
375378
entry: &gimli::write::FilterUnitEntry<'_, R>,
376379
address: u64,
377380
) -> bool {

crates/examples/src/bin/dwarfdump.rs

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ struct Flags<'a> {
197197
dwp: bool,
198198
dwo_parent: Option<object::File<'a>>,
199199
sup: Option<object::File<'a>>,
200-
raw: bool,
201200
info_offset: Option<gimli::DebugInfoOffset>,
202201
match_units: Option<Regex>,
203202
}
@@ -240,7 +239,6 @@ fn main() {
240239
"use the specified file as the parent of the dwo or dwp (e.g. for .debug_addr)",
241240
"library path",
242241
);
243-
opts.optflag("", "raw", "print raw data values");
244242
opts.optopt(
245243
"u",
246244
"match-units",
@@ -320,9 +318,6 @@ fn main() {
320318
if matches.opt_present("dwp") {
321319
flags.dwp = true;
322320
}
323-
if matches.opt_present("raw") {
324-
flags.raw = true;
325-
}
326321
if all {
327322
// .eh_frame is excluded even when printing all information.
328323
// cosmetic flags like -G must be set explicitly too.
@@ -1241,25 +1236,19 @@ fn dump_entries<R: Reader, W: Write>(
12411236
} else {
12421237
write!(w, "{:27} ", attr.name())?;
12431238
}
1244-
if flags.raw {
1245-
writeln!(w, "{:?}", attr.raw_value())?;
1246-
} else {
1247-
match dump_attr_value(w, &attr, unit) {
1248-
Ok(_) => (),
1249-
Err(err) => {
1250-
writeln_error(w, unit.dwarf, err, "Failed to dump attribute value")?
1251-
}
1252-
};
1253-
// dump_attr_value only prints the offset for the macro info attribute.
1254-
// The content is too long to print inline, so store the offset to print later.
1255-
if attr.name() == gimli::DW_AT_macro_info {
1256-
if let gimli::AttributeValue::DebugMacinfoRef(offset) = attr.value() {
1257-
deferred_macinfo.push(offset);
1258-
}
1259-
} else if attr.name() == gimli::DW_AT_macros {
1260-
if let gimli::AttributeValue::DebugMacroRef(offset) = attr.value() {
1261-
deferred_macros.push(offset);
1262-
}
1239+
match dump_attr_value(w, &attr, unit) {
1240+
Ok(_) => (),
1241+
Err(err) => writeln_error(w, unit.dwarf, err, "Failed to dump attribute value")?,
1242+
};
1243+
// dump_attr_value only prints the offset for the macro info attribute.
1244+
// The content is too long to print inline, so store the offset to print later.
1245+
if attr.name() == gimli::DW_AT_macro_info {
1246+
if let gimli::AttributeValue::DebugMacinfoRef(offset) = attr.value() {
1247+
deferred_macinfo.push(offset);
1248+
}
1249+
} else if attr.name() == gimli::DW_AT_macros {
1250+
if let gimli::AttributeValue::DebugMacroRef(offset) = attr.value() {
1251+
deferred_macros.push(offset);
12631252
}
12641253
}
12651254
}
@@ -1299,18 +1288,18 @@ fn dump_attr_value<R: Reader, W: Write>(
12991288
gimli::AttributeValue::Data1(_)
13001289
| gimli::AttributeValue::Data2(_)
13011290
| gimli::AttributeValue::Data4(_)
1302-
| gimli::AttributeValue::Data8(_)
1303-
| gimli::AttributeValue::Data16(_) => {
1304-
if let (Some(udata), Some(sdata)) = (attr.udata_value(), attr.sdata_value()) {
1305-
if sdata >= 0 {
1306-
writeln!(w, "{}", udata)?;
1307-
} else {
1308-
writeln!(w, "{} ({})", udata, sdata)?;
1309-
}
1291+
| gimli::AttributeValue::Data8(_) => {
1292+
let udata = attr.udata_value().unwrap();
1293+
let sdata = attr.sdata_value().unwrap();
1294+
if sdata >= 0 {
1295+
writeln!(w, "{}", udata)?;
13101296
} else {
1311-
writeln!(w, "{:?}", value)?;
1297+
writeln!(w, "{} ({})", udata, sdata)?;
13121298
}
13131299
}
1300+
gimli::AttributeValue::Data16(data) => {
1301+
writeln!(w, "0x{:x}", data)?;
1302+
}
13141303
gimli::AttributeValue::Sdata(data) => {
13151304
match attr.name() {
13161305
gimli::DW_AT_data_member_location => {
@@ -2158,7 +2147,7 @@ fn dump_line_program<R: Reader, W: Write>(w: &mut W, unit: gimli::UnitRef<R>) ->
21582147
write!(w, "Unknown {} with operand {}", opcode, arg)
21592148
}
21602149
LineInstruction::UnknownStandardN(opcode, ref args) => {
2161-
write!(w, "Unknown {} with operands {:?}", opcode, args)
2150+
write!(w, "Unknown {} with operands {:?}", opcode, args.to_slice()?)
21622151
}
21632152
LineInstruction::EndSequence => write!(w, "{}", constants::DW_LNE_end_sequence),
21642153
LineInstruction::SetAddress(address) => {

src/read/cfi.rs

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ pub enum CieOffsetEncoding {
565565
/// An offset into an `UnwindSection`.
566566
//
567567
// Needed to avoid conflicting implementations of `Into<T>`.
568-
pub trait UnwindOffset<T = usize>: Copy + Debug + Eq + From<T>
568+
pub trait UnwindOffset<T = usize>: Copy + Eq + From<T>
569569
where
570570
T: ReaderOffset,
571571
{
@@ -632,10 +632,14 @@ pub trait _UnwindSectionPrivate<R: Reader> {
632632
/// A section holding unwind information: either `.debug_frame` or
633633
/// `.eh_frame`. See [`DebugFrame`](./struct.DebugFrame.html) and
634634
/// [`EhFrame`](./struct.EhFrame.html) respectively.
635-
pub trait UnwindSection<R: Reader>: Clone + Debug + _UnwindSectionPrivate<R> {
635+
pub trait UnwindSection<R, O = <R as Reader>::Offset>: Clone + _UnwindSectionPrivate<R>
636+
where
637+
R: Reader<Offset = O>,
638+
O: ReaderOffset,
639+
{
636640
/// The offset type associated with this CFI section. Either
637641
/// `DebugFrameOffset` or `EhFrameOffset`.
638-
type Offset: UnwindOffset<R::Offset>;
642+
type Offset: UnwindOffset<O>;
639643

640644
/// Iterate over the `CommonInformationEntry`s and `FrameDescriptionEntry`s
641645
/// in this `.debug_frame` section.
@@ -989,10 +993,11 @@ impl BaseAddresses {
989993
/// # }
990994
/// ```
991995
#[derive(Clone, Debug)]
992-
pub struct CfiEntriesIter<'bases, Section, R>
996+
pub struct CfiEntriesIter<'bases, Section, R, Offset = <R as Reader>::Offset>
993997
where
994-
R: Reader,
995-
Section: UnwindSection<R>,
998+
R: Reader<Offset = Offset>,
999+
Offset: ReaderOffset,
1000+
Section: UnwindSection<R, Offset>,
9961001
{
9971002
section: Section,
9981003
bases: &'bases BaseAddresses,
@@ -1062,17 +1067,24 @@ where
10621067

10631068
/// Either a `CommonInformationEntry` (CIE) or a `FrameDescriptionEntry` (FDE).
10641069
#[derive(Clone, Debug, PartialEq, Eq)]
1065-
pub enum CieOrFde<'bases, Section, R>
1066-
where
1067-
R: Reader,
1068-
Section: UnwindSection<R>,
1070+
pub enum CieOrFde<
1071+
'bases,
1072+
Section,
1073+
R,
1074+
Offset = <R as Reader>::Offset,
1075+
SectionOffset = <Section as UnwindSection<R, Offset>>::Offset,
1076+
> where
1077+
R: Reader<Offset = Offset>,
1078+
Offset: ReaderOffset,
1079+
Section: UnwindSection<R, Offset, Offset = SectionOffset>,
1080+
SectionOffset: UnwindOffset<Offset>,
10691081
{
10701082
/// This CFI entry is a `CommonInformationEntry`.
1071-
Cie(CommonInformationEntry<R>),
1083+
Cie(CommonInformationEntry<R, Offset>),
10721084
/// This CFI entry is a `FrameDescriptionEntry`, however fully parsing it
10731085
/// requires parsing its CIE first, so it is left in a partially parsed
10741086
/// state.
1075-
Fde(PartialFrameDescriptionEntry<'bases, Section, R>),
1087+
Fde(PartialFrameDescriptionEntry<'bases, Section, R, Offset, SectionOffset>),
10761088
}
10771089

10781090
fn parse_cfi_entry<'bases, Section, R>(
@@ -1520,15 +1532,22 @@ impl<R: Reader> CommonInformationEntry<R> {
15201532
///
15211533
/// Fully parsing this FDE requires first parsing its CIE.
15221534
#[derive(Clone, Debug, PartialEq, Eq)]
1523-
pub struct PartialFrameDescriptionEntry<'bases, Section, R>
1524-
where
1525-
R: Reader,
1526-
Section: UnwindSection<R>,
1535+
pub struct PartialFrameDescriptionEntry<
1536+
'bases,
1537+
Section,
1538+
R,
1539+
Offset = <R as Reader>::Offset,
1540+
SectionOffset = <Section as UnwindSection<R, Offset>>::Offset,
1541+
> where
1542+
R: Reader<Offset = Offset>,
1543+
Offset: ReaderOffset,
1544+
Section: UnwindSection<R, Offset, Offset = SectionOffset>,
1545+
SectionOffset: UnwindOffset<Offset>,
15271546
{
1528-
offset: R::Offset,
1529-
length: R::Offset,
1547+
offset: Offset,
1548+
length: Offset,
15301549
format: Format,
1531-
cie_offset: Section::Offset,
1550+
cie_offset: SectionOffset,
15321551
rest: R,
15331552
section: Section,
15341553
bases: &'bases BaseAddresses,
@@ -1973,7 +1992,7 @@ where
19731992

19741993
impl<T, S> Debug for UnwindContext<T, S>
19751994
where
1976-
T: ReaderOffset,
1995+
T: ReaderOffset + Debug,
19771996
S: UnwindContextStorage<T>,
19781997
{
19791998
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -2537,7 +2556,7 @@ where
25372556

25382557
impl<T, S> Debug for RegisterRuleMap<T, S>
25392558
where
2540-
T: ReaderOffset,
2559+
T: ReaderOffset + Debug,
25412560
S: UnwindContextStorage<T>,
25422561
{
25432562
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -2710,7 +2729,7 @@ where
27102729

27112730
impl<T, S> Debug for UnwindTableRow<T, S>
27122731
where
2713-
T: ReaderOffset,
2732+
T: ReaderOffset + Debug,
27142733
S: UnwindContextStorage<T>,
27152734
{
27162735
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -3743,7 +3762,7 @@ mod tests {
37433762
fn endian<'input, E>(self) -> Endian
37443763
where
37453764
E: Endianity,
3746-
T: UnwindSection<EndianSlice<'input, E>>,
3765+
T: UnwindSection<EndianSlice<'input, E>, usize>,
37473766
T::Offset: UnwindOffset<usize>,
37483767
{
37493768
if E::default().is_big_endian() {
@@ -3756,7 +3775,7 @@ mod tests {
37563775
fn section<'input, E>(self, contents: &'input [u8]) -> T
37573776
where
37583777
E: Endianity,
3759-
T: UnwindSection<EndianSlice<'input, E>> + ReadSection<EndianSlice<'input, E>>,
3778+
T: UnwindSection<EndianSlice<'input, E>, usize> + ReadSection<EndianSlice<'input, E>>,
37603779
T::Offset: UnwindOffset<usize>,
37613780
{
37623781
EndianSlice::new(contents, E::default()).into()
@@ -3805,7 +3824,7 @@ mod tests {
38053824
) -> Self
38063825
where
38073826
E: Endianity,
3808-
T: UnwindSection<EndianSlice<'input, E>>,
3827+
T: UnwindSection<EndianSlice<'input, E>, usize>,
38093828
T::Offset: UnwindOffset;
38103829
fn fde<'a, 'input, E, T, L>(
38113830
self,
@@ -3815,7 +3834,7 @@ mod tests {
38153834
) -> Self
38163835
where
38173836
E: Endianity,
3818-
T: UnwindSection<EndianSlice<'input, E>>,
3837+
T: UnwindSection<EndianSlice<'input, E>, usize>,
38193838
T::Offset: UnwindOffset,
38203839
L: ToLabelOrNum<'a, u64>;
38213840
}
@@ -3829,7 +3848,7 @@ mod tests {
38293848
) -> Self
38303849
where
38313850
E: Endianity,
3832-
T: UnwindSection<EndianSlice<'input, E>>,
3851+
T: UnwindSection<EndianSlice<'input, E>, usize>,
38333852
T::Offset: UnwindOffset,
38343853
{
38353854
cie.offset = self.size() as _;
@@ -3881,7 +3900,7 @@ mod tests {
38813900
) -> Self
38823901
where
38833902
E: Endianity,
3884-
T: UnwindSection<EndianSlice<'input, E>>,
3903+
T: UnwindSection<EndianSlice<'input, E>, usize>,
38853904
T::Offset: UnwindOffset,
38863905
L: ToLabelOrNum<'a, u64>,
38873906
{

src/read/dwarf.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ pub struct UnitRef<'a, R: Reader> {
14251425
pub dwarf: &'a Dwarf<R>,
14261426

14271427
/// The `Unit` being referenced.
1428-
pub unit: &'a Unit<R>,
1428+
pub unit: &'a Unit<R, R::Offset>,
14291429
}
14301430

14311431
impl<'a, R: Reader> Clone for UnitRef<'a, R> {
@@ -1610,12 +1610,12 @@ impl<'a, R: Reader> UnitRef<'a, R> {
16101610
///
16111611
/// Returned by `Dwarf::die_ranges` and `Dwarf::unit_ranges`.
16121612
#[derive(Debug)]
1613-
pub struct RangeIter<R: Reader>(RangeIterInner<R>);
1613+
pub struct RangeIter<R: Reader, Offset = <R as Reader>::Offset>(RangeIterInner<R, Offset>);
16141614

16151615
#[derive(Debug)]
1616-
enum RangeIterInner<R: Reader> {
1616+
enum RangeIterInner<R: Reader, Offset = <R as Reader>::Offset> {
16171617
Single(Option<Range>),
1618-
List(RngListIter<R>),
1618+
List(RngListIter<R, Offset>),
16191619
}
16201620

16211621
impl<R: Reader> Default for RangeIter<R> {

0 commit comments

Comments
 (0)