1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135(*Generated by Lem from elf_section_header_table.lem.*)(** [elf_section_header_table] provides types, functions and other definitions
* for working with section header tables and their entries.
*)openLem_basic_classesopenLem_boolopenLem_functionopenLem_listopenLem_mapopenLem_maybeopenLem_numopenLem_stringopenByte_sequenceopenErroropenMissing_pervasivesopenShowopenEndiannessopenString_tableopenElf_headeropenElf_types_native_uintopenElf_program_header_table(** Special section indices. *)(** See elf_header.lem for shn_undef *)(** [shn_loreserve]: this specifies the lower bound of the range of reserved
* indices.
*)letshn_loreserve:Nat_big_num.num=((Nat_big_num.of_int65280))(* 0xff00 *)(** [shn_loproc]: start of the range reserved for processor-specific semantics.
*)letshn_loproc:Nat_big_num.num=((Nat_big_num.of_int65280))(* 0xff00 *)(** [shn_hiproc]: end of the range reserved for processor-specific semantics.
*)letshn_hiproc:Nat_big_num.num=((Nat_big_num.of_int65311))(* 0xff1f *)(** [shn_loos]: start of the range reserved for operating system-specific
* semantics.
*)letshn_loos:Nat_big_num.num=((Nat_big_num.of_int65312))(* 0xff20 *)(** [shn_hios]: end of the range reserved for operating system-specific
* semantics.
*)letshn_hios:Nat_big_num.num=((Nat_big_num.of_int65343))(* 0xff3f *)(** [shn_abs]: specifies the absolute values for the corresponding reference.
* Symbols defined relative to section number [shn_abs] have absolute values
* and are not affected by relocation.
*)letshn_abs:Nat_big_num.num=((Nat_big_num.of_int65521))(* 0xfff1 *)(** [shn_common]: symbols defined relative to this index are common symbols,
* such as unallocated C external variables.
*)letshn_common:Nat_big_num.num=((Nat_big_num.of_int65522))(* 0xfff2 *)(** See elf_header.lem for shn_xindex. *)(** [shn_hireserve]: specifies the upper-bound of reserved values.
*)letshn_hireserve:Nat_big_num.num=((Nat_big_num.of_int65535))(* 0xffff *)(** [string_of_special_section_index m] produces a string-based representation
* of a section header entry's special section index, [m].
*)(*val string_of_special_section_index : natural -> string*)letstring_of_special_section_indexi:string=(ifNat_big_num.equalishn_undefthen"SHN_UNDEF"elseifNat_big_num.equalishn_loreservethen"SHN_LORESERVE"elseifNat_big_num.greater_equalishn_loproc&&Nat_big_num.less_equalishn_hiprocthen"SHN_PROCESSOR_SPECIFIC"elseifNat_big_num.greater_equalishn_loos&&Nat_big_num.less_equalishn_hiosthen"SHN_OS_SPECIFIC"elseifNat_big_num.equalishn_absthen"SHN_ABS"elseifNat_big_num.equalishn_commonthen"SHN_COMMON"elseifNat_big_num.equalishn_xindexthen"SHN_XINDEX"elseifNat_big_num.equalishn_hireservethen"SHN_HIRESERVE"else"SHN UNDEFINED")(** Section types. *)(** Marks the section header as being inactive. *)letsht_null:Nat_big_num.num=((Nat_big_num.of_int0))(** Section holds information defined by the program. *)letsht_progbits:Nat_big_num.num=((Nat_big_num.of_int1))(** The following two section types hold a symbol table. An object file may only
* have one symbol table of each of the respective types. The symtab provides
* a place for link editing, whereas the dynsym section holds a minimal set of
* dynamic linking symbols
*)letsht_symtab:Nat_big_num.num=((Nat_big_num.of_int2))letsht_dynsym:Nat_big_num.num=((Nat_big_num.of_int11))(** Section holds a string table *)letsht_strtab:Nat_big_num.num=((Nat_big_num.of_int3))(** Section holds relocation entries with explicit addends. An object file may
* have multiple section of this type.
*)letsht_rela:Nat_big_num.num=((Nat_big_num.of_int4))(** Section holds a symbol hash table. An object file may only have a single
* hash table.
*)letsht_hash:Nat_big_num.num=((Nat_big_num.of_int5))(** Section holds information for dynamic linking. An object file may only have
* a single dynamic section.
*)letsht_dynamic:Nat_big_num.num=((Nat_big_num.of_int6))(** Section holds information that marks the file in some way. *)letsht_note:Nat_big_num.num=((Nat_big_num.of_int7))(** Section occupies no space in the file but otherwise resembles a progbits
* section.
*)letsht_nobits:Nat_big_num.num=((Nat_big_num.of_int8))(** Section holds relocation entries without explicit addends. An object file
* may have multiple section of this type.
*)letsht_rel:Nat_big_num.num=((Nat_big_num.of_int9))(** Section type is reserved but has an unspecified meaning. *)letsht_shlib:Nat_big_num.num=((Nat_big_num.of_int10))(** Section contains an array of pointers to initialisation functions. Each
* pointer is taken as a parameterless function with a void return type.
*)letsht_init_array:Nat_big_num.num=((Nat_big_num.of_int14))(** Section contains an array of pointers to termination functions. Each
* pointer is taken as a parameterless function with a void return type.
*)letsht_fini_array:Nat_big_num.num=((Nat_big_num.of_int15))(** Section contains an array of pointers to initialisation functions that are
* invoked before all other initialisation functions. Each
* pointer is taken as a parameterless function with a void return type.
*)letsht_preinit_array:Nat_big_num.num=((Nat_big_num.of_int16))(** Section defines a section group, i.e. a set of sections that are related and
* must be treated especially by the linker. May only appear in relocatable
* objects.
*)letsht_group:Nat_big_num.num=((Nat_big_num.of_int17))(** Section is associated with sections of type SHT_SYMTAB and is required if
* any of the section header indices referenced by that symbol table contains
* the escape value SHN_XINDEX.
*
* FIXME: Lem bug as [int] type used throughout Lem codebase, rather than
* [BigInt.t], so Lem chokes on these large constants below, hence the weird
* way in which they are written.
*)letsht_symtab_shndx:Nat_big_num.num=((Nat_big_num.of_int18))(** The following ranges are reserved solely for OS-, processor- and user-
* specific semantics, respectively.
*)letsht_loos:Nat_big_num.num=(Nat_big_num.mul(Nat_big_num.mul(Nat_big_num.mul((Nat_big_num.of_int3))((Nat_big_num.of_int1024)))((Nat_big_num.of_int1024)))((Nat_big_num.of_int512)))(* 1610612736 (* 0x60000000 *) *)letsht_hios:Nat_big_num.num=(Nat_big_num.add(Nat_big_num.mul((Nat_big_num.of_int469762047))((Nat_big_num.of_int4)))((Nat_big_num.of_int3)))(* 1879048191 (* 0x6fffffff *) *)letsht_loproc:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int469762048))((Nat_big_num.of_int4)))(* 1879048192 (* 0x70000000 *) *)letsht_hiproc:Nat_big_num.num=(Nat_big_num.add(Nat_big_num.mul((Nat_big_num.of_int536870911))((Nat_big_num.of_int4)))((Nat_big_num.of_int3)))(* 2147483647 (* 0x7fffffff *) *)letsht_louser:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int536870912))((Nat_big_num.of_int4)))(* 2147483648 (* 0x80000000 *) *)letsht_hiuser:Nat_big_num.num=(Nat_big_num.add(Nat_big_num.mul((Nat_big_num.of_int603979775))((Nat_big_num.of_int4)))((Nat_big_num.of_int3)))(* 2415919103 (* 0x8fffffff *) *)(** [string_of_section_type os proc user i] produces a string-based representation
* of section type [i]. Some section types are defined by ABI-specific supplements
* in reserved ranges, in which case the functions [os], [proc] and [user] are
* used to produce the string.
*)(*val string_of_section_type : (natural -> string) -> (natural -> string) ->
(natural -> string) -> natural -> string*)letstring_of_section_typeosprocuseri:string=(ifNat_big_num.equalisht_nullthen"NULL"elseifNat_big_num.equalisht_progbitsthen"PROGBITS"elseifNat_big_num.equalisht_symtabthen"SYMTAB"elseifNat_big_num.equalisht_strtabthen"STRTAB"elseifNat_big_num.equalisht_relathen"RELA"elseifNat_big_num.equalisht_hashthen"HASH"elseifNat_big_num.equalisht_dynamicthen"DYNAMIC"elseifNat_big_num.equalisht_notethen"NOTE"elseifNat_big_num.equalisht_nobitsthen"NOBITS"elseifNat_big_num.equalisht_relthen"REL"elseifNat_big_num.equalisht_shlibthen"SHLIB"elseifNat_big_num.equalisht_dynsymthen"DYNSYM"elseifNat_big_num.equalisht_init_arraythen"INIT_ARRAY"elseifNat_big_num.equalisht_fini_arraythen"FINI_ARRAY"elseifNat_big_num.equalisht_preinit_arraythen"PREINIT_ARRAY"elseifNat_big_num.equalisht_groupthen"GROUP"elseifNat_big_num.equalisht_symtab_shndxthen"SYMTAB_SHNDX"elseifNat_big_num.greater_equalisht_loos&&Nat_big_num.less_equalisht_hiosthenosielseifNat_big_num.greater_equalisht_loproc&&Nat_big_num.less_equalisht_hiprocthenprocielseifNat_big_num.greater_equalisht_louser&&Nat_big_num.less_equalisht_hiuserthenuserielse"Undefined or invalid section type")(** Section flag numeric values. *)(** The section contains data that should be writable during program execution.
*)letshf_write:Nat_big_num.num=((Nat_big_num.of_int1))(** The section occupies memory during program execution.
*)letshf_alloc:Nat_big_num.num=((Nat_big_num.of_int2))(** The section contains executable instructions.
*)letshf_execinstr:Nat_big_num.num=((Nat_big_num.of_int4))(** The data in the section may be merged to reduce duplication. Each section
* is compared based on name, type and flags set with sections with identical
* values at run time being mergeable.
*)letshf_merge:Nat_big_num.num=((Nat_big_num.of_int16))(** The section contains null-terminated character strings.
*)letshf_strings:Nat_big_num.num=((Nat_big_num.of_int32))(** The [info] field of this section header contains a section header table
* index.
*)letshf_info_link:Nat_big_num.num=((Nat_big_num.of_int64))(** Adds special link ordering for link editors.
*)letshf_link_order:Nat_big_num.num=((Nat_big_num.of_int128))(** This section requires special OS-specific processing beyond the standard
* link rules.
*)letshf_os_nonconforming:Nat_big_num.num=((Nat_big_num.of_int256))(** This section is a member (potentially the only member) of a link group.
*)letshf_group:Nat_big_num.num=((Nat_big_num.of_int512))(** This section contains Thread Local Storage (TLS) meaning that each thread of
* execution has its own instance of this data.
*)letshf_tls:Nat_big_num.num=((Nat_big_num.of_int1024))(** This section contains compressed data. Compressed data may not be marked as
* allocatable.
*)letshf_compressed:Nat_big_num.num=((Nat_big_num.of_int2048))(** All bits included in these masks are reserved for OS and processor specific
* semantics respectively.
*)letshf_mask_os:Nat_big_num.num=((Nat_big_num.of_int267386880))(* 0x0ff00000 *)letshf_mask_proc:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int4))((Nat_big_num.of_int1006632960)))(* 0xf0000000 *)(** [string_of_section_flags os proc f] produces a string based representation
* of section flag [f]. Some section flags are defined by the ABI and are in
* reserved ranges, in which case the flag string is produced by functions
* [os] and [proc].
* TODO: add more as validation tests require them.
*)(*val string_of_section_flags : (natural -> string) -> (natural -> string) ->
natural -> string*)letstring_of_section_flagsosprocf:string=(ifNat_big_num.equalfshf_writethen"W"elseifNat_big_num.equalfshf_allocthen" A"elseifNat_big_num.equalfshf_execinstrthen" X"elseifNat_big_num.equalf(Nat_big_num.addshf_allocshf_execinstr)then" AX"elseifNat_big_num.equalf(Nat_big_num.addshf_writeshf_alloc)then" WA"elseifNat_big_num.equalfshf_mergethen" M "elseifNat_big_num.equalf(Nat_big_num.addshf_mergeshf_alloc)then" AM"elseifNat_big_num.equalf(Nat_big_num.add(Nat_big_num.addshf_mergeshf_alloc)shf_strings)then"AMS"elseifNat_big_num.equalf(Nat_big_num.add(Nat_big_num.addshf_allocshf_execinstr)shf_group)then"AXG"elseifNat_big_num.equalfshf_stringsthen" S"elseifNat_big_num.equalf(Nat_big_num.addshf_mergeshf_strings)then" MS"elseifNat_big_num.equalfshf_tlsthen" T"elseifNat_big_num.equalf(Nat_big_num.addshf_tlsshf_alloc)then" AT"elseifNat_big_num.equalf(Nat_big_num.add(Nat_big_num.addshf_writeshf_alloc)shf_tls)then"WAT"elseifNat_big_num.equalfshf_info_linkthen" I"elseifNat_big_num.equalf(Nat_big_num.addshf_allocshf_info_link)then" AI"else" ")(** Section compression. *)(** Type [elf32_compression_header] provides information about the compression and
* decompression of compressed sections. All compressed sections on ELF32 begin
* with an [elf32_compression_header] entry.
*)typeelf32_compression_header={elf32_chdr_type:Uint32_wrapper.uint32(** Specifies the compression algorithm *);elf32_chdr_size:Uint32_wrapper.uint32(** Size in bytes of the uncompressed data *);elf32_chdr_addralign:Uint32_wrapper.uint32(** Specifies the required alignment of the uncompressed data *)}(** Type [elf64_compression_header] provides information about the compression and
* decompression of compressed sections. All compressed sections on ELF64 begin
* with an [elf64_compression_header] entry.
*)typeelf64_compression_header={elf64_chdr_type:Uint32_wrapper.uint32(** Specified the compression algorithm *);elf64_chdr_reserved:Uint32_wrapper.uint32(** Reserved. *);elf64_chdr_size:Uint64_wrapper.uint64(** Size in bytes of the uncompressed data *);elf64_chdr_addralign:Uint64_wrapper.uint64(** Specifies the required alignment of the uncompressed data *)}(** This section is compressed with the ZLIB algorithm. The compressed data begins
* at the first byte immediately following the end of the compression header.
*)letelfcompress_zlib:Nat_big_num.num=((Nat_big_num.of_int1))(** Values in these ranges are reserved for OS-specific semantics.
*)letelfcompress_loos:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int4))((Nat_big_num.of_int402653184)))(* 0x60000000 *)letelfcompress_hios:Nat_big_num.num=(Nat_big_num.add(Nat_big_num.mul((Nat_big_num.of_int2))((Nat_big_num.of_int939524095)))((Nat_big_num.of_int1)))(* 0x6fffffff *)(** Values in these ranges are reserved for processor-specific semantics.
*)letelfcompress_loproc:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int4))((Nat_big_num.of_int469762048)))(* 0x70000000 *)letelfcompress_hiproc:Nat_big_num.num=(Nat_big_num.add(Nat_big_num.mul((Nat_big_num.of_int2))((Nat_big_num.of_int1073741823)))((Nat_big_num.of_int1)))(* 0x7fffffff *)(** [read_elf32_compression_header ed bs0] reads an [elf32_compression_header]
* entry from byte sequence [bs0], interpreting [bs0] with endianness [ed].
* Also returns the suffix of [bs0] after reading in the compression header.
* Fails if the header cannot be read.
*)(*val read_elf32_compression_header : endianness -> byte_sequence ->
error (elf32_compression_header * byte_sequence)*)letread_elf32_compression_headeredbs0:(elf32_compression_header*Byte_sequence_wrapper.byte_sequence)error=(bind(read_elf32_wordedbs0)(fun(typ,bs1)->bind(read_elf32_wordedbs1)(fun(siz,bs2)->bind(read_elf32_wordedbs2)(fun(ali,bs3)->return({elf32_chdr_type=typ;elf32_chdr_size=siz;elf32_chdr_addralign=ali},bs3)))))(** [read_elf64_compression_header ed bs0] reads an [elf64_compression_header]
* entry from byte sequence [bs0], interpreting [bs0] with endianness [ed].
* Also returns the suffix of [bs0] after reading in the compression header.
* Fails if the header cannot be read.
*)(*val read_elf64_compression_header : endianness -> byte_sequence ->
error (elf64_compression_header * byte_sequence)*)letread_elf64_compression_headeredbs0:(elf64_compression_header*Byte_sequence_wrapper.byte_sequence)error=(bind(read_elf64_wordedbs0)(fun(typ,bs1)->bind(read_elf64_wordedbs1)(fun(res,bs2)->bind(read_elf64_xwordedbs2)(fun(siz,bs3)->bind(read_elf64_xwordedbs3)(fun(ali,bs4)->return({elf64_chdr_type=typ;elf64_chdr_reserved=res;elf64_chdr_size=siz;elf64_chdr_addralign=ali},bs4))))))(** Section header table entry type. *)(** [elf32_section_header_table_entry] is the type of entries in the section
* header table in 32-bit ELF files. Each entry in the table details a section
* in the body of the ELF file.
*)typeelf32_section_header_table_entry={elf32_sh_name:Uint32_wrapper.uint32(** Name of the section *);elf32_sh_type:Uint32_wrapper.uint32(** Type of the section and its semantics *);elf32_sh_flags:Uint32_wrapper.uint32(** Flags associated with the section *);elf32_sh_addr:Uint32_wrapper.uint32(** Address of first byte of section in memory image *);elf32_sh_offset:Uint32_wrapper.uint32(** Offset from beginning of file of first byte of section *);elf32_sh_size:Uint32_wrapper.uint32(** Section size in bytes *);elf32_sh_link:Uint32_wrapper.uint32(** Section header table index link *);elf32_sh_info:Uint32_wrapper.uint32(** Extra information, contents depends on type of section *);elf32_sh_addralign:Uint32_wrapper.uint32(** Alignment constraints for section *);elf32_sh_entsize:Uint32_wrapper.uint32(** Size of each entry in table, if section is one *)}letelf32_null_section_header:elf32_section_header_table_entry=({elf32_sh_name=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_type=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_flags=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_addr=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_offset=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_size=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_link=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_info=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_addralign=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf32_sh_entsize=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)))})(** [compare_elf32_section_header_table_entry ent1 ent2] is an ordering comparison
* function on section header table entries suitable for use in constructing
* sets, finite maps and other ordered data types.
*)(*val compare_elf32_section_header_table_entry : elf32_section_header_table_entry ->
elf32_section_header_table_entry -> ordering*)letcompare_elf32_section_header_table_entryh1h2:int=(lexicographic_compareNat_big_num.compare[Uint32_wrapper.to_biginth1.elf32_sh_name;Uint32_wrapper.to_biginth1.elf32_sh_type;Uint32_wrapper.to_biginth1.elf32_sh_flags;Uint32_wrapper.to_biginth1.elf32_sh_addr;Uint32_wrapper.to_biginth1.elf32_sh_offset;Uint32_wrapper.to_biginth1.elf32_sh_size;Uint32_wrapper.to_biginth1.elf32_sh_link;Uint32_wrapper.to_biginth1.elf32_sh_info;Uint32_wrapper.to_biginth1.elf32_sh_addralign;Uint32_wrapper.to_biginth1.elf32_sh_entsize][Uint32_wrapper.to_biginth2.elf32_sh_name;Uint32_wrapper.to_biginth2.elf32_sh_type;Uint32_wrapper.to_biginth2.elf32_sh_flags;Uint32_wrapper.to_biginth2.elf32_sh_addr;Uint32_wrapper.to_biginth2.elf32_sh_offset;Uint32_wrapper.to_biginth2.elf32_sh_size;Uint32_wrapper.to_biginth2.elf32_sh_link;Uint32_wrapper.to_biginth2.elf32_sh_info;Uint32_wrapper.to_biginth2.elf32_sh_addralign;Uint32_wrapper.to_biginth2.elf32_sh_entsize])letinstance_Basic_classes_Ord_Elf_section_header_table_elf32_section_header_table_entry_dict:(elf32_section_header_table_entry)ord_class=({compare_method=compare_elf32_section_header_table_entry;isLess_method=(funf1->(funf2->(Lem.orderingEqual(compare_elf32_section_header_table_entryf1f2)(-1))));isLessEqual_method=(funf1->(funf2->Pset.mem(compare_elf32_section_header_table_entryf1f2)(Pset.from_listcompare[(-1);0])));isGreater_method=(funf1->(funf2->(Lem.orderingEqual(compare_elf32_section_header_table_entryf1f2)1)));isGreaterEqual_method=(funf1->(funf2->Pset.mem(compare_elf32_section_header_table_entryf1f2)(Pset.from_listcompare[1;0])))})(** [elf64_section_header_table_entry] is the type of entries in the section
* header table in 64-bit ELF files. Each entry in the table details a section
* in the body of the ELF file.
*)typeelf64_section_header_table_entry={elf64_sh_name:Uint32_wrapper.uint32(** Name of the section *);elf64_sh_type:Uint32_wrapper.uint32(** Type of the section and its semantics *);elf64_sh_flags:Uint64_wrapper.uint64(** Flags associated with the section *);elf64_sh_addr:Uint64_wrapper.uint64(** Address of first byte of section in memory image *);elf64_sh_offset:Uint64_wrapper.uint64(** Offset from beginning of file of first byte of section *);elf64_sh_size:Uint64_wrapper.uint64(** Section size in bytes *);elf64_sh_link:Uint32_wrapper.uint32(** Section header table index link *);elf64_sh_info:Uint32_wrapper.uint32(** Extra information, contents depends on type of section *);elf64_sh_addralign:Uint64_wrapper.uint64(** Alignment constraints for section *);elf64_sh_entsize:Uint64_wrapper.uint64(** Size of each entry in table, if section is one *)}letelf64_null_section_header:elf64_section_header_table_entry=({elf64_sh_name=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_type=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_flags=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_addr=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_offset=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_size=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_link=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_info=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_addralign=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)));elf64_sh_entsize=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0)))})(** [compare_elf64_section_header_table_entry ent1 ent2] is an ordering comparison
* function on section header table entries suitable for use in constructing
* sets, finite maps and other ordered data types.
*)(*val compare_elf64_section_header_table_entry : elf64_section_header_table_entry ->
elf64_section_header_table_entry -> ordering*)letcompare_elf64_section_header_table_entryh1h2:int=(lexicographic_compareNat_big_num.compare[Uint32_wrapper.to_biginth1.elf64_sh_name;Uint32_wrapper.to_biginth1.elf64_sh_type;Ml_bindings.nat_big_num_of_uint64h1.elf64_sh_flags;Ml_bindings.nat_big_num_of_uint64h1.elf64_sh_addr;Uint64_wrapper.to_biginth1.elf64_sh_offset;Ml_bindings.nat_big_num_of_uint64h1.elf64_sh_size;Uint32_wrapper.to_biginth1.elf64_sh_link;Uint32_wrapper.to_biginth1.elf64_sh_info;Ml_bindings.nat_big_num_of_uint64h1.elf64_sh_addralign;Ml_bindings.nat_big_num_of_uint64h1.elf64_sh_entsize][Uint32_wrapper.to_biginth2.elf64_sh_name;Uint32_wrapper.to_biginth2.elf64_sh_type;Ml_bindings.nat_big_num_of_uint64h2.elf64_sh_flags;Ml_bindings.nat_big_num_of_uint64h2.elf64_sh_addr;Uint64_wrapper.to_biginth2.elf64_sh_offset;Ml_bindings.nat_big_num_of_uint64h2.elf64_sh_size;Uint32_wrapper.to_biginth2.elf64_sh_link;Uint32_wrapper.to_biginth2.elf64_sh_info;Ml_bindings.nat_big_num_of_uint64h2.elf64_sh_addralign;Ml_bindings.nat_big_num_of_uint64h2.elf64_sh_entsize])letinstance_Basic_classes_Ord_Elf_section_header_table_elf64_section_header_table_entry_dict:(elf64_section_header_table_entry)ord_class=({compare_method=compare_elf64_section_header_table_entry;isLess_method=(funf1->(funf2->(Lem.orderingEqual(compare_elf64_section_header_table_entryf1f2)(-1))));isLessEqual_method=(funf1->(funf2->Pset.mem(compare_elf64_section_header_table_entryf1f2)(Pset.from_listcompare[(-1);0])));isGreater_method=(funf1->(funf2->(Lem.orderingEqual(compare_elf64_section_header_table_entryf1f2)1)));isGreaterEqual_method=(funf1->(funf2->Pset.mem(compare_elf64_section_header_table_entryf1f2)(Pset.from_listcompare[1;0])))})(** Section header table type *)(** Type [elf32_section_header_table] represents a section header table for 32-bit
* ELF files. A section header table is an array (implemented as a list, here)
* of section header table entries.
*)typeelf32_section_header_table=elf32_section_header_table_entrylist(** Type [elf64_section_header_table] represents a section header table for 64-bit
* ELF files. A section header table is an array (implemented as a list, here)
* of section header table entries.
*)typeelf64_section_header_table=elf64_section_header_table_entrylist(** Parsing and blitting *)(** [bytes_of_elf32_section_header_table_entry ed ent] blits [ent] to a byte sequence
* assuming endianness [ed].
*)(*val bytes_of_elf32_section_header_table_entry : endianness ->
elf32_section_header_table_entry -> byte_sequence*)letbytes_of_elf32_section_header_table_entryendianentry:Byte_sequence_wrapper.byte_sequence=(Byte_sequence.from_byte_lists[bytes_of_elf32_wordendianentry.elf32_sh_name;bytes_of_elf32_wordendianentry.elf32_sh_type;bytes_of_elf32_wordendianentry.elf32_sh_flags;bytes_of_elf32_addrendianentry.elf32_sh_addr;bytes_of_elf32_offendianentry.elf32_sh_offset;bytes_of_elf32_wordendianentry.elf32_sh_size;bytes_of_elf32_wordendianentry.elf32_sh_link;bytes_of_elf32_wordendianentry.elf32_sh_info;bytes_of_elf32_wordendianentry.elf32_sh_addralign;bytes_of_elf32_wordendianentry.elf32_sh_entsize])(** [read_elf32_section_header_table_entry ed bs0] reads a section header table
* entry from [bs0] assuming endianness [ed]. Also returns the suffix of [bs0]
* after parsing. Fails if the entry cannot be read.
*)(*val read_elf32_section_header_table_entry : endianness -> byte_sequence ->
error (elf32_section_header_table_entry * byte_sequence)*)letread_elf32_section_header_table_entryendianbs:(elf32_section_header_table_entry*Byte_sequence_wrapper.byte_sequence)error=(bind(read_elf32_wordendianbs)(fun(sh_name,bs)->bind(read_elf32_wordendianbs)(fun(sh_type,bs)->bind(read_elf32_wordendianbs)(fun(sh_flags,bs)->bind(read_elf32_addrendianbs)(fun(sh_addr,bs)->bind(read_elf32_offendianbs)(fun(sh_offset,bs)->bind(read_elf32_wordendianbs)(fun(sh_size,bs)->bind(read_elf32_wordendianbs)(fun(sh_link,bs)->bind(read_elf32_wordendianbs)(fun(sh_info,bs)->bind(read_elf32_wordendianbs)(fun(sh_addralign,bs)->bind(read_elf32_wordendianbs)(fun(sh_entsize,bs)->return({elf32_sh_name=sh_name;elf32_sh_type=sh_type;elf32_sh_flags=sh_flags;elf32_sh_addr=sh_addr;elf32_sh_offset=sh_offset;elf32_sh_size=sh_size;elf32_sh_link=sh_link;elf32_sh_info=sh_info;elf32_sh_addralign=sh_addralign;elf32_sh_entsize=sh_entsize},bs))))))))))))(** [bytes_of_elf64_section_header_table_entry ed ent] blits [ent] to a byte sequence
* assuming endianness [ed].
*)(*val bytes_of_elf64_section_header_table_entry : endianness ->
elf64_section_header_table_entry -> byte_sequence*)letbytes_of_elf64_section_header_table_entryendianentry:Byte_sequence_wrapper.byte_sequence=(Byte_sequence.from_byte_lists[bytes_of_elf64_wordendianentry.elf64_sh_name;bytes_of_elf64_wordendianentry.elf64_sh_type;bytes_of_elf64_xwordendianentry.elf64_sh_flags;bytes_of_elf64_addrendianentry.elf64_sh_addr;bytes_of_elf64_offendianentry.elf64_sh_offset;bytes_of_elf64_xwordendianentry.elf64_sh_size;bytes_of_elf64_wordendianentry.elf64_sh_link;bytes_of_elf64_wordendianentry.elf64_sh_info;bytes_of_elf64_xwordendianentry.elf64_sh_addralign;bytes_of_elf64_xwordendianentry.elf64_sh_entsize])(** [read_elf64_section_header_table_entry ed bs0] reads a section header table
* entry from [bs0] assuming endianness [ed]. Also returns the suffix of [bs0]
* after parsing. Fails if the entry cannot be read.
*)(*val read_elf64_section_header_table_entry : endianness -> byte_sequence ->
error (elf64_section_header_table_entry * byte_sequence)*)letread_elf64_section_header_table_entryendianbs:(elf64_section_header_table_entry*Byte_sequence_wrapper.byte_sequence)error=(bind(read_elf64_wordendianbs)(fun(sh_name,bs)->bind(read_elf64_wordendianbs)(fun(sh_type,bs)->bind(read_elf64_xwordendianbs)(fun(sh_flags,bs)->bind(read_elf64_addrendianbs)(fun(sh_addr,bs)->bind(read_elf64_offendianbs)(fun(sh_offset,bs)->bind(read_elf64_xwordendianbs)(fun(sh_size,bs)->bind(read_elf64_wordendianbs)(fun(sh_link,bs)->bind(read_elf64_wordendianbs)(fun(sh_info,bs)->bind(read_elf64_xwordendianbs)(fun(sh_addralign,bs)->bind(read_elf64_xwordendianbs)(fun(sh_entsize,bs)->return({elf64_sh_name=sh_name;elf64_sh_type=sh_type;elf64_sh_flags=sh_flags;elf64_sh_addr=sh_addr;elf64_sh_offset=sh_offset;elf64_sh_size=sh_size;elf64_sh_link=sh_link;elf64_sh_info=sh_info;elf64_sh_addralign=sh_addralign;elf64_sh_entsize=sh_entsize},bs))))))))))))(** [bytes_of_elf32_section_header_table ed tbl] blits section header table [tbl]
* to a byte sequence assuming endianness [ed].
*)(*val bytes_of_elf32_section_header_table : endianness ->
elf32_section_header_table -> byte_sequence*)letbytes_of_elf32_section_header_tableendiantbl:Byte_sequence_wrapper.byte_sequence=(Byte_sequence.concat(Lem_list.map(bytes_of_elf32_section_header_table_entryendian)tbl))(** [bytes_of_elf64_section_header_table ed tbl] blits section header table [tbl]
* to a byte sequence assuming endianness [ed].
*)(*val bytes_of_elf64_section_header_table : endianness ->
elf64_section_header_table -> byte_sequence*)letbytes_of_elf64_section_header_tableendiantbl:Byte_sequence_wrapper.byte_sequence=(Byte_sequence.concat(Lem_list.map(bytes_of_elf64_section_header_table_entryendian)tbl))(** [read_elf32_section_header_table' ed bs0] parses an ELF32 section header table
* from byte sequence [bs0] assuming endianness [ed]. Assumes [bs0] is of the
* exact length required to parse the entire table.
* Fails if any of the section header table entries cannot be parsed.
*)(*val read_elf32_section_header_table' : endianness -> byte_sequence ->
error elf32_section_header_table*)letrecread_elf32_section_header_table'endianbs0:((elf32_section_header_table_entry)list)error=(ifNat_big_num.equal(Byte_sequence.length0bs0)((Nat_big_num.of_int0))thenreturn[]elsebind(read_elf32_section_header_table_entryendianbs0)(fun(entry,bs1)->bind(read_elf32_section_header_table'endianbs1)(funsht->return(entry::sht))))(** [read_elf64_section_header_table' ed bs0] parses an ELF64 section header table
* from byte sequence [bs0] assuming endianness [ed]. Assumes [bs0] is of the
* exact length required to parse the entire table.
* Fails if any of the section header table entries cannot be parsed.
*)(*val read_elf64_section_header_table' : endianness -> byte_sequence ->
error elf64_section_header_table*)letrecread_elf64_section_header_table'endianbs0:((elf64_section_header_table_entry)list)error=(ifNat_big_num.equal(Byte_sequence.length0bs0)((Nat_big_num.of_int0))thenreturn[]elsebind(read_elf64_section_header_table_entryendianbs0)(fun(entry,bs1)->bind(read_elf64_section_header_table'endianbs1)(funsht->return(entry::sht))))(** [read_elf32_section_header_table sz ed bs0] parses an ELF32 section header
* table from a [sz] sized prefix of byte sequence [bs0] assuming endianness
* [ed]. The suffix of [bs0] remaining after parsing is also returned.
* Fails if any of the section header entries cannot be parsed or if [sz] is
* greater than the length of [bs0].
*)(*val read_elf32_section_header_table : natural -> endianness -> byte_sequence ->
error (elf32_section_header_table * byte_sequence)*)letread_elf32_section_header_tabletable_sizeendianbs0:((elf32_section_header_table_entry)list*Byte_sequence_wrapper.byte_sequence)error=(bind(partition0table_sizebs0)(fun(eat,rest)->bind(read_elf32_section_header_table'endianeat)(funentries->return(entries,rest))))(** [read_elf64_section_header_table sz ed bs0] parses an ELF64 section header
* table from a [sz] sized prefix of byte sequence [bs0] assuming endianness
* [ed]. The suffix of [bs0] remaining after parsing is also returned.
* Fails if any of the section header entries cannot be parsed or if [sz] is
* greater than the length of [bs0].
*)(*val read_elf64_section_header_table : natural -> endianness -> byte_sequence ->
error (elf64_section_header_table * byte_sequence)*)letread_elf64_section_header_tabletable_sizeendianbs0:((elf64_section_header_table_entry)list*Byte_sequence_wrapper.byte_sequence)error=(bind(partition0table_sizebs0)(fun(eat,rest)->bind(read_elf64_section_header_table'endianeat)(funentries->return(entries,rest))))(** Correctness criteria *)(** TODO: what is going on here? *)(*val elf32_size_correct : elf32_section_header_table_entry ->
elf32_section_header_table -> bool*)letelf32_size_correcthdrtbl:bool=(letm=(Uint32_wrapper.to_biginthdr.elf32_sh_size)inifNat_big_num.equalm((Nat_big_num.of_int0))thentrueelseNat_big_num.equalm(Nat_big_num.of_int(List.lengthtbl)))(** TODO: what is going on here? *)(*val elf64_size_correct : elf64_section_header_table_entry ->
elf64_section_header_table -> bool*)letelf64_size_correcthdrtbl:bool=(letm=(Ml_bindings.nat_big_num_of_uint64hdr.elf64_sh_size)inifNat_big_num.equalm((Nat_big_num.of_int0))thentrueelseNat_big_num.equalm(Nat_big_num.of_int(List.lengthtbl)))(** [is_elf32_addr_addralign_correct ent] checks whether an internal address
* alignment constraint is met on section header table [ent].
* TODO: needs tweaking to add in power-of-two constraint, too.
*)(*val is_elf32_addr_addralign_correct : elf32_section_header_table_entry -> bool*)letis_elf32_addr_addralign_correctent:bool=(letalign=(Uint32_wrapper.to_bigintent.elf32_sh_addralign)inletaddr=(Uint32_wrapper.to_bigintent.elf32_sh_addr)inifNat_big_num.equal(Nat_big_num.modulusaddralign)((Nat_big_num.of_int0))thenNat_big_num.equalalign((Nat_big_num.of_int0))||Nat_big_num.equalalign((Nat_big_num.of_int1))(* TODO: or a power of two *)elsefalse)(** [is_elf64_addr_addralign_correct ent] checks whether an internal address
* alignment constraint is met on section header table [ent].
* TODO: needs tweaking to add in power-of-two constraint, too.
*)(*val is_elf64_addr_addralign_correct : elf64_section_header_table_entry -> bool*)letis_elf64_addr_addralign_correctent:bool=(letalign=(Ml_bindings.nat_big_num_of_uint64ent.elf64_sh_addralign)inletaddr=(Ml_bindings.nat_big_num_of_uint64ent.elf64_sh_addr)inifNat_big_num.equal(Nat_big_num.modulusaddralign)((Nat_big_num.of_int0))thenNat_big_num.equalalign((Nat_big_num.of_int0))||Nat_big_num.equalalign((Nat_big_num.of_int1))(* TODO: or a power of two *)elsefalse)(** [is_valid_elf32_section_header_table sht] checks whether all entries of
* section header table [sht] are valid.
*)(*val is_valid_elf32_section_header_table : elf32_section_header_table -> bool*)letis_valid_elf32_section_header_tabletbl:bool=((matchtblwith|[]->true|x::xs->Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_name)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_type)sht_null&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_flags)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_addr)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_offset)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_info)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_addralign)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf32_sh_entsize)((Nat_big_num.of_int0))&&elf32_size_correctxtbl)))))))(* XXX: more correctness criteria in time *)))(** [is_valid_elf64_section_header_table sht] checks whether all entries of
* section header table [sht] are valid.
*)(*val is_valid_elf64_section_header_table : elf64_section_header_table -> bool*)letis_valid_elf64_section_header_tabletbl:bool=((matchtblwith|[]->true|x::xs->Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf64_sh_name)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf64_sh_type)sht_null&&(Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64x.elf64_sh_flags)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64x.elf64_sh_addr)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint64_wrapper.to_bigintx.elf64_sh_offset)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Uint32_wrapper.to_bigintx.elf64_sh_info)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64x.elf64_sh_addralign)((Nat_big_num.of_int0))&&(Nat_big_num.equal(Ml_bindings.nat_big_num_of_uint64x.elf64_sh_entsize)((Nat_big_num.of_int0))&&elf64_size_correctxtbl)))))))(* XXX: more correctness criteria in time *)))(** Pretty printing *)(** The [sht_print_bundle] type is used to tidy up other type signatures. Some of the
* top-level string_of_ functions require six or more functions passed to them,
* which quickly gets out of hand. This type is used to reduce that complexity.
* The first component of the type is an OS specific print function, the second is
* a processor specific print function.
*)typesht_print_bundle=(Nat_big_num.num->string)*(Nat_big_num.num->string)*(Nat_big_num.num->string)(** [string_of_elf32_section_header_table_entry sht ent] produces a string
* representation of section header table entry [ent] using [sht], a
* [sht_print_bundle].
* OCaml specific definition.
*)(*val string_of_elf32_section_header_table_entry : sht_print_bundle ->
elf32_section_header_table_entry -> string*)letstring_of_elf32_section_header_table_entry(os,proc,user)entry:string=(unlines[("\t"^("Name: "^Uint32_wrapper.to_stringentry.elf32_sh_name));("\t"^("Type: "^string_of_section_typeosprocuser(Uint32_wrapper.to_bigintentry.elf32_sh_type)));("\t"^("Flags: "^Uint32_wrapper.to_stringentry.elf32_sh_flags));("\t"^("Address: "^Uint32_wrapper.to_stringentry.elf32_sh_addr));("\t"^("Size: "^Uint32_wrapper.to_stringentry.elf32_sh_size))])(** [string_of_elf64_section_header_table_entry sht ent] produces a string
* representation of section header table entry [ent] using [sht], a
* [sht_print_bundle].
* OCaml specific definition.
*)(*val string_of_elf64_section_header_table_entry : sht_print_bundle ->
elf64_section_header_table_entry -> string*)letstring_of_elf64_section_header_table_entry(os,proc,user)entry:string=(unlines[("\t"^("Name: "^Uint32_wrapper.to_stringentry.elf64_sh_name));("\t"^("Type: "^string_of_section_typeosprocuser(Uint32_wrapper.to_bigintentry.elf64_sh_type)));("\t"^("Flags: "^Uint64_wrapper.to_stringentry.elf64_sh_flags));("\t"^("Address: "^Uint64_wrapper.to_stringentry.elf64_sh_addr));("\t"^("Size: "^Uint64_wrapper.to_stringentry.elf64_sh_size))])(** [string_of_elf32_section_header_table_entry' sht stab ent] produces a string
* representation of section header table entry [ent] using [sht] and section
* header string table [stab] to print the name of the section header entry
* correctly.
* OCaml specific definition.
*)(*val string_of_elf32_section_header_table_entry' : sht_print_bundle ->
string_table -> elf32_section_header_table_entry -> string*)letstring_of_elf32_section_header_table_entry'(os,proc,user)stblentry:string=(letname1=((matchget_string_at(Uint32_wrapper.to_bigintentry.elf32_sh_name)stblwith|Fail_->"Invalid index into string table"|Successi->i))inunlines[("\t"^("Name: "^name1));("\t"^("Type: "^string_of_section_typeosprocuser(Uint32_wrapper.to_bigintentry.elf32_sh_type)));("\t"^("Flags: "^Uint32_wrapper.to_stringentry.elf32_sh_flags));("\t"^("Address: "^Uint32_wrapper.to_stringentry.elf32_sh_addr));("\t"^("Size: "^Uint32_wrapper.to_stringentry.elf32_sh_size))])(** [string_of_elf64_section_header_table_entry' sht stab ent] produces a string
* representation of section header table entry [ent] using [sht] and section
* header string table [stab] to print the name of the section header entry
* correctly.
* OCaml specific definition.
*)(*val string_of_elf64_section_header_table_entry' : sht_print_bundle ->
string_table -> elf64_section_header_table_entry -> string*)letstring_of_elf64_section_header_table_entry'(os,proc,user)stblentry:string=(letname1=((matchget_string_at(Uint32_wrapper.to_bigintentry.elf64_sh_name)stblwith|Fail_->"Invalid index into string table"|Successi->i))inunlines[("\t"^("Name: "^name1));("\t"^("Type: "^string_of_section_typeosprocuser(Uint32_wrapper.to_bigintentry.elf64_sh_type)));("\t"^("Flags: "^Uint64_wrapper.to_stringentry.elf64_sh_flags));("\t"^("Address: "^Uint64_wrapper.to_stringentry.elf64_sh_addr));("\t"^("Size: "^Uint64_wrapper.to_stringentry.elf64_sh_size))])(** The following defintions are default printing functions, with no ABI-specific
* functionality, in order to produce a [Show] instance for section header
* table entries.
*)(*val string_of_elf32_section_header_table_entry_default : elf32_section_header_table_entry -> string*)letstring_of_elf32_section_header_table_entry_default:elf32_section_header_table_entry->string=(string_of_elf32_section_header_table_entry(((funy->"*Default OS specific print*")),((funy->"*Default processor specific print*")),((funy->"*Default user specific print*"))))letinstance_Show_Show_Elf_section_header_table_elf32_section_header_table_entry_dict:(elf32_section_header_table_entry)show_class=({show_method=string_of_elf32_section_header_table_entry_default})(*val string_of_elf64_section_header_table_entry_default : elf64_section_header_table_entry -> string*)letstring_of_elf64_section_header_table_entry_default:elf64_section_header_table_entry->string=(string_of_elf64_section_header_table_entry(((funy->"*Default OS specific print*")),((funy->"*Default processor specific print*")),((funy->"*Default user specific print*"))))letinstance_Show_Show_Elf_section_header_table_elf64_section_header_table_entry_dict:(elf64_section_header_table_entry)show_class=({show_method=string_of_elf64_section_header_table_entry_default})(*val string_of_elf32_section_header_table : sht_print_bundle ->
elf32_section_header_table -> string*)letstring_of_elf32_section_header_tablesht_bdltbl:string=(unlines(Lem_list.map(string_of_elf32_section_header_table_entrysht_bdl)tbl))(*val string_of_elf32_section_header_table_default : elf32_section_header_table ->
string*)letstring_of_elf32_section_header_table_default:elf32_section_header_table->string=(string_of_elf32_section_header_table(((funy->"*Default OS specific print*")),((funy->"*Default processor specific print*")),((funy->"*Default user specific print*"))))(*val string_of_elf64_section_header_table : sht_print_bundle ->
elf64_section_header_table -> string*)letstring_of_elf64_section_header_tablesht_bdltbl:string=(unlines(Lem_list.map(string_of_elf64_section_header_table_entrysht_bdl)tbl))(*val string_of_elf64_section_header_table_default : elf64_section_header_table ->
string*)letstring_of_elf64_section_header_table_default:elf64_section_header_table->string=(string_of_elf64_section_header_table(((funy->"*Default OS specific print*")),((funy->"*Default processor specific print*")),((funy->"*Default user specific print*"))))(*val string_of_elf32_section_header_table' : sht_print_bundle -> string_table ->
elf32_section_header_table -> string*)letstring_of_elf32_section_header_table'sht_bdlstbltbl:string=(unlines(Lem_list.map(string_of_elf32_section_header_table_entry'sht_bdlstbl)tbl))(*val string_of_elf64_section_header_table' : sht_print_bundle -> string_table ->
elf64_section_header_table -> string*)letstring_of_elf64_section_header_table'sht_bdlstbltbl:string=(unlines(Lem_list.map(string_of_elf64_section_header_table_entry'sht_bdlstbl)tbl))(** Section to segment mappings *)(** [elf32_tbss_special shdr seg] implements the ELF_TBSS_SPECIAL macro from readelf:
*
* #define ELF_TBSS_SPECIAL(sec_hdr, segment) \
* (((sec_hdr)->sh_flags & SHF_TLS) != 0 \
* && (sec_hdr)->sh_type == SHT_NOBITS \
* && (segment)->p_type != PT_TLS)
*
* From readelf source code, file [internal.h].
*
*)(*val is_elf32_tbss_special : elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool*)letis_elf32_tbss_specialsec_hdrsegment:bool=(not((Uint32_wrapper.logandsec_hdr.elf32_sh_flags(Uint32_wrapper.of_bigintshf_tls))=(Uint32_wrapper.of_bigint((Nat_big_num.of_int0))))&&((Nat_big_num.equal(Uint32_wrapper.to_bigintsec_hdr.elf32_sh_type)sht_nobits)&&(not(Nat_big_num.equal(Uint32_wrapper.to_bigintsegment.elf32_p_type)elf_pt_tls))))(** [elf64_tbss_special shdr seg] implements the ELF_TBSS_SPECIAL macro from readelf:
*
* #define ELF_TBSS_SPECIAL(sec_hdr, segment) \
* (((sec_hdr)->sh_flags & SHF_TLS) != 0 \
* && (sec_hdr)->sh_type == SHT_NOBITS \
* && (segment)->p_type != PT_TLS)
*
* From readelf source code, file [internal.h].
*
*)(*val is_elf64_tbss_special : elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool*)letis_elf64_tbss_specialsec_hdrsegment:bool=(not((Uint64_wrapper.logandsec_hdr.elf64_sh_flags(Uint64_wrapper.of_bigintshf_tls))=(Uint64_wrapper.of_bigint((Nat_big_num.of_int0))))&&((Nat_big_num.equal(Uint32_wrapper.to_bigintsec_hdr.elf64_sh_type)sht_nobits)&&(not(Nat_big_num.equal(Uint32_wrapper.to_bigintsegment.elf64_p_type)elf_pt_tls))))(** [get_elf32_section_to_segment_mapping hdr sht pht isin stbl] computes the
* section to segment mapping for an ELF file using information in the section
* header table [sht], program header table [pht] and file header [hdr]. A
* string table [stbl] is taken to produce the string output. The test whether
* a section lies withing a segment is ABI specific, so [isin] is used to perform
* the test.
*)(*val get_elf32_section_to_segment_mapping : elf32_header -> elf32_section_header_table -> elf32_program_header_table_entry ->
(elf32_header -> elf32_section_header_table_entry -> elf32_program_header_table_entry -> bool) ->
string_table -> error (list string)*)letrecget_elf32_section_to_segment_mappinghdrsectspentisinstbl:((string)list)error=((matchsectswith|[]->return[]|x::xs->ifis_elf32_tbss_specialxpentthenget_elf32_section_to_segment_mappinghdrxspentisinstblelseifnot(isinhdrxpent)thenget_elf32_section_to_segment_mappinghdrxspentisinstblelseletnm=(Uint32_wrapper.to_bigintx.elf32_sh_name)inbind(get_string_atnmstbl)(funstr->bind(get_elf32_section_to_segment_mappinghdrxspentisinstbl)(funtl->return(str::tl)))))(** [get_elf64_section_to_segment_mapping hdr sht pht isin stbl] computes the
* section to segment mapping for an ELF file using information in the section
* header table [sht], program header table [pht] and file header [hdr]. A
* string table [stbl] is taken to produce the string output. The test whether
* a section lies withing a segment is ABI specific, so [isin] is used to perform
* the test.
*)(*val get_elf64_section_to_segment_mapping : elf64_header -> elf64_section_header_table -> elf64_program_header_table_entry ->
(elf64_header -> elf64_section_header_table_entry -> elf64_program_header_table_entry -> bool) ->
string_table -> error (list string)*)letrecget_elf64_section_to_segment_mappinghdrsectspentisinstbl:((string)list)error=((matchsectswith|[]->return[]|x::xs->ifnot(isinhdrxpent)thenget_elf64_section_to_segment_mappinghdrxspentisinstblelseifis_elf64_tbss_specialxpentthenget_elf64_section_to_segment_mappinghdrxspentisinstblelseletnm=(Uint32_wrapper.to_bigintx.elf64_sh_name)inbind(get_string_atnmstbl)(funstr->bind(get_elf64_section_to_segment_mappinghdrxspentisinstbl)(funtl->return(str::tl)))))(** Section groups *)(** This is a COMDAT group and may duplicate other COMDAT groups in other object
* files.
*)letgrp_comdat:Nat_big_num.num=((Nat_big_num.of_int1))(** Any bits in the following mask ranges are reserved exclusively for OS and
* processor specific semantics, respectively.
*)letgrp_maskos:Nat_big_num.num=((Nat_big_num.of_int267386880))(* 0x0ff00000 *)letgrp_maskproc:Nat_big_num.num=(Nat_big_num.mul((Nat_big_num.of_int4))((Nat_big_num.of_int1006632960)))(* 0xf0000000 *)(** [obtain_elf32_section_group_indices endian sht bs0] extracts all section header
* table indices of sections that are marked as being part of a section group.
*)(*val obtain_elf32_section_group_indices : endianness -> elf32_section_header_table -> byte_sequence
-> error (list (natural * list elf32_word))*)letobtain_elf32_section_group_indicesendianshtbs0:((Nat_big_num.num*(Uint32_wrapper.uint32)list)list)error=(letfiltered=(List.filter(funent->Nat_big_num.equal(Uint32_wrapper.to_bigintent.elf32_sh_type)sht_group)sht)inmapM(fungrp->letoff=(Uint32_wrapper.to_bigintgrp.elf32_sh_offset)inletsiz=(Uint32_wrapper.to_bigintgrp.elf32_sh_size)inletcnt=(Nat_big_num.divsiz((Nat_big_num.of_int4)))(* size of elf32_word in bytes *)inbind(Byte_sequence.offset_and_cutoffsizbs0)(funrel->bind(Error.repeatM'cntrel(read_elf32_wordendian))(fun(mems,_)->(matchmemswith|[]->fail"obtain_elf32_section_group_indices: section group sections must consist of at least one elf32_word"|x::xs->letflag=(Uint32_wrapper.to_bigintx)inreturn(flag,xs)))))filtered)(** [obtain_elf64_section_group_indices endian sht bs0] extracts all section header
* table indices of sections that are marked as being part of a section group.
*)(*val obtain_elf64_section_group_indices : endianness -> elf64_section_header_table -> byte_sequence
-> error (list (natural * list elf64_word))*)letobtain_elf64_section_group_indicesendianshtbs0:((Nat_big_num.num*(Uint32_wrapper.uint32)list)list)error=(letfiltered=(List.filter(funent->Nat_big_num.equal(Uint32_wrapper.to_bigintent.elf64_sh_type)sht_group)sht)inmapM(fungrp->letoff=(Uint64_wrapper.to_bigintgrp.elf64_sh_offset)inletsiz=(Ml_bindings.nat_big_num_of_uint64grp.elf64_sh_size)inletcnt=(Nat_big_num.divsiz((Nat_big_num.of_int4)))(* size of elf64_word in bytes *)inbind(Byte_sequence.offset_and_cutoffsizbs0)(funrel->bind(Error.repeatM'cntrel(read_elf64_wordendian))(fun(mems,_)->(matchmemswith|[]->fail"obtain_elf64_section_group_indices: section group sections must consist of at least one elf64_word"|x::xs->letflag=(Uint32_wrapper.to_bigintx)inreturn(flag,xs)))))filtered)(** [obtain_elf32_tls_template sht] extracts the TLS template (i.e. all sections
* in section header table [sht] that have their TLS flag bit set).
*)(*val obtain_elf32_tls_template : elf32_section_header_table -> elf32_section_header_table*)letobtain_elf32_tls_templatesht:(elf32_section_header_table_entry)list=(List.filter(funent->letflags=(Uint32_wrapper.to_bigintent.elf32_sh_flags)innot(Nat_big_num.equal(Nat_big_num.bitwise_andflagsshf_tls)((Nat_big_num.of_int0))))sht)(** [obtain_elf64_tls_template sht] extracts the TLS template (i.e. all sections
* in section header table [sht] that have their TLS flag bit set).
*)(*val obtain_elf64_tls_template : elf64_section_header_table -> elf64_section_header_table*)letobtain_elf64_tls_templatesht:(elf64_section_header_table_entry)list=(List.filter(funent->letflags=(Ml_bindings.nat_big_num_of_uint64ent.elf64_sh_flags)innot(Nat_big_num.equal(Nat_big_num.bitwise_andflagsshf_tls)((Nat_big_num.of_int0))))sht)(** [obtain_elf32_hash_table endian sht bs0] extracts a hash table from an ELF file
* providing a section of type SHT_HASH exists in section header table [sht].
* Extraction is from byte sequence [bs0] assuming endianness [endian]. The
* return type represents the number of buckets, the number of chains, the buckets
* and finally the chains.
*)(*val obtain_elf32_hash_table : endianness -> elf32_section_header_table -> byte_sequence ->
error (elf32_word * elf32_word * list elf32_word * list elf32_word)*)letobtain_elf32_hash_tableendianshtbs0:(Uint32_wrapper.uint32*Uint32_wrapper.uint32*(Uint32_wrapper.uint32)list*(Uint32_wrapper.uint32)list)error=(letfiltered=(List.filter(funent->Nat_big_num.equal(Uint32_wrapper.to_bigintent.elf32_sh_type)sht_hash)sht)in(matchfilteredwith|[]->fail"obtain_elf32_hash_table: no section header table entry of type sht_hash"|[x]->letsiz=(Uint32_wrapper.to_bigintx.elf32_sh_size)inletoff=(Uint32_wrapper.to_bigintx.elf32_sh_offset)inbind(Byte_sequence.offset_and_cutsizoffbs0)(funrel->bind(read_elf32_wordendianrel)(fun(nbucket,rel)->bind(read_elf32_wordendianrel)(fun(nchain,rel)->bind(Error.repeatM'(Uint32_wrapper.to_bigintnbucket)rel(read_elf32_wordendian))(fun(buckets,rel)->bind(Error.repeatM'(Uint32_wrapper.to_bigintnchain)rel(read_elf32_wordendian))(fun(chain,_)->return(nbucket,nchain,buckets,chain))))))|_->fail"obtain_elf32_hash_table: multiple section header table entries of type sht_hash"))(** [obtain_elf64_hash_table endian sht bs0] extracts a hash table from an ELF file
* providing a section of type SHT_HASH exists in section header table [sht].
* Extraction is from byte sequence [bs0] assuming endianness [endian]. The
* return type represents the number of buckets, the number of chains, the buckets
* and finally the chains.
*)(*val obtain_elf64_hash_table : endianness -> elf64_section_header_table -> byte_sequence ->
error (elf64_word * elf64_word * list elf64_word * list elf64_word)*)letobtain_elf64_hash_tableendianshtbs0:(Uint32_wrapper.uint32*Uint32_wrapper.uint32*(Uint32_wrapper.uint32)list*(Uint32_wrapper.uint32)list)error=(letfiltered=(List.filter(funent->Nat_big_num.equal(Uint32_wrapper.to_bigintent.elf64_sh_type)sht_hash)sht)in(matchfilteredwith|[]->fail"obtain_elf64_hash_table: no section header table entry of type sht_hash"|[x]->letsiz=(Ml_bindings.nat_big_num_of_uint64x.elf64_sh_size)inletoff=(Uint64_wrapper.to_bigintx.elf64_sh_offset)inbind(Byte_sequence.offset_and_cutsizoffbs0)(funrel->bind(read_elf64_wordendianrel)(fun(nbucket,rel)->bind(read_elf64_wordendianrel)(fun(nchain,rel)->bind(Error.repeatM'(Uint32_wrapper.to_bigintnbucket)rel(read_elf64_wordendian))(fun(buckets,rel)->bind(Error.repeatM'(Uint32_wrapper.to_bigintnchain)rel(read_elf64_wordendian))(fun(chain,_)->return(nbucket,nchain,buckets,chain))))))|_->fail"obtain_elf64_hash_table: multiple section header table entries of type sht_hash"))(** Special sections *)(** [construct_special_sections] contains a finite map from section name (as
* a string) to the expected attributes and flags expected of that section,
* as specified in the ELF specification.
* NOTE: some of these are overriden by the ABI.
*)(*val elf_special_sections : Map.map string (natural * natural)*)letelf_special_sections:((string),(Nat_big_num.num*Nat_big_num.num))Pmap.map=(Lem_map.fromList(instance_Map_MapKeyType_var_dictinstance_Basic_classes_SetType_var_dict)[(".bss",(sht_nobits,Nat_big_num.addshf_allocshf_write));(".comment",(sht_progbits,(Nat_big_num.of_int0)));(".data",(sht_progbits,Nat_big_num.addshf_allocshf_write));(".data1",(sht_progbits,Nat_big_num.addshf_allocshf_write));(".debug",(sht_progbits,(Nat_big_num.of_int0)))(* ; (".dynamic", (sht_dynamic, ?)) *);(".dynstr",(sht_strtab,shf_alloc));(".dynsym",(sht_dynsym,shf_alloc));(".fini",(sht_progbits,Nat_big_num.addshf_allocshf_execinstr));(".fini_array",(sht_fini_array,Nat_big_num.addshf_allocshf_write))(* ; (".got", (sht_progbits, ?)) *);(".hash",(sht_hash,shf_alloc));(".init",(sht_progbits,Nat_big_num.addshf_allocshf_execinstr));(".init_array",(sht_init_array,Nat_big_num.addshf_allocshf_write))(* ; (".interp", (sht_progbits, ?)) *);(".line",(sht_progbits,(Nat_big_num.of_int0)));(".note",(sht_note,(Nat_big_num.of_int0)))(* ; (".plt", (sht_progbits, ?)) *);(".preinit_array",(sht_preinit_array,Nat_big_num.addshf_allocshf_write))(* ; (".relname", (sht_rel, ?)) *)(* ; (".relaname", (sht_rela, ?)) *);(".rodata",(sht_progbits,shf_alloc));(".rodata1",(sht_progbits,shf_alloc));(".shstrtab",(sht_strtab,(Nat_big_num.of_int0)))(* ; (".strtab", (sht_strtab, ?)) *)(* ; (".symtab", (sht_symtab, ?)) *)(* ; (".symtab_shndx", (sht_symtab_shndx, ?)) *);(".tbss",(sht_nobits,Nat_big_num.add(Nat_big_num.addshf_allocshf_write)shf_tls));(".tdata",(sht_progbits,Nat_big_num.add(Nat_big_num.addshf_allocshf_write)shf_tls));(".tdata1",(sht_progbits,Nat_big_num.add(Nat_big_num.addshf_allocshf_write)shf_tls));(".text",(sht_progbits,Nat_big_num.addshf_allocshf_execinstr))])