use std::{
collections::{hash_map, HashMap},
io::Cursor,
num::NonZeroU64,
path::Path,
};
use anyhow::{anyhow, bail, ensure, Context, Result};
use cwdemangle::demangle;
use flagset::Flags;
use indexmap::IndexMap;
use objdiff_core::obj::split_meta::{SplitMeta, SHT_SPLITMETA, SPLITMETA_SECTION};
use object::{
elf,
elf::{SHF_ALLOC, SHF_EXECINSTR, SHF_WRITE, SHT_NOBITS, SHT_PROGBITS},
write::{
elf::{ProgramHeader, Rel, SectionHeader, SectionIndex, SymbolIndex, Writer},
StringId,
},
Architecture, Endianness, Object, ObjectKind, ObjectSection, ObjectSymbol, Relocation,
RelocationFlags, RelocationTarget, SectionKind, Symbol, SymbolKind, SymbolScope, SymbolSection,
};
use crate::{
array_ref,
obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind,
ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjUnit,
},
util::{
comment::{CommentSym, MWComment},
file::map_file,
reader::{Endian, FromReader, ToWriter},
},
};
enum BoundaryState {
/// Looking for a file symbol, any section symbols are queued
LookForFile(Vec<(u64, String)>),
/// Looking for section symbols
LookForSections(String),
/// Done with files and sections
FilesEnded,
}
pub fn process_elf
(path: P) -> Result
where P: AsRef {
let file = map_file(path)?;
let obj_file = object::read::File::parse(file.as_slice())?;
let architecture = match obj_file.architecture() {
Architecture::PowerPc => ObjArchitecture::PowerPc,
arch => bail!("Unexpected architecture: {arch:?}"),
};
ensure!(obj_file.endianness() == Endianness::Big, "Expected big endian");
let kind = match obj_file.kind() {
ObjectKind::Executable => ObjKind::Executable,
ObjectKind::Relocatable => ObjKind::Relocatable,
kind => bail!("Unexpected ELF type: {kind:?}"),
};
let mut obj_name = String::new();
let mut stack_address: Option = None;
let mut stack_end: Option = None;
let mut db_stack_addr: Option = None;
let mut arena_lo: Option = None;
let mut arena_hi: Option = None;
let mut sda_base: Option = None;
let mut sda2_base: Option = None;
let mut sections: Vec = vec![];
let mut section_indexes: Vec