Commit 82031140 authored by Arjan Oortgiese's avatar Arjan Oortgiese

Support for reading 64-bit programs ELF symbol tables

parent ebf20fff
......@@ -20,6 +20,8 @@ exported_clean_symbol :: !Int !{#Char} -> Bool;
exported_clean_symbol i s
| i==0
= False;
| s.[i]=='\0'
= False;
| s.[i]=='e' && s.[i+1]=='_' && s.[i+2]=='_'
= True;
| s.[i]=='_' && s.[i+1]=='_'
......@@ -48,6 +50,8 @@ exported_clean_symbol i s
= False;
| s.[i]=='I' && s.[i+1]=='N' && s.[i+2]=='T' && s.[i+3]=='\0'
= True;
| s.[i]=='d' && s.[i+1]=='I' && s.[i+2]=='N' && s.[i+3]=='T' && s.[i+4]=='\0'
= True;
| s.[i]=='C' && s.[i+1]=='H' && s.[i+2]=='A' && s.[i+3]=='R' && s.[i+4]=='\0'
= True;
| s.[i]=='R' && s.[i+1]=='E' && s.[i+2]=='A' && s.[i+3]=='L' && s.[i+4]=='\0'
......@@ -86,43 +90,74 @@ read_section_headers section_n n_section_headers section_headers exe_file
| section_n<n_section_headers
# (ok,i0,exe_file) = freadi exe_file;
# (ok,section_type,exe_file) = freadi exe_file;
# (ok,i2,exe_file) = freadi exe_file;
# (ok,i3,exe_file) = freadi exe_file;
# (ok,i4,exe_file) = freadi exe_file;
# (ok,i5,exe_file) = freadi exe_file;
# (ok,i6,exe_file) = freadi exe_file;
# (ok,i7,exe_file) = freadi exe_file;
# (ok,i8,exe_file) = freadi exe_file;
# (ok,i9,exe_file) = freadi exe_file;
# (ok,sh_flags,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,sh_addr,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,sh_offset,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,sh_size,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,sh_link,exe_file) = freadi exe_file;
# (ok,sh_info,exe_file) = freadi exe_file;
# (ok,sh_addralign,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,sh_entsize,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
| section_type==2
# section_headers & symbol_table_offset = i4, symbol_table_size = i5,
string_table_section_n = i6, first_non_local_symbol = i7;
# section_headers & symbol_table_offset = sh_offset, symbol_table_size = sh_size,
string_table_section_n = sh_link, first_non_local_symbol = sh_info;
= read_section_headers (section_n+1) n_section_headers section_headers exe_file;
| section_type==3
| section_n==section_headers.string_table_section_n
# section_headers & string_table_offset = i4, string_table_size = i5;
# section_headers & string_table_offset = sh_offset, string_table_size = sh_size;
= read_section_headers (section_n+1) n_section_headers section_headers exe_file;
= read_section_headers (section_n+1) n_section_headers section_headers exe_file;
= read_section_headers (section_n+1) n_section_headers section_headers exe_file;
= (section_headers,exe_file);
read_symbol_table symbol_n symbol_table_size string_table symbols exe_file
= IF_INT_64_OR_32
(read_symbol_table64 symbol_n symbol_table_size string_table symbols exe_file)
(read_symbol_table32 symbol_n symbol_table_size string_table symbols exe_file);
read_symbol_table32 symbol_n symbol_table_size string_table symbols exe_file
| symbol_n<<4 < symbol_table_size
# (ok,i0,exe_file) = freadi exe_file;
# (ok,i1,exe_file) = freadi exe_file;
# (ok,i2,exe_file) = freadi exe_file;
#! (ok,i3,exe_file) = freadi exe_file;
| not (exported_clean_symbol i0 string_table)
= read_symbol_table (symbol_n+1) symbol_table_size string_table symbols exe_file;
= read_symbol_table32 (symbol_n+1) symbol_table_size string_table symbols exe_file;
# object = i3 bitand 0xf;
bind = (i3>>4) bitand 0xf;
| (object==1 /*OBJECT*/ || object==2 /*FUNC*/ || object==0 /*NOTYPE*/) // bind==1 /* GLOBAL */
# symbol_name = string_from_string_table i0 string_table;
# symbols = [(symbol_name,i1):symbols];
= read_symbol_table (symbol_n+1) symbol_table_size string_table symbols exe_file;
= read_symbol_table (symbol_n+1) symbol_table_size string_table symbols exe_file;
= read_symbol_table32 (symbol_n+1) symbol_table_size string_table symbols exe_file;
= read_symbol_table32 (symbol_n+1) symbol_table_size string_table symbols exe_file;
= (symbols,exe_file);
read_symbol_table64 symbol_n symbol_table_size string_table symbols exe_file
| symbol_n*24 < symbol_table_size
# (ok,st_name,exe_file) = freadi exe_file;
# (ok,i1,exe_file) = freadi exe_file;
# (ok,st_value,exe_file) = freadi64 exe_file;
#! (ok,st_size,exe_file) = freadi64 exe_file;
| not (exported_clean_symbol st_name string_table)
= read_symbol_table64 (symbol_n+1) symbol_table_size string_table symbols exe_file;
# object = i1 bitand 0xf;
bind = (i1>>4) bitand 0xf;
| (object==1 /*OBJECT*/ || object==2 /*FUNC*/ || object==0 /*NOTYPE*/) // bind==1 /* GLOBAL */
# symbol_name = string_from_string_table st_name string_table;
# symbols = [(symbol_name,st_value):symbols];
= read_symbol_table64 (symbol_n+1) symbol_table_size string_table symbols exe_file;
= read_symbol_table64 (symbol_n+1) symbol_table_size string_table symbols exe_file;
= (symbols,exe_file);
freadi64 exe_file
# (ok, i1, exe_file) = freadi exe_file;
| not ok
= (False, 0, exe_file);
# (ok, i2, exe_file) = freadi exe_file;
| not ok
= (False, 0, exe_file);
= (True, (i2 << 32) + i1, exe_file);
read_symbols :: !{#Char} !*Files -> (!{#Symbol},!*Files);
read_symbols file_name files
# (ok,exe_file,files) = fopen file_name FReadData files;
......@@ -141,9 +176,9 @@ read_symbols file_name files
| not ok || c<>'F'
= abort "Not an ELF file (error in header)";
# (ok,exe_file) = fseek exe_file 32 FSeekSet;
# (ok,section_headers_offset,exe_file) = freadi exe_file;
# (ok,exe_file) = fseek exe_file 48 FSeekSet;
# (ok,exe_file) = fseek exe_file (IF_INT_64_OR_32 40 32) FSeekSet;
# (ok,section_headers_offset,exe_file) = IF_INT_64_OR_32 (freadi64 exe_file) (freadi exe_file);
# (ok,exe_file) = fseek exe_file (IF_INT_64_OR_32 60 48) FSeekSet;
| not ok
= abort "fseek failed";
# (ok,i ,exe_file) = freadi exe_file;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment