Add `rename` field to extract configuration

Allows renaming, for example, local statics from `test$1234`
to `test` for inclusion in the source function.
This commit is contained in:
Luke Street 2024-11-07 08:44:24 -07:00
parent 1cc38ad621
commit 9fc56d847f
2 changed files with 25 additions and 5 deletions

View File

@ -296,6 +296,8 @@ pub struct ModuleConfig {
pub struct ExtractConfig { pub struct ExtractConfig {
/// The name of the symbol to extract. /// The name of the symbol to extract.
pub symbol: String, pub symbol: String,
/// Optionally rename the output symbol. (e.g. symbol$1234 -> symbol)
pub rename: Option<String>,
/// If specified, the symbol's data will be extracted to the given file. /// If specified, the symbol's data will be extracted to the given file.
/// Path is relative to `out_dir/bin`. /// Path is relative to `out_dir/bin`.
#[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")] #[serde(with = "unix_path_serde_option", default, skip_serializing_if = "Option::is_none")]
@ -385,6 +387,7 @@ pub struct OutputModule {
#[derive(Serialize, Deserialize, Debug, Clone, Default)] #[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct OutputExtract { pub struct OutputExtract {
pub symbol: String, pub symbol: String,
pub rename: Option<String>,
#[serde(with = "unix_path_serde_option")] #[serde(with = "unix_path_serde_option")]
pub binary: Option<Utf8UnixPathBuf>, pub binary: Option<Utf8UnixPathBuf>,
#[serde(with = "unix_path_serde_option")] #[serde(with = "unix_path_serde_option")]
@ -1014,7 +1017,8 @@ fn split_write_obj(
if header_kind != HeaderKind::None { if header_kind != HeaderKind::None {
if let Some(header) = &extract.header { if let Some(header) = &extract.header {
let header_string = bin2c(symbol, section, data, header_kind); let header_string =
bin2c(symbol, section, data, header_kind, extract.rename.as_deref());
let out_path = base_dir.join("include").join(header.with_encoding()); let out_path = base_dir.join("include").join(header.with_encoding());
if let Some(parent) = out_path.parent() { if let Some(parent) = out_path.parent() {
DirBuilder::new().recursive(true).create(parent)?; DirBuilder::new().recursive(true).create(parent)?;
@ -1026,6 +1030,7 @@ fn split_write_obj(
// Copy to output config // Copy to output config
out_config.extract.push(OutputExtract { out_config.extract.push(OutputExtract {
symbol: symbol.name.clone(), symbol: symbol.name.clone(),
rename: extract.rename.clone(),
binary: extract.binary.clone(), binary: extract.binary.clone(),
header: extract.header.clone(), header: extract.header.clone(),
header_type: header_kind.to_string(), header_type: header_kind.to_string(),

View File

@ -50,15 +50,26 @@ impl fmt::Display for HeaderKind {
} }
/// Converts a binary blob into a C array. /// Converts a binary blob into a C array.
pub fn bin2c(symbol: &ObjSymbol, section: &ObjSection, data: &[u8], kind: HeaderKind) -> String { pub fn bin2c(
symbol: &ObjSymbol,
section: &ObjSection,
data: &[u8],
kind: HeaderKind,
rename: Option<&str>,
) -> String {
match kind { match kind {
HeaderKind::None => String::new(), HeaderKind::None => String::new(),
HeaderKind::Symbol => bin2c_symbol(symbol, section, data), HeaderKind::Symbol => bin2c_symbol(symbol, section, data, rename),
HeaderKind::Raw => bin2c_raw(data), HeaderKind::Raw => bin2c_raw(data),
} }
} }
fn bin2c_symbol(symbol: &ObjSymbol, section: &ObjSection, data: &[u8]) -> String { fn bin2c_symbol(
symbol: &ObjSymbol,
section: &ObjSection,
data: &[u8],
rename: Option<&str>,
) -> String {
let mut output = String::new(); let mut output = String::new();
output.push_str(PROLOGUE); output.push_str(PROLOGUE);
output.push_str(&format!( output.push_str(&format!(
@ -72,7 +83,11 @@ fn bin2c_symbol(symbol: &ObjSymbol, section: &ObjSection, data: &[u8]) -> String
output.push_str("const "); output.push_str("const ");
} }
output.push_str("unsigned char "); output.push_str("unsigned char ");
if let Some(rename) = rename {
output.push_str(rename);
} else {
output.push_str(symbol.demangled_name.as_deref().unwrap_or(symbol.name.as_str())); output.push_str(symbol.demangled_name.as_deref().unwrap_or(symbol.name.as_str()));
}
output.push_str(&format!("[] ATTRIBUTE_ALIGN({}) = {{", symbol.align.unwrap_or(4))); output.push_str(&format!("[] ATTRIBUTE_ALIGN({}) = {{", symbol.align.unwrap_or(4)));
for (i, byte) in data.iter().enumerate() { for (i, byte) in data.iter().enumerate() {
if i % 16 == 0 { if i % 16 == 0 {