Do relocation for .rela.dyn section

This commit is contained in:
Tate, Hongliang Tian 2018-11-28 22:17:12 +08:00
parent cf77c3a9a8
commit 4c3f556c7d
6 changed files with 51 additions and 7 deletions

@ -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<P64>], 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| {

@ -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;

@ -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-%)

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

9
test/hello_world/main.c Normal file

@ -0,0 +1,9 @@
#include <unistd.h>
#include <string.h>
static const char* msg = "Hello World\n";
int main(void) {
write(1, msg, strlen(msg) + 1);
return 0;
}