From 000f57e11cf3272951cd3463f5d8bb82bc8e3903 Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 6 Nov 2022 22:11:41 -0500 Subject: read symbol type --- .gitignore | 1 + src/elf.rs | 12 ++++++++++++ src/linker.rs | 20 ++++++++++++-------- test.c | 8 +++++--- tests/dylib-test.c | 12 ++++++++++++ tests/dylib.c | 4 ++++ tests/dylib.h | 8 ++++++++ 7 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 tests/dylib-test.c create mode 100644 tests/dylib.c create mode 100644 tests/dylib.h diff --git a/.gitignore b/.gitignore index 52f2ae5..437eab9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target *.o +*.so tags TAGS *.out diff --git a/src/elf.rs b/src/elf.rs index 2a51082..41ce491 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -373,6 +373,18 @@ impl From for SymbolType { } } +impl From for u8 { + fn from(x: SymbolType) -> Self { + use SymbolType::*; + match x { + Function => STT_FUNC, + Object => STT_OBJECT, + Section => STT_SECTION, + Other(x) => x, + } + } +} + #[derive(Debug, Copy, Clone)] pub enum SymbolValue { Undefined, diff --git a/src/linker.rs b/src/linker.rs index f8f5760..8126d19 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -302,6 +302,8 @@ struct Relocation { /// symbol that needs to be supplied sym: SymbolName, r#type: elf::RelType, + /// type of `sym` + symbol_type: elf::SymbolType, addend: i64, } @@ -400,8 +402,10 @@ struct LinkerOutput { relocations: Vec<(Relocation, u64)>, /// contents of dynamic strtab. strtab: Vec, - /// offsets into dynamic strtab where symbol names appear. - symbol_strtab_offsets: HashMap, + /// (offset into strtab, type) + /// Seems like no one sets the type of undefined symbols. + /// Still, might as well pretend they do. + dynsyms: HashMap, /// array of stratb pointers to library names. lib_strtab_offsets: Vec, } @@ -416,7 +420,7 @@ impl LinkerOutput { interp: vec![], relocations: vec![], lib_strtab_offsets: vec![], - symbol_strtab_offsets: HashMap::new(), + dynsyms: HashMap::new(), strtab: vec![0], } } @@ -450,10 +454,10 @@ impl LinkerOutput { pub fn add_relocation(&mut self, symbol_names: &SymbolNames, rel: &Relocation, addr: u64) { let name = rel.sym; - if self.symbol_strtab_offsets.get(&name).is_none() { + if self.dynsyms.get(&name).is_none() { let s = symbol_names.get_str(name).unwrap(); let offset = self.add_string(s); - self.symbol_strtab_offsets.insert(name, offset); + self.dynsyms.insert(name, (offset, rel.symbol_type)); } self.relocations.push((rel.clone(), addr)); } @@ -559,12 +563,11 @@ impl LinkerOutput { let null_symbol = [0; mem::size_of::()]; out.write_all(&null_symbol)?; let mut symbols: HashMap = HashMap::new(); - for (i, (sym, strtab_offset)) in self.symbol_strtab_offsets.iter().enumerate() { + for (i, (sym, (strtab_offset, symbol_type))) in self.dynsyms.iter().enumerate() { symbols.insert(*sym, (i + 1) as u32); - // @TODO: allow STT_OBJECT as well let sym = elf::Sym32 { name: *strtab_offset as u32, - info: elf::STB_GLOBAL << 4 | elf::STT_FUNC, + info: elf::STB_GLOBAL << 4 | u8::from(*symbol_type), value: 0, size: 0, other: 0, @@ -812,6 +815,7 @@ impl<'a> Linker<'a> { r#where, source_id, sym, + symbol_type: rel.symbol.r#type, r#type: rel.r#type, addend: rel.addend, }); diff --git a/test.c b/test.c index ef50528..4b86a0b 100644 --- a/test.c +++ b/test.c @@ -1,9 +1,11 @@ #include #include -int x; -void entry() { - puts("Hello, world!"); +extern int errno; +int main() { + errno = 0; + fopen("zzz","r"); + printf("%d\n",errno); //printf("hello\n"); exit(0); diff --git a/tests/dylib-test.c b/tests/dylib-test.c new file mode 100644 index 0000000..ae824b0 --- /dev/null +++ b/tests/dylib-test.c @@ -0,0 +1,12 @@ +#include "dylib.h" +#include +#include + +void entry(void) { + the_number = 7; + printf("%d\n",the_number); + bigger(); + printf("%d\n",the_number); + + exit(0); +} diff --git a/tests/dylib.c b/tests/dylib.c new file mode 100644 index 0000000..8da43a8 --- /dev/null +++ b/tests/dylib.c @@ -0,0 +1,4 @@ +#include "dylib.h" + +int the_number; +void bigger() { the_number += 1; } diff --git a/tests/dylib.h b/tests/dylib.h new file mode 100644 index 0000000..3b5d369 --- /dev/null +++ b/tests/dylib.h @@ -0,0 +1,8 @@ +// here is a realyl great dynami library i made it myself +#ifndef DYLIB_H_IS_REALLY_INCLUDED____ +#define DYLIB_H_IS_REALLY_INCLUDED____ +// ---------------dylib HEADER FILE --------- +// /PLEASE INCLUDE IF YOU WANT TO USE dylib +extern int the_number; // the number what it is +void bigger(void); // make the number bigger by 1 +#endif // DYLIB_H_IS_REALLY_INCLUDED____ -- cgit v1.2.3