Skip to content

Commit 9026469

Browse files
committed
refactor: rename relocations field and flatten relocs
1 parent d3596db commit 9026469

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
@@ -313,6 +313,10 @@ pub struct ExtractConfig {
313313
/// Path is relative to `out_dir/include`.
314314
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")]
315315
pub header: Option<Utf8UnixPathBuf>,
316+
/// If specified, any relocations within the symbol will be written to the given file in JSON
317+
/// format. Path is relative to `out_dir/bin`.
318+
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")]
319+
pub relocations: Option<Utf8UnixPathBuf>,
316320
/// The type for the extracted symbol in the header file. By default, the header will emit
317321
/// a full symbol declaration (a.k.a. `symbol`), but this can be set to `raw` to emit the raw
318322
/// data as a byte array. `none` avoids emitting a header entirely, in which case the `header`
@@ -399,11 +403,24 @@ pub struct OutputExtract {
399403
pub binary: Option<Utf8UnixPathBuf>,
400404
#[serde(with = "unix_path_serde_option")]
401405
pub header: Option<Utf8UnixPathBuf>,
406+
#[serde(with = "unix_path_serde_option")]
407+
pub relocations: Option<Utf8UnixPathBuf>,
402408
pub header_type: String,
403409
pub custom_type: Option<String>,
404410
pub custom_data: Option<serde_json::Value>,
405411
}
406412

413+
#[derive(Serialize)]
414+
struct ExtractRelocInfo {
415+
offset: u32,
416+
#[serde(rename = "type")]
417+
kind: ObjRelocKind,
418+
target: String,
419+
addend: i64,
420+
#[serde(skip_serializing_if = "Option::is_none")]
421+
module: Option<u32>,
422+
}
423+
407424
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, Hash)]
408425
pub struct OutputLink {
409426
pub modules: Vec<String>,
@@ -1059,12 +1076,35 @@ fn split_write_obj(
10591076
}
10601077
}
10611078

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

0 commit comments

Comments
 (0)