Fix the alignment of stack entrypoint
Libc ABI requires 16-byte alignment of the stack entrypoint
This commit is contained in:
parent
1882458862
commit
f87bbc586b
@ -58,10 +58,11 @@ pub fn do_init(
|
|||||||
let stack_buf = unsafe { StackBuf::new(stack_top, init_area_size)? };
|
let stack_buf = unsafe { StackBuf::new(stack_top, init_area_size)? };
|
||||||
let envp_cloned = clone_cstrings_on_stack(&stack_buf, envp)?;
|
let envp_cloned = clone_cstrings_on_stack(&stack_buf, envp)?;
|
||||||
let argv_cloned = clone_cstrings_on_stack(&stack_buf, argv)?;
|
let argv_cloned = clone_cstrings_on_stack(&stack_buf, argv)?;
|
||||||
|
adjust_alignment(&stack_buf, auxtbl, &envp_cloned, &argv_cloned)?;
|
||||||
dump_auxtbl_on_stack(&stack_buf, auxtbl)?;
|
dump_auxtbl_on_stack(&stack_buf, auxtbl)?;
|
||||||
dump_cstrptrs_on_stack(&stack_buf, &envp_cloned);
|
dump_cstrptrs_on_stack(&stack_buf, &envp_cloned)?;
|
||||||
dump_cstrptrs_on_stack(&stack_buf, &argv_cloned);
|
dump_cstrptrs_on_stack(&stack_buf, &argv_cloned)?;
|
||||||
stack_buf.put(argv.len() as u64);
|
stack_buf.put(argv.len() as u64)?;
|
||||||
Ok(stack_buf.get_pos())
|
Ok(stack_buf.get_pos())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,21 +160,56 @@ fn clone_cstrings_on_stack<'a, 'b>(
|
|||||||
Ok(cstrs_cloned)
|
Ok(cstrs_cloned)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_auxtbl_on_stack<'a, 'b>(stack: &'a StackBuf, auxtbl: &'b AuxVec) -> Result<()> {
|
fn adjust_alignment(
|
||||||
// For every key-value pair, dump the value first, then the key
|
stack: &StackBuf,
|
||||||
stack.put(0 as u64);
|
auxtbl: &AuxVec,
|
||||||
stack.put(AuxKey::AT_NULL as u64);
|
envp: &[&CStr],
|
||||||
for (aux_key, aux_val) in auxtbl.table() {
|
argv: &[&CStr],
|
||||||
stack.put(*aux_val as u64);
|
) -> Result<()> {
|
||||||
stack.put(*aux_key as u64);
|
// Put 8 byte to make the postion of stack 8-byte aligned
|
||||||
|
stack.put(0 as u64)?;
|
||||||
|
let current_pos = stack.get_pos();
|
||||||
|
let to_alloc_size = {
|
||||||
|
let auxtbl_size = calc_auxtbl_size_on_stack(auxtbl);
|
||||||
|
let envp_size = calc_cstrptrs_size_on_stack(&envp);
|
||||||
|
let argv_size = calc_cstrptrs_size_on_stack(&argv);
|
||||||
|
let argc_size = mem::size_of::<u64>();
|
||||||
|
auxtbl_size + envp_size + argv_size + argc_size
|
||||||
|
};
|
||||||
|
// Libc ABI requires 16-byte alignment of the stack entrypoint.
|
||||||
|
// Current postion of the stack is 8-byte aligned already, insert 8 byte
|
||||||
|
// to meet the requirement if necessary.
|
||||||
|
if (current_pos - to_alloc_size) % 16 != 0 {
|
||||||
|
stack.put(0 as u64)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_cstrptrs_on_stack<'a, 'b>(stack: &'a StackBuf, strptrs: &'b [&'a CStr]) -> Result<()> {
|
fn dump_auxtbl_on_stack<'a, 'b>(stack: &'a StackBuf, auxtbl: &'b AuxVec) -> Result<()> {
|
||||||
stack.put(0 as u64); // End with a NULL pointer
|
// For every key-value pair, dump the value first, then the key
|
||||||
for sp in strptrs.iter().rev() {
|
stack.put(0 as u64)?;
|
||||||
stack.put(sp.as_ptr() as u64);
|
stack.put(AuxKey::AT_NULL as u64)?;
|
||||||
|
for (aux_key, aux_val) in auxtbl.table() {
|
||||||
|
stack.put(*aux_val as u64)?;
|
||||||
|
stack.put(*aux_key as u64)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_auxtbl_size_on_stack(auxtbl: &AuxVec) -> usize {
|
||||||
|
let auxtbl_item_size = mem::size_of::<u64>() * 2;
|
||||||
|
(auxtbl.table().len() + 1) * auxtbl_item_size
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dump_cstrptrs_on_stack<'a, 'b>(stack: &'a StackBuf, strptrs: &'b [&'a CStr]) -> Result<()> {
|
||||||
|
stack.put(0 as u64)?; // End with a NULL pointer
|
||||||
|
for sp in strptrs.iter().rev() {
|
||||||
|
stack.put(sp.as_ptr() as u64)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_cstrptrs_size_on_stack(strptrs: &[&CStr]) -> usize {
|
||||||
|
let cstrptrs_item_size = mem::size_of::<u64>();
|
||||||
|
(strptrs.len() + 1) * cstrptrs_item_size
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user