Skip to content

Commit 89864dc

Browse files
authored
refactor: rename relocations field and flatten relocs (#115)
1 parent 9c52101 commit 89864dc

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/cmd/dol.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,10 @@ pub struct ExtractConfig {
317317
/// Path is relative to `out_dir/include`.
318318
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")]
319319
pub header: Option<Utf8UnixPathBuf>,
320+
/// If specified, any relocations within the symbol will be written to the given file in JSON
321+
/// format. Path is relative to `out_dir/bin`.
322+
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")]
323+
pub relocations: Option<Utf8UnixPathBuf>,
320324
/// The type for the extracted symbol in the header file. By default, the header will emit
321325
/// a full symbol declaration (a.k.a. `symbol`), but this can be set to `raw` to emit the raw
322326
/// data as a byte array. `none` avoids emitting a header entirely, in which case the `header`
@@ -403,11 +407,24 @@ pub struct OutputExtract {
403407
pub binary: Option<Utf8UnixPathBuf>,
404408
#[serde(with = "unix_path_serde_option")]
405409
pub header: Option<Utf8UnixPathBuf>,
410+
#[serde(with = "unix_path_serde_option")]
411+
pub relocations: Option<Utf8UnixPathBuf>,
406412
pub header_type: String,
407413
pub custom_type: Option<String>,
408414
pub custom_data: Option<serde_json::Value>,
409415
}
410416

417+
#[derive(Serialize)]
418+
struct ExtractRelocInfo {
419+
offset: u32,
420+
#[serde(rename = "type")]
421+
kind: ObjRelocKind,
422+
target: String,
423+
addend: i64,
424+
#[serde(skip_serializing_if = "Option::is_none")]
425+
module: Option<u32>,
426+
}
427+
411428
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, Hash)]
412429
pub struct OutputLink {
413430
pub modules: Vec<String>,
@@ -1063,12 +1080,35 @@ fn split_write_obj(
10631080
}
10641081
}
10651082

1083+
if let Some(relocations) = &extract.relocations {
1084+
let start = symbol.address as u32 - section.address as u32;
1085+
let end = start + symbol.size as u32;
1086+
let mut reloc_entries = Vec::new();
1087+
for (addr, reloc) in section.relocations.range(start..end) {
1088+
let target_symbol = &module.obj.symbols[reloc.target_symbol];
1089+
reloc_entries.push(ExtractRelocInfo {
1090+
offset: addr - start,
1091+
kind: reloc.kind,
1092+
target: target_symbol.name.clone(),
1093+
addend: reloc.addend,
1094+
module: reloc.module,
1095+
});
1096+
}
1097+
let relocations_json = serde_json::to_vec_pretty(&reloc_entries)?;
1098+
let out_path = base_dir.join("bin").join(relocations.with_encoding());
1099+
if let Some(parent) = out_path.parent() {
1100+
DirBuilder::new().recursive(true).create(parent)?;
1101+
}
1102+
write_if_changed(&out_path, &relocations_json)?;
1103+
}
1104+
10661105
// Copy to output config
10671106
out_config.extract.push(OutputExtract {
10681107
symbol: symbol.name.clone(),
10691108
rename: extract.rename.clone(),
10701109
binary: extract.binary.clone(),
10711110
header: extract.header.clone(),
1111+
relocations: extract.relocations.clone(),
10721112
header_type: header_kind.to_string(),
10731113
custom_type: extract.custom_type.clone(),
10741114
custom_data: extract.custom_data.clone(),

0 commit comments

Comments
 (0)