diff options
| author | Kathy Gray | 2014-09-29 12:36:14 +0100 |
|---|---|---|
| committer | Kathy Gray | 2014-09-29 12:36:14 +0100 |
| commit | c205e3e77e35cf07fdf616c133d9a70a96986394 (patch) | |
| tree | a827d3d436fb69c4a73df9b9fb066c98fbceab84 /src/elf_model/elf_symbol_table.ml | |
| parent | 80eabf2fca417f5dc245e5212e0f33f6c23bb58b (diff) | |
Add in elf model from Dominic/Stephen. Make run_power build again. Does not effectively use elf model yet
Diffstat (limited to 'src/elf_model/elf_symbol_table.ml')
| -rw-r--r-- | src/elf_model/elf_symbol_table.ml | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/elf_model/elf_symbol_table.ml b/src/elf_model/elf_symbol_table.ml new file mode 100644 index 00000000..a2fed159 --- /dev/null +++ b/src/elf_model/elf_symbol_table.ml @@ -0,0 +1,246 @@ +(*Generated by Lem from elf_symbol_table.lem.*) +open Lem_basic_classes +open Lem_bool +open Lem_list +open Lem_num +open Lem_string + +open Bitstring +open Elf_section_header +open Elf_types +open Error +open Show + +(** Symbol table indices *) + +(** Symbol table index is a subscript into the symbol table, which holds + * information needed to locate and relocate a program's symbolic definitions + * and references. Index 0 designates both the first entry in the table and + * serves as the undefined symbol index. [stn_undef] is a mnemonic for that + * undefined symbol. + *) +let stn_undef : int =( 0) + +(** Symbol bindings *) + +(** [elf32_st_bind] unpacks the binding information from the [st_info] field + * in the record type below. + *) +let elf32_st_bind i = +(Int64.to_int (Int64.shift_right i( 4))) +(** [elf64_st_bind] unpacks the binding information from the [st_info] field + * in the record type below. + *) +let elf64_st_bind i = +(Int64.to_int (Int64.shift_right i( 4))) +(** [elf32_st_type] unpacks the type information from the [e32_st_info] field + * in the record type below. + *) +let elf32_st_type i = +(Int64.to_int (Int64.logand i (Int64.of_int( 15)))) (* 0xf *) +(** [elf64_st_type] unpacks the type information from the [e64_st_info] field + * in the record type below. + *) +let elf64_st_type i = +(Int64.to_int (Int64.logand i (Int64.of_int( 15)))) (* 0xf *) +(** [elf32_st_info] unpacks other information from the [e32_st_info] field in the + * record type below. + *) +let elf32_st_info b t = +(let left = (Int64.shift_left b( 4)) in + let right = (Int64.logand t (Int64.of_int( 15))) in (* 0xf *) + let result = (Int64.add left right) in + Int64.to_int result) +(** [elf64_st_info] unpacks other information from the [e64_st_info] field in the + * record type below. + *) +let elf64_st_info b t = +(let left = (Int64.shift_left b( 4)) in + let right = (Int64.logand t (Int64.of_int( 15))) in (* 0xf *) + let result = (Int64.add left right) in + Int64.to_int result) +(** [stb_local]: local symbols are not visible outside the object file + * containing their definition. + *) +let stb_local : int =( 0) +(** [stb_global]: global symbols are visible to all object files being combined. + *) +let stb_global : int =( 1) +(** [stb_weak]: weak symbols resemble global symbols but their definitions have + * lower precedence. + *) +let stb_weak : int =( 2) +(** [stb_loos]: start of the range reserved for operating-system specific + * semantics. + *) +let stb_loos : int =( 10) +(** [stb_hios]: end of the range reserved for operating-system specific + * semantics. + *) +let stb_hios : int =( 12) +(** [stb_loproc]: start of the range reserved for processor specific semantics. + *) +let stb_loproc : int =( 13) +(** [stb_hiproc]: end of the range reserved for processor specific semantics. + *) +let stb_hiproc : int =( 15) + +(** Symbol types. *) + +(** [stt_notype]: the symbol's type is not specified. + *) +let stt_notype : int =( 0) +(** [stt_object]: the symbol is associated with a data object, such as a + * variable, an array, and so on. + *) +let stt_object : int =( 1) +(** [stt_func]: the symbol is associated with a function or other executable + * code. + *) +let stt_func : int =( 2) +(** [stt_section]: the symbol is associated with a section. + *) +let stt_section : int =( 3) +(** [stt_file]: the symbol's name gives the name of the source file associated + * with the object file. Must have [stb_local] binding and its section index + * must be [shn_abs]. It must also precede the other [stb_local] symbols for + * the file, is present. + *) +let stt_file : int =( 4) +(** [stt_common]: labels an unitialised common block. + *) +let stt_common : int =( 5) +(** [stt_tls]: specifies a thread local storage (TLS) entity. Gives the + * assigned offset of the symbol, not its address. TLS symbols may only be + * referenced by special TLS relocations and TLS relocations may only reference + * symbols with type [stt_tls]. + *) +let stt_tls : int =( 6) +(** [stt_loos]: start of the range reserved for operating-system specific + * semantics. + *) +let stt_loos : int =( 10) +(** [stt_hios]: end of the range reserved for operating-system specific + * semantics. + *) +let stt_hios : int =( 12) +(** [stt_loproc]: start of the range reserved for processor specific + * semantics. + *) +let stt_loproc : int =( 13) +(** [stt_hiproc]: end of the range reserved for processor specific semantics. + *) +let stt_hiproc : int =( 15) + +(** Symbol visibility. *) + +(** [elf32_st_visibility] unpacks visibility information from the [e32_st_other] + * field in the record type below. + *) +(*val elf32_st_visibility : unsigned_char -> nat*) +let elf32_st_visibility o = +(Int64.to_int (Int64.logand o (Int64.of_int( 3)))) (* 0x3 *) + +(** [stv_default]: symbol visibility is as specified by the symbol's binding + * type. Global and weak symbols are visible outside their defining component + * (executable or shared object file). Local symbols are hidden. Global and + * weak symbols are also pre-emptable: they may be pre-empted by definitions + * of the same name in another component. + *) +let stv_default : int =( 0) +(** [stv_internal]: meaning may be further defined by processor supplements to + * further constrain hidden symbols. An internal symbol in a relocatable file + * must be either removed or converted to [stb_local] when the relocatable + * object is included in an executable or shared object by the linker. + *) +let stv_internal : int =( 1) +(** [stv_hidden]: a symbol in the current component is hidden if its name is not + * visible to other components, necessarily protecting the symbol. A hidden + * object may still be referenced from another component if its address is + * passed outside. A hidden symbol in a relocatable object must be either + * removed or converted to [stb_local] when the relocatable file is included in + * an executable or shared object by the linker. + *) +let stv_hidden : int =( 2) +(** [stv_protected]: a protected symbol is visible in other components but is + * not pre-emptable, so that any reference to such a symbol from within the + * defining component must be resolved to the definition in that component. + * A symbol with [stb_local] binding must not have [stv_protected] visibility. + * If a symbol definition with [stv_protected] visibility from a shared object + * file is taken as resolving a reference from an executable or another shared + * object, the [shn_undef] symbol table entry created has [stv_default] + * visibility. + *) +let stv_protected : int =( 3) + +(** The symbol table entry type. *) + +type elf32_symbol_table_entry = + { elf32_st_name : Int64.t + ; elf32_st_value : Int64.t + ; elf32_st_size : Int64.t + ; elf32_st_info0 : Int64.t + ; elf32_st_other : Int64.t + ; elf32_st_shndx : Int64.t + } + +let string_of_elf32_symbol_table_entry entry = +(List.fold_right (^) [ + "\t"; "Name: "; Int64.to_string entry.elf32_st_name + ; "\t"; "Size: "; Int64.to_string entry.elf32_st_size + ; "\n\t"; "Value: "; Int64.to_string entry.elf32_st_value + ; "\t"; "Info: "; Int64.to_string entry.elf32_st_info0; "\n\n" + ] "") + +let read_elf32_symbol_table_entry bitstring6 : elf32_symbol_table_entry error = +(Ml_bindings.read_elf32_word bitstring6 >>= (fun (name, bitstring5) -> + Ml_bindings.read_elf32_addr bitstring5 >>= (fun (value, bitstring4) -> + Ml_bindings.read_elf32_word bitstring4 >>= (fun (size, bitstring3) -> + Ml_bindings.read_unsigned_char bitstring3 >>= (fun (info, bitstring2) -> + Ml_bindings.read_unsigned_char bitstring2 >>= (fun (other, bitstring1) -> + Ml_bindings.read_elf32_half bitstring1 >>= (fun (shndx, bitstring0) -> + let entry = ({ elf32_st_name = name; elf32_st_value = value; elf32_st_size = size; elf32_st_info0 = info; elf32_st_other = other; elf32_st_shndx = shndx }) in + return entry))))))) + +let rec read_elf32_symbol_table_entries bs : ( elf32_symbol_table_entry list) error = +(if Bitstring.bitstring_length bs = 0 then + return [] + else + let (cut, rest) = (Utility.partition_bitstring( 128) bs) in + read_elf32_symbol_table_entry cut >>= (fun head -> + read_elf32_symbol_table_entries rest >>= (fun tail -> + return (head::tail)))) + +let rec read_elf32_symbol_tables' offset_sizes bs = +((match offset_sizes with + | [] -> return [] + | x::xs -> + let (offset, size) = x in + let (_, relevant) = (Utility.partition_bitstring offset bs) in + let (cut, _) = (Utility.partition_bitstring size relevant) in + read_elf32_symbol_table_entries cut >>= (fun head -> + read_elf32_symbol_tables' xs bs >>= (fun tail -> + return (head::tail))) + )) + +type elf32_symbol_table = elf32_symbol_table_entry list + +let read_elf32_symbol_tables sections bs : ( elf32_symbol_table list) error = +(let symtabs = (List.filter (fun sect -> + (Int64.to_int sect.elf32_sh_type = sht_symtab) || + (Int64.to_int sect.elf32_sh_type = sht_dynsym)) sections) + in + let _ = (print_endline ("Symtabs: " ^ natShow (List.length symtabs))) in + let offsets_sizes = (List.map (fun sect -> + let offset = ((Int64.to_int sect.elf32_sh_offset) * 8) in + let size = +(let _ = (print_endline ("YYY size: " ^ natShow (Int64.to_int sect.elf32_sh_size * 8))) in + Int64.to_int sect.elf32_sh_size * 8) + in + (offset, size)) symtabs) + in + read_elf32_symbol_tables' offsets_sizes bs) + +let string_of_elf32_symbol_table tbl = +("Symbol table contents:" ^ ("\n" ^ + List.fold_right (^) (List.map string_of_elf32_symbol_table_entry tbl) "")) |
