Run dynamically-linked hello world
This commit is contained in:
parent
33739cc00b
commit
e11c30c5c5
@ -9,19 +9,29 @@ pub fn do_init(
|
|||||||
ldso_elf_file: &ElfFile,
|
ldso_elf_file: &ElfFile,
|
||||||
ldso_elf_buf: &[u8]
|
ldso_elf_buf: &[u8]
|
||||||
) -> Result<ProcessVM, Error> {
|
) -> Result<ProcessVM, Error> {
|
||||||
|
// Alloc all virtual memory areas
|
||||||
let mut code_seg = get_code_segment(elf_file)?;
|
let mut code_seg = get_code_segment(elf_file)?;
|
||||||
let mut data_seg = get_data_segment(elf_file)?;
|
let mut data_seg = get_data_segment(elf_file)?;
|
||||||
let mut ldso_code_seg = get_code_segment(ldso_elf_file)?;
|
|
||||||
let mut ldso_data_seg = get_data_segment(ldso_elf_file)?;
|
|
||||||
|
|
||||||
// Alloc all virtual memory areas
|
|
||||||
let code_start = 0;
|
let code_start = 0;
|
||||||
let code_end = align_down(data_seg.get_mem_addr(), data_seg.get_mem_align());
|
let code_end = align_down(data_seg.get_mem_addr(), data_seg.get_mem_align());
|
||||||
let data_start = code_end;
|
let data_start = code_end;
|
||||||
let data_end = align_up(data_seg.get_mem_addr() + data_seg.get_mem_size(), 4096);
|
let data_end = align_up(data_seg.get_mem_addr() + data_seg.get_mem_size(), 4096);
|
||||||
let code_size = code_end - code_start;
|
let code_size = code_end - code_start;
|
||||||
let data_size = data_end - data_start;
|
let data_size = data_end - data_start;
|
||||||
let mut process_vm = ProcessVMBuilder::new(code_size, data_size).build()?;
|
|
||||||
|
let mut ldso_code_seg = get_code_segment(ldso_elf_file)?;
|
||||||
|
let mut ldso_data_seg = get_data_segment(ldso_elf_file)?;
|
||||||
|
let ldso_code_start = 0;
|
||||||
|
let ldso_code_end = align_down(ldso_data_seg.get_mem_addr(), ldso_data_seg.get_mem_align());
|
||||||
|
let ldso_data_start = ldso_code_end;
|
||||||
|
let ldso_data_end = align_up(ldso_data_seg.get_mem_addr() + ldso_data_seg.get_mem_size(), 4096);
|
||||||
|
let ldso_code_size = ldso_code_end - ldso_code_start;
|
||||||
|
let ldso_data_size = ldso_data_end - ldso_data_start;
|
||||||
|
|
||||||
|
let mut process_vm = ProcessVMBuilder::new(code_size, data_size)
|
||||||
|
.ldso_code_size(ldso_code_size)
|
||||||
|
.ldso_data_size(ldso_data_size)
|
||||||
|
.build()?;
|
||||||
|
|
||||||
// Load code and data
|
// Load code and data
|
||||||
let process_base_addr = process_vm.get_code_range().start();
|
let process_base_addr = process_vm.get_code_range().start();
|
||||||
@ -38,7 +48,7 @@ pub fn do_init(
|
|||||||
ldso_data_seg.load_from_file(ldso_elf_buf);
|
ldso_data_seg.load_from_file(ldso_elf_buf);
|
||||||
|
|
||||||
// Relocate symbols
|
// Relocate symbols
|
||||||
reloc_symbols(process_base_addr, elf_file)?;
|
//reloc_symbols(process_base_addr, elf_file)?;
|
||||||
//link_syscalls(process_base_addr, elf_file)?;
|
//link_syscalls(process_base_addr, elf_file)?;
|
||||||
|
|
||||||
Ok(process_vm)
|
Ok(process_vm)
|
||||||
|
@ -44,7 +44,6 @@ pub fn do_spawn<P: AsRef<Path>>(
|
|||||||
let inode = parent_ref.lock().unwrap().lookup_inode(path)?;
|
let inode = parent_ref.lock().unwrap().lookup_inode(path)?;
|
||||||
inode.read_as_vec()?
|
inode.read_as_vec()?
|
||||||
};
|
};
|
||||||
|
|
||||||
let elf_file = {
|
let elf_file = {
|
||||||
let elf_file =
|
let elf_file =
|
||||||
ElfFile::new(&elf_buf).map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?;
|
ElfFile::new(&elf_buf).map_err(|e| (Errno::ENOEXEC, "Failed to parse the ELF file"))?;
|
||||||
@ -82,20 +81,22 @@ pub fn do_spawn<P: AsRef<Path>>(
|
|||||||
let vm = init_vm::do_init(&elf_file, &elf_buf[..],
|
let vm = init_vm::do_init(&elf_file, &elf_buf[..],
|
||||||
&ldso_elf_file, &ldso_elf_buf[..])?;
|
&ldso_elf_file, &ldso_elf_buf[..])?;
|
||||||
let base_addr = vm.get_base_addr();
|
let base_addr = vm.get_base_addr();
|
||||||
let program_entry = {
|
let auxtbl = init_auxtbl(&vm, &elf_file)?;
|
||||||
let program_entry = base_addr + elf_helper::get_start_address(&elf_file)?;
|
|
||||||
if !vm.get_code_range().contains(program_entry) {
|
|
||||||
return errno!(EINVAL, "Invalid program entry");
|
|
||||||
}
|
|
||||||
program_entry
|
|
||||||
};
|
|
||||||
let auxtbl = init_auxtbl(base_addr, program_entry, &elf_file)?;
|
|
||||||
let task = {
|
let task = {
|
||||||
|
let ldso_entry = {
|
||||||
|
let ldso_base_addr = vm.get_ldso_code_range().start();
|
||||||
|
let ldso_entry = ldso_base_addr +
|
||||||
|
elf_helper::get_start_address(&ldso_elf_file)?;
|
||||||
|
if !vm.get_ldso_code_range().contains(ldso_entry) {
|
||||||
|
return errno!(EINVAL, "Invalid program entry");
|
||||||
|
}
|
||||||
|
ldso_entry
|
||||||
|
};
|
||||||
let user_stack_base = vm.get_stack_base();
|
let user_stack_base = vm.get_stack_base();
|
||||||
let user_stack_limit = vm.get_stack_limit();
|
let user_stack_limit = vm.get_stack_limit();
|
||||||
let user_rsp = init_stack::do_init(user_stack_base, 4096, argv, envp, &auxtbl)?;
|
let user_rsp = init_stack::do_init(user_stack_base, 4096, argv, envp, &auxtbl)?;
|
||||||
unsafe {
|
unsafe {
|
||||||
Task::new(program_entry, user_rsp,
|
Task::new(ldso_entry, user_rsp,
|
||||||
user_stack_base, user_stack_limit, None)?
|
user_stack_base, user_stack_limit, None)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -167,8 +168,7 @@ fn init_files(parent_ref: &ProcessRef, file_actions: &[FileAction]) -> Result<Fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init_auxtbl(
|
fn init_auxtbl(
|
||||||
base_addr: usize,
|
process_vm: &ProcessVM,
|
||||||
program_entry: usize,
|
|
||||||
elf_file: &ElfFile,
|
elf_file: &ElfFile,
|
||||||
) -> Result<AuxTable, Error> {
|
) -> Result<AuxTable, Error> {
|
||||||
let mut auxtbl = AuxTable::new();
|
let mut auxtbl = AuxTable::new();
|
||||||
@ -179,13 +179,18 @@ fn init_auxtbl(
|
|||||||
auxtbl.set(AuxKey::AT_EGID, 0)?;
|
auxtbl.set(AuxKey::AT_EGID, 0)?;
|
||||||
auxtbl.set(AuxKey::AT_SECURE, 0)?;
|
auxtbl.set(AuxKey::AT_SECURE, 0)?;
|
||||||
|
|
||||||
|
let process_base_addr = process_vm.get_process_range().start();
|
||||||
let ph = elf_helper::get_program_header_info(elf_file)?;
|
let ph = elf_helper::get_program_header_info(elf_file)?;
|
||||||
auxtbl.set(AuxKey::AT_PHDR, (base_addr + ph.addr) as u64)?;
|
auxtbl.set(AuxKey::AT_PHDR, (process_base_addr + ph.addr) as u64)?;
|
||||||
auxtbl.set(AuxKey::AT_PHENT, ph.entry_size as u64)?;
|
auxtbl.set(AuxKey::AT_PHENT, ph.entry_size as u64)?;
|
||||||
auxtbl.set(AuxKey::AT_PHNUM, ph.entry_num as u64)?;
|
auxtbl.set(AuxKey::AT_PHNUM, ph.entry_num as u64)?;
|
||||||
|
|
||||||
|
let program_entry = process_base_addr + elf_helper::get_start_address(&elf_file)?;
|
||||||
auxtbl.set(AuxKey::AT_ENTRY, program_entry as u64)?;
|
auxtbl.set(AuxKey::AT_ENTRY, program_entry as u64)?;
|
||||||
|
|
||||||
|
let ldso_base = process_vm.get_ldso_code_range().start();
|
||||||
|
auxtbl.set(AuxKey::AT_BASE, ldso_base as u64)?;
|
||||||
|
|
||||||
auxtbl.set(AuxKey::AT_SYSINFO, 123)?;
|
auxtbl.set(AuxKey::AT_SYSINFO, 123)?;
|
||||||
|
|
||||||
let syscall_addr = __occlum_syscall as *const () as u64;
|
let syscall_addr = __occlum_syscall as *const () as u64;
|
||||||
|
@ -45,7 +45,7 @@ $(BUILD_TARGETS): %:
|
|||||||
|
|
||||||
sefs:
|
sefs:
|
||||||
@$(RM) -rf $(SEFS_PATH)
|
@$(RM) -rf $(SEFS_PATH)
|
||||||
@cp ~/Workspace/occlum/musl.old/lib/libc.so $(FS_PATH)/ld.so
|
@cp /lib/ld-musl-x86_64.so.1 $(FS_PATH)/ld.so
|
||||||
@cd $(PROJECT_DIR)/deps/sefs/sefs-fuse/bin/ && \
|
@cd $(PROJECT_DIR)/deps/sefs/sefs-fuse/bin/ && \
|
||||||
./app \
|
./app \
|
||||||
$(CUR_DIR)/$(SEFS_PATH) \
|
$(CUR_DIR)/$(SEFS_PATH) \
|
||||||
|
Loading…
Reference in New Issue
Block a user