Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/cmd/dol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ pub struct ProjectConfig {
/// Marks all emitted symbols as "exported" to prevent the linker from removing them.
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
pub export_all: bool,
/// Promotes local symbols referenced by other units to global.
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
pub globalize_symbols: bool,
/// Optional base path for all object files.
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "is_default")]
pub object_base: Option<Utf8UnixPathBuf>,
Expand All @@ -259,6 +262,7 @@ impl Default for ProjectConfig {
symbols_known: false,
fill_gaps: true,
export_all: true,
globalize_symbols: true,
object_base: None,
extract_objects: true,
}
Expand Down Expand Up @@ -967,7 +971,7 @@ fn split_write_obj(

debug!("Splitting {} objects", module.obj.link_order.len());
let module_name = module.config.name().to_string();
let split_objs = split_obj(&module.obj, Some(module_name.as_str()))?;
let split_objs = split_obj(&module.obj, Some(module_name.as_str()), config.globalize_symbols)?;

debug!("Writing object files");
DirBuilder::new()
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn disasm(args: DisasmArgs) -> Result<()> {
match obj.kind {
ObjKind::Executable => {
log::info!("Splitting {} objects", obj.link_order.len());
let split_objs = split_obj(&obj, None)?;
let split_objs = split_obj(&obj, None, false)?;

let asm_dir = args.out.join("asm");
let include_dir = args.out.join("include");
Expand Down
32 changes: 19 additions & 13 deletions src/util/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,11 @@ fn resolve_link_order(obj: &ObjInfo) -> Result<Vec<ObjUnit>> {

/// Split an object into multiple relocatable objects.
#[instrument(level = "debug", skip(obj))]
pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo>> {
pub fn split_obj(
obj: &ObjInfo,
module_name: Option<&str>,
globalize_symbols: bool,
) -> Result<Vec<ObjInfo>> {
let mut objects: Vec<ObjInfo> = vec![];
let mut object_symbols: Vec<Vec<Option<SymbolIndex>>> = vec![];
let mut name_to_obj: HashMap<String, usize> = HashMap::new();
Expand Down Expand Up @@ -1215,7 +1219,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
}

// Update relocations
let mut globalize_symbols = vec![];
let mut symbols_to_globalize = vec![];
for (obj_idx, out_obj) in objects.iter_mut().enumerate() {
let symbol_idxs = &mut object_symbols[obj_idx];
for (_section_index, section) in out_obj.sections.iter_mut() {
Expand All @@ -1231,7 +1235,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo

// If the symbol is local, we'll upgrade the scope to global
// and rename it to avoid conflicts
if target_sym.flags.is_local() {
if globalize_symbols && target_sym.flags.is_local() {
let address_str = if obj.module_id == 0 {
format!("{:08X}", target_sym.address)
} else if let Some(section_index) = target_sym.section {
Expand All @@ -1250,7 +1254,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
} else {
format!("{}_{}", target_sym.name, address_str)
};
globalize_symbols.push((reloc.target_symbol, new_name));
symbols_to_globalize.push((reloc.target_symbol, new_name));
}

symbol_idxs[reloc.target_symbol as usize] = Some(out_sym_idx);
Expand Down Expand Up @@ -1295,16 +1299,18 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
}

// Upgrade local symbols to global if necessary
for (obj, symbol_map) in objects.iter_mut().zip(&object_symbols) {
for (globalize_idx, new_name) in &globalize_symbols {
if let Some(symbol_idx) = symbol_map[*globalize_idx as usize] {
let mut symbol = obj.symbols[symbol_idx].clone();
symbol.name.clone_from(new_name);
if symbol.flags.is_local() {
log::debug!("Globalizing {} in {}", symbol.name, obj.name);
symbol.flags.set_scope(ObjSymbolScope::Global);
if globalize_symbols {
for (obj, symbol_map) in objects.iter_mut().zip(&object_symbols) {
for (globalize_idx, new_name) in &symbols_to_globalize {
if let Some(symbol_idx) = symbol_map[*globalize_idx as usize] {
let mut symbol = obj.symbols[symbol_idx].clone();
symbol.name.clone_from(new_name);
if symbol.flags.is_local() {
log::debug!("Globalizing {} in {}", symbol.name, obj.name);
symbol.flags.set_scope(ObjSymbolScope::Global);
}
obj.symbols.replace(symbol_idx, symbol)?;
}
obj.symbols.replace(symbol_idx, symbol)?;
}
}
}
Expand Down
Loading