Skip to content

Commit 367deae

Browse files
authored
Big dwarf dump improvements (#129)
* Support type definitions inside functions in dwarf dump Detect subroutine parent class and constness Support nested typedefs * Omit unnecessary/duplicate dwarf info * Move total size to before struct so that clangd picks it up * Subroutine typedefs and subroutine block inner types * Handle override, const, volatile, virtual, static function logic * Omit return type of ctors and dtors * Add back the nested template thing because it's actually useful * Return type omitting bug fix * Add static struct members * Fix formatting * Handle typedef specification attribute * Avoid adding duplicate inline params * Handle non-overriden GCC constructors and destructors * clippy * Cargo fmt * Apply clippy's suggestion * Extract producer and correctly handle MWCC static members * Enable static member function detection only for GCC * Fix bug where function parameter wasn't applied if both names were None * Fix gcc boolean logic and omit __in_chrg * Add parent fallback for PS2 MW * Demangle mangled function names * Have inlines and blocks in the same vec to keep their correct order * Change comment * List member functions inside struct * Remove Inline comment and add a new line before blocks * Fix fmt and check * Support appending static member functions to struct on GCC * Reverse enum members in GCC
1 parent d766ff5 commit 367deae

File tree

4 files changed

+958
-139
lines changed

4 files changed

+958
-139
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ filetime = "0.2"
4444
fixedbitset = "0.5"
4545
flagset = { version = "0.4", features = ["serde"] }
4646
glob = "0.3"
47+
gnuv2_demangle = "0.4"
4748
hex = "0.4"
4849
indent = "0.1"
4950
indexmap = "2.6"

src/cmd/dwarf.rs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{
2-
collections::{btree_map, BTreeMap},
2+
cell::RefCell,
3+
collections::btree_map,
34
io::{stdout, Cursor, Read, Write},
45
ops::Bound::{Excluded, Unbounded},
56
str::from_utf8,
@@ -19,8 +20,9 @@ use typed_path::Utf8NativePathBuf;
1920
use crate::{
2021
util::{
2122
dwarf::{
22-
process_compile_unit, process_cu_tag, process_overlay_branch, read_debug_section,
23-
should_skip_tag, tag_type_string, AttributeKind, TagKind,
23+
parse_producer, preprocess_cu_tag, process_compile_unit, process_cu_tag,
24+
process_overlay_branch, read_debug_section, should_skip_tag, tag_type_string,
25+
AttributeKind, MemberFunctionMap, TagKind, TypedefMap,
2426
},
2527
file::buf_writer,
2628
path::native_path,
@@ -166,7 +168,8 @@ where
166168
}
167169

168170
let mut reader = Cursor::new(&*data);
169-
let info = read_debug_section(&mut reader, obj_file.endianness().into(), args.include_erased)?;
171+
let mut info =
172+
read_debug_section(&mut reader, obj_file.endianness().into(), args.include_erased)?;
170173

171174
for (&addr, tag) in &info.tags {
172175
log::debug!("{}: {:?}", addr, tag);
@@ -210,6 +213,7 @@ where
210213
writeln!(w, "\n/*\n Compile unit: {}", unit.name)?;
211214
if let Some(producer) = unit.producer {
212215
writeln!(w, " Producer: {producer}")?;
216+
info.producer = parse_producer(&producer);
213217
}
214218
if let Some(comp_dir) = unit.comp_dir {
215219
writeln!(w, " Compile directory: {comp_dir}")?;
@@ -245,8 +249,29 @@ where
245249
}
246250
children.sort_by_key(|x| x.key);
247251

248-
let mut typedefs = BTreeMap::<u32, Vec<u32>>::new();
249-
for child in children {
252+
let mut typedefs = TypedefMap::new();
253+
info.member_functions = RefCell::new(MemberFunctionMap::new());
254+
// pre-parse step
255+
for &child in &children {
256+
preprocess_cu_tag(&info, child);
257+
258+
if let TagKind::Typedef = child.kind {
259+
// TODO fundamental typedefs?
260+
if let Some(ud_type_ref) =
261+
child.reference_attribute(AttributeKind::UserDefType)
262+
{
263+
match typedefs.entry(ud_type_ref) {
264+
btree_map::Entry::Vacant(e) => {
265+
e.insert(vec![child.key]);
266+
}
267+
btree_map::Entry::Occupied(e) => {
268+
e.into_mut().push(child.key);
269+
}
270+
}
271+
}
272+
}
273+
}
274+
for &child in &children {
250275
let tag_type = match process_cu_tag(&info, child) {
251276
Ok(tag_type) => tag_type,
252277
Err(e) => {
@@ -284,22 +309,6 @@ where
284309
continue;
285310
}
286311
}
287-
288-
if let TagKind::Typedef = child.kind {
289-
// TODO fundamental typedefs?
290-
if let Some(ud_type_ref) =
291-
child.reference_attribute(AttributeKind::UserDefType)
292-
{
293-
match typedefs.entry(ud_type_ref) {
294-
btree_map::Entry::Vacant(e) => {
295-
e.insert(vec![child.key]);
296-
}
297-
btree_map::Entry::Occupied(e) => {
298-
e.into_mut().push(child.key);
299-
}
300-
}
301-
}
302-
}
303312
}
304313
}
305314
kind => bail!("Unhandled root tag type {:?}", kind),

0 commit comments

Comments
 (0)