diff --git a/src/libos/src/elf_helper.rs b/src/libos/src/elf_helper.rs index 716ed529..1a2cb171 100644 --- a/src/libos/src/elf_helper.rs +++ b/src/libos/src/elf_helper.rs @@ -34,15 +34,15 @@ pub fn print_sections(elf_file: &ElfFile) -> Result<(), Error> { Ok(()) } -pub fn print_pltrel_section(elf_file: &ElfFile) -> Result<(), Error> { - let rela_entries = get_pltrel_entries(elf_file) +pub fn print_rela_plt_section(elf_file: &ElfFile) -> Result<(), Error> { + let rela_entries = get_rela_entries(elf_file, ".rela.plt") .map_err(|e| (Errno::ENOEXEC, "Failed to get .pltrel entries"))?; let dynsym_entries = get_dynsym_entries(elf_file) .map_err(|e| (Errno::ENOEXEC, "Failed to get .dynsym entries"))?; - println!(".plt.rela section:"); + println!(".rela.plt section:"); for entry in rela_entries { println!("\toffset: {}, symbol index: {}, type: {}, addend: {}", entry.get_offset(), @@ -113,10 +113,10 @@ pub fn get_sym_entries<'b, 'a: 'b>(elf_file: &'b ElfFile<'a>) }).ok_or_else(|| (Errno::ENOEXEC, "Failed get the symbol entries").into()) } -pub fn get_pltrel_entries<'b, 'a: 'b>(elf_file: &'b ElfFile<'a>) +pub fn get_rela_entries<'b, 'a: 'b>(elf_file: &'b ElfFile<'a>, sec_name: &'b str) -> Result<&'a [Rela], Error> { - elf_file.find_section_by_name(".rela.plt") + elf_file.find_section_by_name(sec_name) .and_then(|plt_rela_section| { plt_rela_section.get_data(&elf_file).ok() }).and_then(|rela_table| { diff --git a/src/libos/src/process.rs b/src/libos/src/process.rs index 7929f5af..44a9d983 100644 --- a/src/libos/src/process.rs +++ b/src/libos/src/process.rs @@ -232,8 +232,10 @@ impl Process { { let mut new_process : Process = Default::default(); new_process.create_process_image(elf_file)?; + new_process.reloc_symbols(elf_file)?; new_process.link_syscalls(elf_file)?; new_process.mprotect()?; + //println!("Process image: {:#X?}", new_process); new_process.task = Task { user_stack_addr: new_process.init_stack(argv, envp)? as usize, @@ -298,12 +300,41 @@ impl Process { Ok(base_addr) } + fn reloc_symbols(self: &mut Process, elf_file: &ElfFile) + -> Result<(), Error> + { + let rela_entries = elf_helper::get_rela_entries(&elf_file, ".rela.dyn")?; + for rela_entry in rela_entries { + /* + println!("\toffset: {:#X}, symbol index: {}, type: {}, addend: {:#X}", + rela_entry.get_offset(), + rela_entry.get_symbol_table_index(), + rela_entry.get_type(), + rela_entry.get_addend()); + */ + + /* reloc type == R_X86_64_RELATIVE */ + match rela_entry.get_type() { + 8 if rela_entry.get_symbol_table_index() == 0 => { + let rela_addr = self.program_base_addr + rela_entry.get_offset() as usize; + let rela_val = self.program_base_addr + rela_entry.get_addend() as usize; + unsafe { + std::ptr::write_unaligned(rela_addr as *mut usize, rela_val); + } + } + // TODO: need to handle other relocation types + _ => { } + } + } + Ok(()) + } + fn link_syscalls(self: &mut Process, elf_file: &ElfFile) -> Result<(), Error> { let syscall_addr = __occlum_syscall as *const () as usize; - let rela_entries = elf_helper::get_pltrel_entries(&elf_file)?; + let rela_entries = elf_helper::get_rela_entries(&elf_file, ".rela.plt")?; let dynsym_entries = elf_helper::get_dynsym_entries(&elf_file)?; for rela_entry in rela_entries { let dynsym_idx = rela_entry.get_symbol_table_index() as usize; diff --git a/test/Makefile b/test/Makefile index 8b8fd16b..9ad5bd22 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,7 @@ CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) PROJECT_DIR := $(realpath $(CUR_DIR)/../) -TEST_SUITES := empty +TEST_SUITES := empty hello_world BUILD_TEST_SUITES := $(TEST_SUITES:%=%) RUN_TEST_SUITES := $(TEST_SUITES:%=run-%) CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) diff --git a/test/empty/empty.c b/test/empty/main.c similarity index 100% rename from test/empty/empty.c rename to test/empty/main.c diff --git a/test/hello_world/Makefile b/test/hello_world/Makefile new file mode 100644 index 00000000..b71a4d49 --- /dev/null +++ b/test/hello_world/Makefile @@ -0,0 +1,4 @@ +include ../test_common.mk + +EXTRA_C_FLAGS := +EXTRA_LINK_FLAGS := diff --git a/test/hello_world/main.c b/test/hello_world/main.c new file mode 100644 index 00000000..5cc3c736 --- /dev/null +++ b/test/hello_world/main.c @@ -0,0 +1,9 @@ +#include +#include + +static const char* msg = "Hello World\n"; + +int main(void) { + write(1, msg, strlen(msg) + 1); + return 0; +}