diff --git a/src/obj/mod.rs b/src/obj/mod.rs index 5f15aac..182de7a 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -31,6 +31,32 @@ flags! { #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] pub struct ObjSymbolFlagSet(pub FlagSet); +impl ObjSymbolFlagSet { + #[inline] + pub fn is_local(&self) -> bool { self.0.contains(ObjSymbolFlags::Local) } + + #[inline] + pub fn is_global(&self) -> bool { !self.is_local() } + + #[inline] + pub fn is_common(&self) -> bool { self.0.contains(ObjSymbolFlags::Common) } + + #[inline] + pub fn is_weak(&self) -> bool { self.0.contains(ObjSymbolFlags::Weak) } + + #[inline] + pub fn is_hidden(&self) -> bool { self.0.contains(ObjSymbolFlags::Hidden) } + + #[inline] + pub fn is_force_active(&self) -> bool { self.0.contains(ObjSymbolFlags::ForceActive) } + + #[inline] + pub fn set_global(&mut self) { + self.0 = + (self.0 & !(ObjSymbolFlags::Local | ObjSymbolFlags::Weak)) | ObjSymbolFlags::Global; + } +} + #[allow(clippy::derived_hash_with_manual_eq)] impl Hash for ObjSymbolFlagSet { fn hash(&self, state: &mut H) { self.0.bits().hash(state) } diff --git a/src/obj/split.rs b/src/obj/split.rs index 4c187c8..6ad0738 100644 --- a/src/obj/split.rs +++ b/src/obj/split.rs @@ -637,7 +637,7 @@ pub fn split_obj(obj: &ObjInfo) -> Result> { // If the symbol is local, we'll upgrade the scope to global // and rename it to avoid conflicts - if target_sym.flags.0.contains(ObjSymbolFlags::Local) { + if target_sym.flags.is_local() { let address_str = format!("{:08X}", target_sym.address); let new_name = if target_sym.name.ends_with(&address_str) { target_sym.name.clone() @@ -694,10 +694,9 @@ pub fn split_obj(obj: &ObjInfo) -> Result> { if let Some(symbol_idx) = symbol_map[*globalize_idx] { let mut symbol = obj.symbols.at(symbol_idx).clone(); symbol.name = new_name.clone(); - if symbol.flags.0.contains(ObjSymbolFlags::Local) { + if symbol.flags.is_local() { log::debug!("Globalizing {} in {}", symbol.name, obj.name); - symbol.flags.0 &= !ObjSymbolFlags::Local; - symbol.flags.0 |= ObjSymbolFlags::Global; + symbol.flags.set_global(); } obj.symbols.replace(symbol_idx, symbol)?; } diff --git a/src/util/asm.rs b/src/util/asm.rs index 2b6d18e..70ad0f8 100644 --- a/src/util/asm.rs +++ b/src/util/asm.rs @@ -160,7 +160,7 @@ pub fn write_asm(w: &mut W, obj: &ObjInfo) -> Result<()> { // Write common symbols let mut common_symbols = Vec::new(); - for symbol in symbols.iter().filter(|s| s.flags.0.contains(ObjSymbolFlags::Common)) { + for symbol in symbols.iter().filter(|s| s.flags.is_common()) { ensure!(symbol.section.is_none(), "Invalid: common symbol with section {:?}", symbol); common_symbols.push(symbol); } @@ -353,9 +353,9 @@ fn write_symbol_entry( ObjSymbolKind::Unknown => "sym", ObjSymbolKind::Section => bail!("Attempted to write section symbol: {symbol:?}"), }; - let scope = if symbol.flags.0.contains(ObjSymbolFlags::Weak) { + let scope = if symbol.flags.is_weak() { "weak" - } else if symbol.flags.0.contains(ObjSymbolFlags::Local) { + } else if symbol.flags.is_local() { "local" } else { // Default to global @@ -392,7 +392,7 @@ fn write_symbol_entry( } if matches!(entry.kind, SymbolEntryKind::Start | SymbolEntryKind::Label) - && symbol.flags.0.contains(ObjSymbolFlags::Hidden) + && symbol.flags.is_hidden() { write!(w, ".hidden ")?; write_symbol_name(w, &symbol.name)?; diff --git a/src/util/comment.rs b/src/util/comment.rs index ea681f5..404f0cf 100644 --- a/src/util/comment.rs +++ b/src/util/comment.rs @@ -132,7 +132,7 @@ pub fn write_comment_sym(w: &mut W, symbol: &ObjSymbol) -> Result<()> let align = match symbol.align { Some(align) => align, None => { - if symbol.flags.0.contains(ObjSymbolFlags::Common) { + if symbol.flags.is_common() { symbol.address as u32 } else { match symbol.kind { @@ -146,12 +146,12 @@ pub fn write_comment_sym(w: &mut W, symbol: &ObjSymbol) -> Result<()> }; w.write_u32::(align)?; let mut vis_flags = 0; - if symbol.flags.0.contains(ObjSymbolFlags::Weak) { + if symbol.flags.is_weak() { vis_flags |= 0xE; // TODO 0xD? } w.write_u8(vis_flags)?; let mut active_flags = 0; - if symbol.flags.0.contains(ObjSymbolFlags::ForceActive) { + if symbol.flags.is_force_active() { active_flags |= 8; } w.write_u8(active_flags)?; diff --git a/src/util/config.rs b/src/util/config.rs index f02d4e0..da806a0 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -152,7 +152,7 @@ fn write_symbol(w: &mut W, obj: &ObjInfo, symbol: &ObjSymbol) -> Resul if let Some(kind) = symbol_data_kind_to_str(symbol.data_kind) { write!(w, " data:{kind}")?; } - if symbol.flags.0.contains(ObjSymbolFlags::Hidden) { + if symbol.flags.is_hidden() { write!(w, " hidden")?; } if obj.blocked_ranges.contains_key(&(symbol.address as u32)) { diff --git a/src/util/elf.rs b/src/util/elf.rs index 64b06d6..b37d9d8 100644 --- a/src/util/elf.rs +++ b/src/util/elf.rs @@ -462,7 +462,7 @@ pub fn write_elf(obj: &ObjInfo) -> Result> { ObjSymbolKind::Unknown => elf::STT_NOTYPE, ObjSymbolKind::Function => elf::STT_FUNC, ObjSymbolKind::Object => { - if symbol.flags.0.contains(ObjSymbolFlags::Common) { + if symbol.flags.is_common() { elf::STT_COMMON } else { elf::STT_OBJECT @@ -470,20 +470,16 @@ pub fn write_elf(obj: &ObjInfo) -> Result> { } ObjSymbolKind::Section => elf::STT_SECTION, }; - let st_bind = if symbol.flags.0.contains(ObjSymbolFlags::Weak) { + let st_bind = if symbol.flags.is_weak() { elf::STB_WEAK - } else if symbol.flags.0.contains(ObjSymbolFlags::Local) { + } else if symbol.flags.is_local() { elf::STB_LOCAL } else { elf::STB_GLOBAL }; (st_bind << 4) + st_type }, - st_other: if symbol.flags.0.contains(ObjSymbolFlags::Hidden) { - elf::STV_HIDDEN - } else { - elf::STV_DEFAULT - }, + st_other: if symbol.flags.is_hidden() { elf::STV_HIDDEN } else { elf::STV_DEFAULT }, st_shndx: if section_index.is_some() { 0 } else if symbol.address != 0 {