summaryrefslogtreecommitdiff
path: root/checklink/ELF_utils.ml
diff options
context:
space:
mode:
authorGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-03-28 13:32:21 +0000
committerGravatar xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2012-03-28 13:32:21 +0000
commitbefbc76f89f3d8abc8da17caf91ea4a87ec96eeb (patch)
treed84d76258ca9b2505713552bb62be8c40714787b /checklink/ELF_utils.ml
parent26c166e279ec05837b6b3b5db80a7ef3c520db32 (diff)
checklink: first import of Valentin Robert's validator for asm and link
cparser: renamed Errors to Cerrors; removed packing into Cparser. git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1856 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'checklink/ELF_utils.ml')
-rw-r--r--checklink/ELF_utils.ml85
1 files changed, 85 insertions, 0 deletions
diff --git a/checklink/ELF_utils.ml b/checklink/ELF_utils.ml
new file mode 100644
index 0000000..f860e3f
--- /dev/null
+++ b/checklink/ELF_utils.ml
@@ -0,0 +1,85 @@
+open ELF_types
+open Library
+
+let section_ndx_by_name_noelf (eshdra: elf32_shdr array)(name: string): int =
+ match array_exists (fun eshdr -> eshdr.sh_name = name) eshdra with
+ | Some sndx -> sndx
+ | None -> assert false
+
+let section_ndx_by_name (e: elf)(name: string): int option =
+ array_exists (fun eshdr -> eshdr.sh_name = name) e.e_shdra
+
+let section_bitstring_noelf
+ (bs: bitstring)(eshdra: elf32_shdr array)(sndx: int): bitstring =
+ let sofs = int32_int eshdra.(sndx).sh_offset in
+ let size = int32_int eshdra.(sndx).sh_size in
+ Bitstring.subbitstring bs (sofs * 8) (size * 8)
+
+let section_bitstring (e: elf): int -> bitstring =
+ section_bitstring_noelf e.e_bitstring e.e_shdra
+
+let physical_offset_of_vaddr (e: elf)(sndx: int)(vaddr: int32): int32 =
+ let shdr = e.e_shdra.(sndx) in
+ Int32.(add shdr.sh_offset (sub vaddr shdr.sh_addr))
+
+let section_at_vaddr (e: elf)(vaddr: int32): int option =
+ array_exists
+ (fun shdr ->
+ shdr.sh_addr <= vaddr && vaddr < Int32.add shdr.sh_addr shdr.sh_size
+ )
+ e.e_shdra
+
+(**
+ Returns the entire bitstring that begins at the specified virtual address
+ within the specified section and ends at the end of the file. This is useful
+ when you don't know the sections size yet.
+*)
+let bitstring_at_vaddr_nosize (e: elf)(sndx: int)(vaddr: int32): bitstring =
+ let shdr = e.e_shdra.(sndx) in
+ let bs = section_bitstring e sndx in
+ let ofs = int32_int (Int32.sub vaddr shdr.sh_addr) in
+ bitmatch bs with
+ | { subbs : -1 : bitstring, offset(8*ofs) } -> subbs
+
+(**
+ Returns the bitstring of the specified size beginning at the specified
+ virtual address within the specified section.
+*)
+let bitstring_at_vaddr e sndx vaddr size =
+ let shdr = e.e_shdra.(sndx) in
+ let bs = section_bitstring e sndx in
+ let ofs = int32_int (Int32.sub vaddr shdr.sh_addr) in
+ bitmatch bs with
+ | { subbs : size : bitstring, offset(8*ofs) } -> subbs
+
+(**
+ Removes symbol version for GCC's symbols.
+*)
+let strip_versioning (s: string): string =
+ try String.sub s 0 (String.index s '@')
+ with Not_found -> s
+
+(**
+ Removes CompCert's mangling of variadic functions
+*)
+let strip_mangling (s: string): string =
+ try String.sub s 0 (String.index s '$')
+ with Not_found -> s
+
+(**
+ Returns the index of the first symbol matching the specified name, if it
+ exists.
+*)
+let ndx_of_sym_name (e: elf) (name: string): int option =
+ array_exists
+ (fun x -> strip_versioning x.st_name = strip_mangling name)
+ e.e_symtab
+
+(**
+ Returns the list of all symbols matching the specified name.
+*)
+let ndxes_of_sym_name (e: elf) (name: string): int list =
+ List.map fst
+ (List.filter
+ (fun (_, x) -> strip_versioning x.st_name = strip_mangling name)
+ (Array.to_list (Array.mapi (fun a b -> (a, b)) e.e_symtab)))