Add & use ObjSymbolFlagSet helper functions

This commit is contained in:
Luke Street 2023-08-03 19:00:10 -04:00
parent 26a3021f45
commit 8f461b8e0a
6 changed files with 41 additions and 20 deletions

View File

@ -31,6 +31,32 @@ flags! {
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct ObjSymbolFlagSet(pub FlagSet<ObjSymbolFlags>); pub struct ObjSymbolFlagSet(pub FlagSet<ObjSymbolFlags>);
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)] #[allow(clippy::derived_hash_with_manual_eq)]
impl Hash for ObjSymbolFlagSet { impl Hash for ObjSymbolFlagSet {
fn hash<H: Hasher>(&self, state: &mut H) { self.0.bits().hash(state) } fn hash<H: Hasher>(&self, state: &mut H) { self.0.bits().hash(state) }

View File

@ -637,7 +637,7 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
// If the symbol is local, we'll upgrade the scope to global // If the symbol is local, we'll upgrade the scope to global
// and rename it to avoid conflicts // 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 address_str = format!("{:08X}", target_sym.address);
let new_name = if target_sym.name.ends_with(&address_str) { let new_name = if target_sym.name.ends_with(&address_str) {
target_sym.name.clone() target_sym.name.clone()
@ -694,10 +694,9 @@ pub fn split_obj(obj: &ObjInfo) -> Result<Vec<ObjInfo>> {
if let Some(symbol_idx) = symbol_map[*globalize_idx] { if let Some(symbol_idx) = symbol_map[*globalize_idx] {
let mut symbol = obj.symbols.at(symbol_idx).clone(); let mut symbol = obj.symbols.at(symbol_idx).clone();
symbol.name = new_name.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); log::debug!("Globalizing {} in {}", symbol.name, obj.name);
symbol.flags.0 &= !ObjSymbolFlags::Local; symbol.flags.set_global();
symbol.flags.0 |= ObjSymbolFlags::Global;
} }
obj.symbols.replace(symbol_idx, symbol)?; obj.symbols.replace(symbol_idx, symbol)?;
} }

View File

@ -160,7 +160,7 @@ pub fn write_asm<W: Write>(w: &mut W, obj: &ObjInfo) -> Result<()> {
// Write common symbols // Write common symbols
let mut common_symbols = Vec::new(); 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); ensure!(symbol.section.is_none(), "Invalid: common symbol with section {:?}", symbol);
common_symbols.push(symbol); common_symbols.push(symbol);
} }
@ -353,9 +353,9 @@ fn write_symbol_entry<W: Write>(
ObjSymbolKind::Unknown => "sym", ObjSymbolKind::Unknown => "sym",
ObjSymbolKind::Section => bail!("Attempted to write section symbol: {symbol:?}"), 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" "weak"
} else if symbol.flags.0.contains(ObjSymbolFlags::Local) { } else if symbol.flags.is_local() {
"local" "local"
} else { } else {
// Default to global // Default to global
@ -392,7 +392,7 @@ fn write_symbol_entry<W: Write>(
} }
if matches!(entry.kind, SymbolEntryKind::Start | SymbolEntryKind::Label) if matches!(entry.kind, SymbolEntryKind::Start | SymbolEntryKind::Label)
&& symbol.flags.0.contains(ObjSymbolFlags::Hidden) && symbol.flags.is_hidden()
{ {
write!(w, ".hidden ")?; write!(w, ".hidden ")?;
write_symbol_name(w, &symbol.name)?; write_symbol_name(w, &symbol.name)?;

View File

@ -132,7 +132,7 @@ pub fn write_comment_sym<W: Write>(w: &mut W, symbol: &ObjSymbol) -> Result<()>
let align = match symbol.align { let align = match symbol.align {
Some(align) => align, Some(align) => align,
None => { None => {
if symbol.flags.0.contains(ObjSymbolFlags::Common) { if symbol.flags.is_common() {
symbol.address as u32 symbol.address as u32
} else { } else {
match symbol.kind { match symbol.kind {
@ -146,12 +146,12 @@ pub fn write_comment_sym<W: Write>(w: &mut W, symbol: &ObjSymbol) -> Result<()>
}; };
w.write_u32::<BigEndian>(align)?; w.write_u32::<BigEndian>(align)?;
let mut vis_flags = 0; let mut vis_flags = 0;
if symbol.flags.0.contains(ObjSymbolFlags::Weak) { if symbol.flags.is_weak() {
vis_flags |= 0xE; // TODO 0xD? vis_flags |= 0xE; // TODO 0xD?
} }
w.write_u8(vis_flags)?; w.write_u8(vis_flags)?;
let mut active_flags = 0; let mut active_flags = 0;
if symbol.flags.0.contains(ObjSymbolFlags::ForceActive) { if symbol.flags.is_force_active() {
active_flags |= 8; active_flags |= 8;
} }
w.write_u8(active_flags)?; w.write_u8(active_flags)?;

View File

@ -152,7 +152,7 @@ fn write_symbol<W: Write>(w: &mut W, obj: &ObjInfo, symbol: &ObjSymbol) -> Resul
if let Some(kind) = symbol_data_kind_to_str(symbol.data_kind) { if let Some(kind) = symbol_data_kind_to_str(symbol.data_kind) {
write!(w, " data:{kind}")?; write!(w, " data:{kind}")?;
} }
if symbol.flags.0.contains(ObjSymbolFlags::Hidden) { if symbol.flags.is_hidden() {
write!(w, " hidden")?; write!(w, " hidden")?;
} }
if obj.blocked_ranges.contains_key(&(symbol.address as u32)) { if obj.blocked_ranges.contains_key(&(symbol.address as u32)) {

View File

@ -462,7 +462,7 @@ pub fn write_elf(obj: &ObjInfo) -> Result<Vec<u8>> {
ObjSymbolKind::Unknown => elf::STT_NOTYPE, ObjSymbolKind::Unknown => elf::STT_NOTYPE,
ObjSymbolKind::Function => elf::STT_FUNC, ObjSymbolKind::Function => elf::STT_FUNC,
ObjSymbolKind::Object => { ObjSymbolKind::Object => {
if symbol.flags.0.contains(ObjSymbolFlags::Common) { if symbol.flags.is_common() {
elf::STT_COMMON elf::STT_COMMON
} else { } else {
elf::STT_OBJECT elf::STT_OBJECT
@ -470,20 +470,16 @@ pub fn write_elf(obj: &ObjInfo) -> Result<Vec<u8>> {
} }
ObjSymbolKind::Section => elf::STT_SECTION, 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 elf::STB_WEAK
} else if symbol.flags.0.contains(ObjSymbolFlags::Local) { } else if symbol.flags.is_local() {
elf::STB_LOCAL elf::STB_LOCAL
} else { } else {
elf::STB_GLOBAL elf::STB_GLOBAL
}; };
(st_bind << 4) + st_type (st_bind << 4) + st_type
}, },
st_other: if symbol.flags.0.contains(ObjSymbolFlags::Hidden) { st_other: if symbol.flags.is_hidden() { elf::STV_HIDDEN } else { elf::STV_DEFAULT },
elf::STV_HIDDEN
} else {
elf::STV_DEFAULT
},
st_shndx: if section_index.is_some() { st_shndx: if section_index.is_some() {
0 0
} else if symbol.address != 0 { } else if symbol.address != 0 {