Skip to content

Commit

Permalink
More rust cleanup
Browse files Browse the repository at this point in the history
- Fixup usage of QualifiedName in plugins
- Make QualifiedName more usable
  • Loading branch information
emesare committed Jan 5, 2025
1 parent e3d59cc commit 8c098d2
Show file tree
Hide file tree
Showing 15 changed files with 307 additions and 215 deletions.
6 changes: 3 additions & 3 deletions plugins/dwarf/dwarf_export/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fn export_type(
AttributeValue::Data2(t.width() as u16),
);

for struct_member in t.get_structure().unwrap().members().unwrap() {
for struct_member in t.get_structure().unwrap().members() {
let struct_member_die_uid =
dwarf.unit.add(structure_die_uid, constants::DW_TAG_member);
dwarf.unit.get_mut(struct_member_die_uid).set(
Expand Down Expand Up @@ -378,8 +378,8 @@ fn export_types(
) {
for t in &bv.types() {
export_type(
t.name().to_string(),
&t.type_object(),
t.name.to_string(),
&t.ty,
bv,
defined_types,
dwarf,
Expand Down
15 changes: 8 additions & 7 deletions plugins/dwarf/dwarf_import/src/die_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub(crate) fn handle_enum<R: ReaderType>(
pub(crate) fn handle_typedef(
debug_info_builder: &mut DebugInfoBuilder,
entry_type: Option<TypeUID>,
typedef_name: &String,
typedef_name: &str,
) -> (Option<Ref<Type>>, bool) {
// All base types have:
// DW_AT_name
Expand All @@ -152,7 +152,7 @@ pub(crate) fn handle_typedef(
// This will fail in the case where we have a typedef to a type that doesn't exist (failed to parse, incomplete, etc)
if let Some(entry_type_offset) = entry_type {
if let Some(t) = debug_info_builder.get_type(entry_type_offset) {
return (Some(t.get_type()), typedef_name != t.get_name());
return (Some(t.get_type()), typedef_name != t.name);
}
}

Expand Down Expand Up @@ -304,13 +304,14 @@ pub(crate) fn handle_function<R: ReaderType>(

// Alias function type in the case that it contains itself
if let Some(name) = debug_info_builder_context.get_name(dwarf, unit, entry) {
let ntr = Type::named_type_from_type(
&name,
&Type::function(return_type.as_ref(), &[], false),
);
debug_info_builder.add_type(
get_uid(dwarf, unit, entry),
&name,
Type::named_type_from_type(
&name,
&Type::function::<&binaryninja::types::Type>(return_type.as_ref(), &[], false),
),
name,
ntr,
false,
);
}
Expand Down
26 changes: 11 additions & 15 deletions plugins/dwarf/dwarf_import/src/dwarfdebuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,12 @@ impl FunctionInfoBuilder {

// TODO : Don't make this pub...fix the value thing
pub(crate) struct DebugType {
name: String,
ty: Ref<Type>,
commit: bool,
pub name: String,
pub ty: Ref<Type>,
pub commit: bool,
}

impl DebugType {
pub fn get_name(&self) -> &String {
&self.name
}

pub fn get_type(&self) -> Ref<Type> {
self.ty.clone()
}
Expand Down Expand Up @@ -327,7 +323,7 @@ impl DebugInfoBuilder {
self.types.values()
}

pub(crate) fn add_type(&mut self, type_uid: TypeUID, name: &String, t: Ref<Type>, commit: bool) {
pub(crate) fn add_type(&mut self, type_uid: TypeUID, name: String, t: Ref<Type>, commit: bool) {
if let Some(DebugType {
name: existing_name,
ty: existing_type,
Expand Down Expand Up @@ -396,7 +392,7 @@ impl DebugInfoBuilder {

// Either get the known type or use a 0 confidence void type so we at least get the name applied
let ty = match type_uid {
Some(uid) => Conf::new(self.get_type(uid).unwrap().get_type(), 128),
Some(uid) => Conf::new(self.get_type(uid).unwrap().ty.clone(), 128),
None => Conf::new(Type::void(), 0)
};
let function = &mut self.functions[function_index];
Expand Down Expand Up @@ -465,8 +461,8 @@ impl DebugInfoBuilder {
if let Some((_existing_name, existing_type_uid)) =
self.data_variables.insert(address, (name, type_uid))
{
let existing_type = self.get_type(existing_type_uid).unwrap().get_type();
let new_type = self.get_type(type_uid).unwrap().get_type();
let existing_type = self.get_type(existing_type_uid).unwrap().ty.as_ref();
let new_type = self.get_type(type_uid).unwrap().ty.as_ref();

if existing_type_uid != type_uid || existing_type != new_type {
warn!("DWARF info contains duplicate data variable definition. Overwriting data variable at 0x{:08x} (`{}`) with `{}`",
Expand Down Expand Up @@ -549,7 +545,7 @@ impl DebugInfoBuilder {

fn get_function_type(&self, function: &FunctionInfoBuilder) -> Ref<Type> {
let return_type = match function.return_type {
Some(return_type_id) => Conf::new(self.get_type(return_type_id).unwrap().get_type(), 128),
Some(return_type_id) => Conf::new(self.get_type(return_type_id).unwrap().ty.clone(), 128),
_ => Conf::new(Type::void(), 0),
};

Expand All @@ -559,7 +555,7 @@ impl DebugInfoBuilder {
.filter_map(|parameter| match parameter {
Some((name, 0)) => Some(FunctionParameter::new(Type::void(), name.clone(), None)),
Some((name, uid)) => Some(FunctionParameter::new(
self.get_type(*uid).unwrap().get_type(),
self.get_type(*uid).unwrap().ty.clone(),
name.clone(),
None,
)),
Expand Down Expand Up @@ -610,8 +606,8 @@ impl DebugInfoBuilder {
let symbol_full_name = symbol.full_name();

// If our name has fewer namespaces than the existing name, assume we lost the namespace info
if simplify_str_to_fqn(func_full_name, true).len()
< simplify_str_to_fqn(symbol_full_name.clone(), true).len()
if simplify_str_to_fqn(func_full_name, true).items.len()
< simplify_str_to_fqn(symbol_full_name.clone(), true).items.len()
{
func.full_name = Some(symbol_full_name.to_string());
}
Expand Down
6 changes: 3 additions & 3 deletions plugins/dwarf/dwarf_import/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ pub(crate) fn get_build_id(view: &BinaryView) -> Result<String, String> {
}


pub(crate) fn download_debug_info(build_id: &String, view: &BinaryView) -> Result<Ref<BinaryView>, String> {
pub(crate) fn download_debug_info(build_id: &str, view: &BinaryView) -> Result<Ref<BinaryView>, String> {
let settings = Settings::new("");

let debug_server_urls = settings.get_string_list("network.debuginfodServers", Some(view), None);
Expand Down Expand Up @@ -479,7 +479,7 @@ pub(crate) fn download_debug_info(build_id: &String, view: &BinaryView) -> Resul
}


pub(crate) fn find_local_debug_file_for_build_id(build_id: &String, view: &BinaryView) -> Option<String> {
pub(crate) fn find_local_debug_file_for_build_id(build_id: &str, view: &BinaryView) -> Option<String> {
let settings = Settings::new("");
let debug_dirs_enabled = settings.get_bool("analysis.debugInfo.enableDebugDirectories", Some(view), None);

Expand Down Expand Up @@ -522,7 +522,7 @@ pub(crate) fn find_local_debug_file_for_build_id(build_id: &String, view: &Binar
}


pub(crate) fn load_debug_info_for_build_id(build_id: &String, view: &BinaryView) -> (Option<Ref<BinaryView>>, bool) {
pub(crate) fn load_debug_info_for_build_id(build_id: &str, view: &BinaryView) -> (Option<Ref<BinaryView>>, bool) {
if let Some(debug_file_path) = find_local_debug_file_for_build_id(build_id, view) {
return
(
Expand Down
27 changes: 16 additions & 11 deletions plugins/dwarf/dwarf_import/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,29 @@ fn do_structure_parse<R: ReaderType>(
// This reference type will be used by any children to grab while we're still building this type
// it will also be how any other types refer to this struct
if let Some(full_name) = &full_name {
let ntr = Type::named_type_from_type(
full_name,
&Type::structure(&structure_builder.finalize()),
);
debug_info_builder.add_type(
get_uid(dwarf, unit, entry),
&full_name,
Type::named_type_from_type(
full_name.clone(),
&Type::structure(&structure_builder.finalize()),
),
full_name.to_owned(),
ntr,
false,
);
} else {
// We _need_ to have initial typedefs or else we can enter infinite parsing loops
// These get overwritten in the last step with the actual type, however, so this
// is either perfectly fine or breaking a bunch of NTRs
let full_name = format!("anonymous_structure_{:x}", get_uid(dwarf, unit, entry));
let ntr = Type::named_type_from_type(
&full_name,
&Type::structure(&structure_builder.finalize()),
);
debug_info_builder.add_type(
get_uid(dwarf, unit, entry),
&full_name,
Type::named_type_from_type(&full_name, &Type::structure(&structure_builder.finalize())),
full_name,
ntr,
false,
);
}
Expand Down Expand Up @@ -224,14 +229,14 @@ fn do_structure_parse<R: ReaderType>(
if let Some(full_name) = full_name {
debug_info_builder.add_type(
get_uid(dwarf, unit, entry) + 1, // TODO : This is super broke (uid + 1 is not guaranteed to be unique)
&full_name,
full_name,
finalized_structure,
true,
);
} else {
debug_info_builder.add_type(
get_uid(dwarf, unit, entry),
&format!("{}", finalized_structure),
finalized_structure.to_string(),
finalized_structure,
false, // Don't commit anonymous unions (because I think it'll break things)
);
Expand Down Expand Up @@ -451,10 +456,10 @@ pub(crate) fn get_type<R: ReaderType>(
}
.unwrap_or_else(|| {
commit = false;
format!("{}", type_def)
type_def.to_string()
});

debug_info_builder.add_type(entry_uid, &name, type_def, commit);
debug_info_builder.add_type(entry_uid, name, type_def, commit);
Some(entry_uid)
} else {
None
Expand Down
4 changes: 2 additions & 2 deletions plugins/idb_import/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,15 @@ impl<F: Fn(usize, usize) -> Result<(), ()>> TranslateIDBTypes<'_, F> {
}
TranslateTypeResult::PartiallyTranslated(og_ty, error) => {
TranslateTypeResult::PartiallyTranslated(
Type::named_type_from_type(&String::from_utf8_lossy(&ty.name), og_ty),
Type::named_type_from_type(String::from_utf8_lossy(&ty.name), og_ty),
error
.as_ref()
.map(|x| BnTypeError::Typedef(Box::new(x.clone())))
.clone(),
)
}
TranslateTypeResult::Translated(og_ty) => TranslateTypeResult::Translated(
Type::named_type_from_type(&String::from_utf8_lossy(&ty.name), og_ty),
Type::named_type_from_type(String::from_utf8_lossy(&ty.name), og_ty),
),
}
}
Expand Down
35 changes: 14 additions & 21 deletions plugins/pdb-ng/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ use binaryninja::debuginfo::{DebugFunctionInfo, DebugInfo};
use binaryninja::platform::Platform;
use binaryninja::rc::Ref;
use binaryninja::settings::Settings;
use binaryninja::types::{
EnumerationBuilder, NamedTypeReference,
NamedTypeReferenceClass, StructureBuilder, StructureType, Type, TypeClass,
};
use binaryninja::types::{EnumerationBuilder, NamedTypeReference, NamedTypeReferenceClass, QualifiedName, StructureBuilder, StructureType, Type, TypeClass};
use binaryninja::variable::NamedDataVariableWithType;
use crate::symbol_parser::{ParsedDataSymbol, ParsedProcedure, ParsedSymbol};
use crate::type_parser::ParsedType;
Expand Down Expand Up @@ -67,13 +64,13 @@ pub struct PDBParserInstance<'a, S: Source<'a> + 'a> {
/// TypeIndex -> ParsedType enum used during parsing
pub(crate) indexed_types: BTreeMap<TypeIndex, ParsedType>,
/// QName -> Binja Type for finished types
pub(crate) named_types: BTreeMap<String, Ref<Type>>,
pub(crate) named_types: BTreeMap<QualifiedName, Ref<Type>>,
/// Raw (mangled) name -> TypeIndex for resolving forward references
pub(crate) full_type_indices: BTreeMap<String, TypeIndex>,
/// Stack of types we're currently parsing
pub(crate) type_stack: Vec<TypeIndex>,
/// Stack of parent types we're parsing nested types inside of
pub(crate) namespace_stack: Vec<String>,
pub(crate) namespace_stack: QualifiedName,
/// Type Index -> Does it return on the stack
pub(crate) type_default_returnable: BTreeMap<TypeIndex, bool>,

Expand Down Expand Up @@ -287,9 +284,9 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
fn collect_name(
&self,
name: &NamedTypeReference,
unknown_names: &mut HashMap<String, NamedTypeReferenceClass>,
unknown_names: &mut HashMap<QualifiedName, NamedTypeReferenceClass>,
) {
let used_name = name.name().to_string();
let used_name = name.name();
if let Some(&found) =
unknown_names.get(&used_name)
{
Expand All @@ -312,20 +309,16 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
fn collect_names(
&self,
ty: &Type,
unknown_names: &mut HashMap<String, NamedTypeReferenceClass>,
unknown_names: &mut HashMap<QualifiedName, NamedTypeReferenceClass>,
) {
match ty.type_class() {
TypeClass::StructureTypeClass => {
if let Some(structure) = ty.get_structure() {
if let Some(members) = structure.members() {
for member in members {
self.collect_names(member.ty.contents.as_ref(), unknown_names);
}
for member in structure.members() {
self.collect_names(member.ty.contents.as_ref(), unknown_names);
}
if let Some(bases) = structure.base_structures() {
for base in bases {
self.collect_name(base.ty.as_ref(), unknown_names);
}
for base in structure.base_structures() {
self.collect_name(base.ty.as_ref(), unknown_names);
}
}
}
Expand Down Expand Up @@ -368,7 +361,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
.bv
.types()
.iter()
.map(|qnat| qnat.name().string())
.map(|qnat| qnat.name)
.collect::<HashSet<_>>();

for ty in &self.named_types {
Expand Down Expand Up @@ -409,7 +402,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
match class {
NamedTypeReferenceClass::UnknownNamedTypeClass
| NamedTypeReferenceClass::TypedefNamedTypeClass => {
self.debug_info.add_type(name, Type::void().as_ref(), &[]); // TODO : Components
self.debug_info.add_type(&name, Type::void().as_ref(), &[]); // TODO : Components
}
NamedTypeReferenceClass::ClassNamedTypeClass
| NamedTypeReferenceClass::StructNamedTypeClass
Expand All @@ -431,15 +424,15 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
structure.set_alignment(1);

self.debug_info.add_type(
name,
&name,
Type::structure(structure.finalize().as_ref()).as_ref(),
&[], // TODO : Components
);
}
NamedTypeReferenceClass::EnumNamedTypeClass => {
let enumeration = EnumerationBuilder::new();
self.debug_info.add_type(
name,
&name,
Type::enumeration(
enumeration.finalize().as_ref(),
self.arch.default_integer_size().try_into()?,
Expand Down
Loading

0 comments on commit 8c098d2

Please sign in to comment.