Guess section alignment & write __ArenaHi in .lcf
This commit is contained in:
parent
98ab89a1de
commit
265e26ee40
|
@ -1,6 +1,6 @@
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
text : origin = 0x80003100
|
text : origin = $ORIGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
|
@ -16,7 +16,7 @@ SECTIONS
|
||||||
_db_stack_addr = (_stack_addr + 0x2000);
|
_db_stack_addr = (_stack_addr + 0x2000);
|
||||||
_db_stack_end = _stack_addr;
|
_db_stack_end = _stack_addr;
|
||||||
__ArenaLo = (_db_stack_addr + 0x1f) & ~0x1f;
|
__ArenaLo = (_db_stack_addr + 0x1f) & ~0x1f;
|
||||||
__ArenaHi = 0x81700000;
|
__ArenaHi = $ARENAHI;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEFILES
|
FORCEFILES
|
||||||
|
|
|
@ -1,20 +1,46 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Result};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::obj::ObjInfo;
|
use crate::obj::ObjInfo;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn align_up(value: u32, align: u32) -> u32 { (value + (align - 1)) & !(align - 1) }
|
||||||
|
|
||||||
pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result<String> {
|
pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result<String> {
|
||||||
|
let origin = obj.sections.iter().map(|s| s.address).min().unwrap();
|
||||||
let stack_size = match (obj.stack_address, obj.stack_end) {
|
let stack_size = match (obj.stack_address, obj.stack_end) {
|
||||||
(Some(stack_address), Some(stack_end)) => stack_address - stack_end,
|
(Some(stack_address), Some(stack_end)) => stack_address - stack_end,
|
||||||
_ => 65535, // default
|
_ => 65535, // default
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Guess section alignment
|
||||||
|
let mut alignments = Vec::with_capacity(obj.sections.len());
|
||||||
|
let mut last_section_end = origin as u32;
|
||||||
|
for section in &obj.sections {
|
||||||
|
let section_start = section.address as u32;
|
||||||
|
let mut align = 0x20;
|
||||||
|
while align_up(last_section_end, align) < section_start {
|
||||||
|
align = (align + 1).next_power_of_two();
|
||||||
|
}
|
||||||
|
if align_up(last_section_end, align) != section_start {
|
||||||
|
bail!(
|
||||||
|
"Couldn't determine alignment for section '{}' ({:#010X} -> {:#010X})",
|
||||||
|
section.name,
|
||||||
|
last_section_end,
|
||||||
|
section_start
|
||||||
|
);
|
||||||
|
}
|
||||||
|
last_section_end = section_start + section.size as u32;
|
||||||
|
alignments.push(align);
|
||||||
|
}
|
||||||
|
|
||||||
let section_defs = obj
|
let section_defs = obj
|
||||||
.sections
|
.sections
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| format!("{} ALIGN({:#X}):{{}}", s.name, 0x20 /* TODO */))
|
.zip(alignments)
|
||||||
|
.map(|(s, align)| format!("{} ALIGN({:#X}):{{}}", s.name, align))
|
||||||
.join("\n ");
|
.join("\n ");
|
||||||
|
|
||||||
let mut force_files = Vec::with_capacity(obj.link_order.len());
|
let mut force_files = Vec::with_capacity(obj.link_order.len());
|
||||||
|
@ -35,15 +61,17 @@ pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result<String
|
||||||
let last_section_symbol = format!("_f_{}", last_section_name.trim_start_matches('.'));
|
let last_section_symbol = format!("_f_{}", last_section_name.trim_start_matches('.'));
|
||||||
|
|
||||||
let mut out = include_str!("../../assets/ldscript.lcf")
|
let mut out = include_str!("../../assets/ldscript.lcf")
|
||||||
.replacen("$SECTIONS", §ion_defs, 1)
|
.replace("$ORIGIN", &format!("{:#X}", origin))
|
||||||
|
.replace("$SECTIONS", §ion_defs)
|
||||||
.replace("$LAST_SECTION_SYMBOL", &last_section_symbol)
|
.replace("$LAST_SECTION_SYMBOL", &last_section_symbol)
|
||||||
.replace("$LAST_SECTION_NAME", &last_section_name)
|
.replace("$LAST_SECTION_NAME", &last_section_name)
|
||||||
.replacen("$STACKSIZE", &format!("{:#X}", stack_size), 1)
|
.replace("$STACKSIZE", &format!("{:#X}", stack_size))
|
||||||
.replacen("$FORCEACTIVE", &force_active.join("\n "), 1);
|
.replace("$FORCEACTIVE", &force_active.join("\n "))
|
||||||
|
.replace("$ARENAHI", &format!("{:#X}", obj.arena_hi.unwrap_or(0x81700000)));
|
||||||
out = if auto_force_files {
|
out = if auto_force_files {
|
||||||
out.replacen("$FORCEFILES", &force_files.join("\n "), 1)
|
out.replace("$FORCEFILES", &force_files.join("\n "))
|
||||||
} else {
|
} else {
|
||||||
out.replacen("$FORCEFILES", "", 1)
|
out.replace("$FORCEFILES", "")
|
||||||
};
|
};
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue