Executable and Linkable Format: Ruby parsing library

Application

SVR4 ABI and up, many *nix systems

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.11

References

This page hosts a formal specification of Executable and Linkable Format using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Runtime library

All Ruby code generated by Kaitai Struct depends on the Kaitai Struct runtime library for Ruby. You must add this dependency to your project before you can parse or serialize any data.

The Ruby runtime library can be installed from RubyGems:

gem install kaitai-struct

Code

Parse a local file and get structure in memory:

data = Elf.from_file("path/to/local/file.bin")

Or parse structure from a string of bytes:

bytes = "\x00\x01\x02..."
data = Elf.new(Kaitai::Struct::Stream.new(bytes))

After that, one can get various attributes from the structure by invoking getter methods like:

data.magic # => File identification, must be 0x7f + "ELF".

Ruby source code to parse Executable and Linkable Format

elf.rb

# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

require 'kaitai/struct/struct'

unless Gem::Version.new(Kaitai::Struct::VERSION) >= Gem::Version.new('0.11')
  raise "Incompatible Kaitai Struct Ruby API: 0.11 or later is required, but you have #{Kaitai::Struct::VERSION}"
end


##
# @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h Source
# @see https://refspecs.linuxfoundation.org/elf/gabi4+/contents.html Source
# @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/elf-application-binary-interface.html Source
class Elf < Kaitai::Struct::Struct

  BITS = {
    1 => :bits_b32,
    2 => :bits_b64,
  }
  I__BITS = BITS.invert

  DYNAMIC_ARRAY_TAGS = {
    0 => :dynamic_array_tags_null,
    1 => :dynamic_array_tags_needed,
    2 => :dynamic_array_tags_pltrelsz,
    3 => :dynamic_array_tags_pltgot,
    4 => :dynamic_array_tags_hash,
    5 => :dynamic_array_tags_strtab,
    6 => :dynamic_array_tags_symtab,
    7 => :dynamic_array_tags_rela,
    8 => :dynamic_array_tags_relasz,
    9 => :dynamic_array_tags_relaent,
    10 => :dynamic_array_tags_strsz,
    11 => :dynamic_array_tags_syment,
    12 => :dynamic_array_tags_init,
    13 => :dynamic_array_tags_fini,
    14 => :dynamic_array_tags_soname,
    15 => :dynamic_array_tags_rpath,
    16 => :dynamic_array_tags_symbolic,
    17 => :dynamic_array_tags_rel,
    18 => :dynamic_array_tags_relsz,
    19 => :dynamic_array_tags_relent,
    20 => :dynamic_array_tags_pltrel,
    21 => :dynamic_array_tags_debug,
    22 => :dynamic_array_tags_textrel,
    23 => :dynamic_array_tags_jmprel,
    24 => :dynamic_array_tags_bind_now,
    25 => :dynamic_array_tags_init_array,
    26 => :dynamic_array_tags_fini_array,
    27 => :dynamic_array_tags_init_arraysz,
    28 => :dynamic_array_tags_fini_arraysz,
    29 => :dynamic_array_tags_runpath,
    30 => :dynamic_array_tags_flags,
    32 => :dynamic_array_tags_preinit_array,
    33 => :dynamic_array_tags_preinit_arraysz,
    34 => :dynamic_array_tags_symtab_shndx,
    35 => :dynamic_array_tags_relrsz,
    36 => :dynamic_array_tags_relr,
    37 => :dynamic_array_tags_relrent,
    117440513 => :dynamic_array_tags_deprecated_sparc_register,
    1610612749 => :dynamic_array_tags_sunw_auxiliary,
    1610612750 => :dynamic_array_tags_sunw_rtldinf,
    1610612751 => :dynamic_array_tags_sunw_filter,
    1610612752 => :dynamic_array_tags_sunw_cap,
    1610612753 => :dynamic_array_tags_sunw_symtab,
    1610612754 => :dynamic_array_tags_sunw_symsz,
    1610612755 => :dynamic_array_tags_sunw_sortent,
    1610612756 => :dynamic_array_tags_sunw_symsort,
    1610612757 => :dynamic_array_tags_sunw_symsortsz,
    1610612758 => :dynamic_array_tags_sunw_tlssort,
    1610612759 => :dynamic_array_tags_sunw_tlssortsz,
    1610612760 => :dynamic_array_tags_sunw_capinfo,
    1610612761 => :dynamic_array_tags_sunw_strpad,
    1610612762 => :dynamic_array_tags_sunw_capchain,
    1610612763 => :dynamic_array_tags_sunw_ldmach,
    1610612764 => :dynamic_array_tags_sunw_symtab_shndx,
    1610612765 => :dynamic_array_tags_sunw_capchainent,
    1610612766 => :dynamic_array_tags_sunw_deferred,
    1610612767 => :dynamic_array_tags_sunw_capchainsz,
    1610612768 => :dynamic_array_tags_sunw_phname,
    1610612769 => :dynamic_array_tags_sunw_parent,
    1610612771 => :dynamic_array_tags_sunw_sx_aslr,
    1610612773 => :dynamic_array_tags_sunw_relax,
    1610612775 => :dynamic_array_tags_sunw_kmod,
    1610612777 => :dynamic_array_tags_sunw_sx_nxheap,
    1610612779 => :dynamic_array_tags_sunw_sx_nxstack,
    1610612781 => :dynamic_array_tags_sunw_sx_adiheap,
    1610612783 => :dynamic_array_tags_sunw_sx_adistack,
    1610612785 => :dynamic_array_tags_sunw_sx_ssbd,
    1610612786 => :dynamic_array_tags_sunw_symnsort,
    1610612787 => :dynamic_array_tags_sunw_symnsortsz,
    1879047668 => :dynamic_array_tags_gnu_flags_1,
    1879047669 => :dynamic_array_tags_gnu_prelinked,
    1879047670 => :dynamic_array_tags_gnu_conflictsz,
    1879047671 => :dynamic_array_tags_gnu_liblistsz,
    1879047672 => :dynamic_array_tags_checksum,
    1879047673 => :dynamic_array_tags_pltpadsz,
    1879047674 => :dynamic_array_tags_moveent,
    1879047675 => :dynamic_array_tags_movesz,
    1879047676 => :dynamic_array_tags_feature_1,
    1879047677 => :dynamic_array_tags_posflag_1,
    1879047678 => :dynamic_array_tags_syminsz,
    1879047679 => :dynamic_array_tags_syminent,
    1879047925 => :dynamic_array_tags_gnu_hash,
    1879047926 => :dynamic_array_tags_tlsdesc_plt,
    1879047927 => :dynamic_array_tags_tlsdesc_got,
    1879047928 => :dynamic_array_tags_gnu_conflict,
    1879047929 => :dynamic_array_tags_gnu_liblist,
    1879047930 => :dynamic_array_tags_config,
    1879047931 => :dynamic_array_tags_depaudit,
    1879047932 => :dynamic_array_tags_audit,
    1879047933 => :dynamic_array_tags_pltpad,
    1879047934 => :dynamic_array_tags_movetab,
    1879047935 => :dynamic_array_tags_syminfo,
    1879048176 => :dynamic_array_tags_versym,
    1879048185 => :dynamic_array_tags_relacount,
    1879048186 => :dynamic_array_tags_relcount,
    1879048187 => :dynamic_array_tags_flags_1,
    1879048188 => :dynamic_array_tags_verdef,
    1879048189 => :dynamic_array_tags_verdefnum,
    1879048190 => :dynamic_array_tags_verneed,
    1879048191 => :dynamic_array_tags_verneednum,
    1879048193 => :dynamic_array_tags_sparc_register,
    2147483645 => :dynamic_array_tags_auxiliary,
    2147483646 => :dynamic_array_tags_used,
    2147483647 => :dynamic_array_tags_filter,
  }
  I__DYNAMIC_ARRAY_TAGS = DYNAMIC_ARRAY_TAGS.invert

  ENDIAN = {
    1 => :endian_le,
    2 => :endian_be,
  }
  I__ENDIAN = ENDIAN.invert

  MACHINE = {
    0 => :machine_no_machine,
    1 => :machine_m32,
    2 => :machine_sparc,
    3 => :machine_i386,
    4 => :machine_m68k,
    5 => :machine_m88k,
    6 => :machine_iamcu,
    7 => :machine_i860,
    8 => :machine_mips,
    9 => :machine_s370,
    10 => :machine_mips_rs3_le,
    11 => :machine_old_sparc_v9,
    15 => :machine_parisc,
    17 => :machine_vpp500,
    18 => :machine_sparc32plus,
    19 => :machine_i960,
    20 => :machine_powerpc,
    21 => :machine_powerpc64,
    22 => :machine_s390,
    23 => :machine_spu,
    36 => :machine_v800,
    37 => :machine_fr20,
    38 => :machine_rh32,
    39 => :machine_mcore,
    40 => :machine_arm,
    41 => :machine_old_alpha,
    42 => :machine_superh,
    43 => :machine_sparc_v9,
    44 => :machine_tricore,
    45 => :machine_arc,
    46 => :machine_h8_300,
    47 => :machine_h8_300h,
    48 => :machine_h8s,
    49 => :machine_h8_500,
    50 => :machine_ia_64,
    51 => :machine_mips_x,
    52 => :machine_coldfire,
    53 => :machine_m68hc12,
    54 => :machine_mma,
    55 => :machine_pcp,
    56 => :machine_ncpu,
    57 => :machine_ndr1,
    58 => :machine_starcore,
    59 => :machine_me16,
    60 => :machine_st100,
    61 => :machine_tinyj,
    62 => :machine_x86_64,
    63 => :machine_pdsp,
    64 => :machine_pdp10,
    65 => :machine_pdp11,
    66 => :machine_fx66,
    67 => :machine_st9plus,
    68 => :machine_st7,
    69 => :machine_m68hc16,
    70 => :machine_m68hc11,
    71 => :machine_m68hc08,
    72 => :machine_m68hc05,
    73 => :machine_svx,
    74 => :machine_st19,
    75 => :machine_vax,
    76 => :machine_cris,
    77 => :machine_javelin,
    78 => :machine_firepath,
    79 => :machine_zsp,
    80 => :machine_mmix,
    81 => :machine_huany,
    82 => :machine_prism,
    83 => :machine_avr,
    84 => :machine_fr30,
    85 => :machine_d10v,
    86 => :machine_d30v,
    87 => :machine_v850,
    88 => :machine_m32r,
    89 => :machine_mn10300,
    90 => :machine_mn10200,
    91 => :machine_picojava,
    92 => :machine_or1k,
    93 => :machine_arc_compact,
    94 => :machine_xtensa,
    95 => :machine_videocore,
    96 => :machine_tmm_gpp,
    97 => :machine_ns32k,
    98 => :machine_tpc,
    99 => :machine_snp1k,
    100 => :machine_st200,
    101 => :machine_ip2k,
    102 => :machine_max,
    103 => :machine_cr,
    104 => :machine_f2mc16,
    105 => :machine_msp430,
    106 => :machine_blackfin,
    107 => :machine_se_c33,
    108 => :machine_sep,
    109 => :machine_arca,
    110 => :machine_unicore,
    111 => :machine_excess,
    112 => :machine_dxp,
    113 => :machine_altera_nios2,
    114 => :machine_crx,
    115 => :machine_xgate,
    116 => :machine_c166,
    117 => :machine_m16c,
    118 => :machine_dspic30f,
    119 => :machine_freescale_ce,
    120 => :machine_m32c,
    131 => :machine_tsk3000,
    132 => :machine_rs08,
    133 => :machine_sharc,
    134 => :machine_ecog2,
    135 => :machine_score7,
    136 => :machine_dsp24,
    137 => :machine_videocore3,
    138 => :machine_latticemico32,
    139 => :machine_se_c17,
    140 => :machine_ti_c6000,
    141 => :machine_ti_c2000,
    142 => :machine_ti_c5500,
    143 => :machine_ti_arp32,
    144 => :machine_ti_pru,
    160 => :machine_mmdsp_plus,
    161 => :machine_cypress_m8c,
    162 => :machine_r32c,
    163 => :machine_trimedia,
    164 => :machine_qdsp6,
    165 => :machine_i8051,
    166 => :machine_stxp7x,
    167 => :machine_nds32,
    168 => :machine_ecog1x,
    169 => :machine_maxq30,
    170 => :machine_ximo16,
    171 => :machine_manik,
    172 => :machine_cray_nv2,
    173 => :machine_rx,
    174 => :machine_metag,
    175 => :machine_mcst_elbrus,
    176 => :machine_ecog16,
    177 => :machine_cr16,
    178 => :machine_etpu,
    179 => :machine_sle9x,
    180 => :machine_l1om,
    181 => :machine_k1om,
    182 => :machine_intel182,
    183 => :machine_aarch64,
    184 => :machine_arm184,
    185 => :machine_avr32,
    186 => :machine_stm8,
    187 => :machine_tile64,
    188 => :machine_tilepro,
    189 => :machine_microblaze,
    190 => :machine_cuda,
    191 => :machine_tilegx,
    192 => :machine_cloudshield,
    193 => :machine_corea_1st,
    194 => :machine_corea_2nd,
    195 => :machine_arc_compact2,
    196 => :machine_open8,
    197 => :machine_rl78,
    198 => :machine_videocore5,
    199 => :machine_renesas_78k0r,
    200 => :machine_freescale_56800ex,
    201 => :machine_ba1,
    202 => :machine_ba2,
    203 => :machine_xcore,
    204 => :machine_mchp_pic,
    205 => :machine_intelgt,
    206 => :machine_intel206,
    207 => :machine_intel207,
    208 => :machine_intel208,
    209 => :machine_intel209,
    210 => :machine_km32,
    211 => :machine_kmx32,
    212 => :machine_kmx16,
    213 => :machine_kmx8,
    214 => :machine_kvarc,
    215 => :machine_cdp,
    216 => :machine_coge,
    217 => :machine_cool,
    218 => :machine_norc,
    219 => :machine_csr_kalimba,
    220 => :machine_z80,
    221 => :machine_visium,
    222 => :machine_ft32,
    223 => :machine_moxie,
    224 => :machine_amdgpu,
    243 => :machine_riscv,
    244 => :machine_lanai,
    245 => :machine_ceva,
    246 => :machine_ceva_x2,
    247 => :machine_bpf,
    248 => :machine_graphcore_ipu,
    249 => :machine_img1,
    250 => :machine_nfp,
    251 => :machine_ve,
    252 => :machine_csky,
    253 => :machine_arc_compact3_64,
    254 => :machine_mcs6502,
    255 => :machine_arc_compact3,
    256 => :machine_kvx,
    257 => :machine_wdc_65816,
    258 => :machine_loongarch,
    259 => :machine_kf32,
    260 => :machine_u16_u8core,
    261 => :machine_tachyum,
    262 => :machine_nxp_56800ef,
    263 => :machine_sbf,
    264 => :machine_ai_engine,
    265 => :machine_sima_mla,
    266 => :machine_bang,
    267 => :machine_loonggpu,
    268 => :machine_sw64,
    269 => :machine_ai_engine_ctrlcode,
    270 => :machine_ppu,
    4183 => :machine_avr_old,
    4185 => :machine_msp430_old,
    4643 => :machine_adapteva_epiphany,
    9520 => :machine_mt,
    13104 => :machine_cygnus_fr30,
    16727 => :machine_webassembly,
    18056 => :machine_xc16x,
    19951 => :machine_s12z,
    21569 => :machine_cygnus_frv,
    23205 => :machine_dlx,
    30288 => :machine_cygnus_d10v,
    30326 => :machine_cygnus_d30v,
    33303 => :machine_ip2k_old,
    36901 => :machine_cygnus_powerpc,
    36902 => :machine_alpha,
    36929 => :machine_cygnus_m32r,
    36992 => :machine_cygnus_v850,
    41872 => :machine_s390_old,
    43975 => :machine_xtensa_old,
    44357 => :machine_xstormy16,
    47787 => :machine_microblaze_old,
    48879 => :machine_cygnus_mn10300,
    57005 => :machine_cygnus_mn10200,
    61453 => :machine_cygnus_mep,
    65200 => :machine_m32c_old,
    65210 => :machine_iq2000,
    65211 => :machine_nios32,
    65261 => :machine_moxie_old,
  }
  I__MACHINE = MACHINE.invert

  OBJ_TYPE = {
    0 => :obj_type_no_file_type,
    1 => :obj_type_relocatable,
    2 => :obj_type_executable,
    3 => :obj_type_shared,
    4 => :obj_type_core,
  }
  I__OBJ_TYPE = OBJ_TYPE.invert

  OS_ABI = {
    0 => :os_abi_system_v,
    1 => :os_abi_hp_ux,
    2 => :os_abi_netbsd,
    3 => :os_abi_gnu,
    6 => :os_abi_solaris,
    7 => :os_abi_aix,
    8 => :os_abi_irix,
    9 => :os_abi_freebsd,
    10 => :os_abi_tru64,
    11 => :os_abi_modesto,
    12 => :os_abi_openbsd,
    13 => :os_abi_openvms,
    14 => :os_abi_nsk,
    15 => :os_abi_aros,
    16 => :os_abi_fenixos,
    17 => :os_abi_cloudabi,
    18 => :os_abi_openvos,
    51 => :os_abi_cuda,
    64 => :os_abi_arm_aeabi,
    65 => :os_abi_arm_fdpic,
    66 => :os_abi_amdgpu_mesa3d,
    97 => :os_abi_arm,
    255 => :os_abi_standalone,
  }
  I__OS_ABI = OS_ABI.invert

  PH_TYPE = {
    0 => :ph_type_null_type,
    1 => :ph_type_load,
    2 => :ph_type_dynamic,
    3 => :ph_type_interp,
    4 => :ph_type_note,
    5 => :ph_type_shlib,
    6 => :ph_type_phdr,
    7 => :ph_type_tls,
    1684333904 => :ph_type_sunw_unwind,
    1685382480 => :ph_type_gnu_eh_frame,
    1685382481 => :ph_type_gnu_stack,
    1685382482 => :ph_type_gnu_relro,
    1685382483 => :ph_type_gnu_property,
    1685382484 => :ph_type_gnu_sframe,
    1694766464 => :ph_type_pax_flags,
    1705237477 => :ph_type_openbsd_mutable,
    1705237478 => :ph_type_openbsd_randomize,
    1705237479 => :ph_type_openbsd_wxneeded,
    1705237480 => :ph_type_openbsd_nobtcfi,
    1705237481 => :ph_type_openbsd_syscalls,
    1705253862 => :ph_type_openbsd_bootdata,
    1879048183 => :ph_type_sunw_sysstat_zone,
    1879048184 => :ph_type_sunw_sysstat,
    1879048185 => :ph_type_sunw_reserve,
    1879048186 => :ph_type_sunw_bss,
    1879048187 => :ph_type_sunw_stack,
    1879048188 => :ph_type_sunw_dtrace,
    1879048189 => :ph_type_sunw_cap,
    1879048192 => :ph_type_arm_archext,
    1879048193 => :ph_type_arm_exidx,
    1879048194 => :ph_type_aarch64_memtag_mte,
    1879048195 => :ph_type_riscv_attributes,
  }
  I__PH_TYPE = PH_TYPE.invert

  SECTION_HEADER_IDX_SPECIAL = {
    0 => :section_header_idx_special_undefined,
    65280 => :section_header_idx_special_before,
    65281 => :section_header_idx_special_after,
    65282 => :section_header_idx_special_amd64_lcommon,
    65343 => :section_header_idx_special_sunw_ignore,
    65521 => :section_header_idx_special_abs,
    65522 => :section_header_idx_special_common,
    65535 => :section_header_idx_special_xindex,
  }
  I__SECTION_HEADER_IDX_SPECIAL = SECTION_HEADER_IDX_SPECIAL.invert

  SH_TYPE = {
    0 => :sh_type_null_type,
    1 => :sh_type_progbits,
    2 => :sh_type_symtab,
    3 => :sh_type_strtab,
    4 => :sh_type_rela,
    5 => :sh_type_hash,
    6 => :sh_type_dynamic,
    7 => :sh_type_note,
    8 => :sh_type_nobits,
    9 => :sh_type_rel,
    10 => :sh_type_shlib,
    11 => :sh_type_dynsym,
    14 => :sh_type_init_array,
    15 => :sh_type_fini_array,
    16 => :sh_type_preinit_array,
    17 => :sh_type_group,
    18 => :sh_type_symtab_shndx,
    19 => :sh_type_relr,
    1610612737 => :sh_type_android_rel,
    1610612738 => :sh_type_android_rela,
    1879000832 => :sh_type_gnu_incremental_inputs,
    1879002112 => :sh_type_llvm_odrtab,
    1879002113 => :sh_type_llvm_linker_options,
    1879002115 => :sh_type_llvm_addrsig,
    1879002116 => :sh_type_llvm_dependent_libraries,
    1879002117 => :sh_type_llvm_sympart,
    1879002118 => :sh_type_llvm_part_ehdr,
    1879002119 => :sh_type_llvm_part_phdr,
    1879002120 => :sh_type_llvm_bb_addr_map_v0,
    1879002121 => :sh_type_llvm_call_graph_profile,
    1879002122 => :sh_type_llvm_bb_addr_map,
    1879002123 => :sh_type_llvm_offloading,
    1879002124 => :sh_type_llvm_lto,
    1879002125 => :sh_type_llvm_jt_sizes,
    1879002126 => :sh_type_llvm_cfi_jump_table,
    1879002127 => :sh_type_llvm_call_graph,
    1879002128 => :sh_type_llvm_dyndbg_elf,
    1879047936 => :sh_type_android_relr,
    1879048171 => :sh_type_sunw_ctf,
    1879048172 => :sh_type_sunw_symnsort,
    1879048173 => :sh_type_sunw_phname,
    1879048174 => :sh_type_sunw_ancillary,
    1879048175 => :sh_type_sunw_capchain,
    1879048176 => :sh_type_sunw_capinfo,
    1879048177 => :sh_type_sunw_symsort,
    1879048178 => :sh_type_sunw_tlssort,
    1879048179 => :sh_type_sunw_ldynsym,
    1879048180 => :sh_type_gnu_sframe,
    1879048181 => :sh_type_gnu_attributes,
    1879048182 => :sh_type_gnu_hash,
    1879048183 => :sh_type_gnu_liblist,
    1879048184 => :sh_type_checksum,
    1879048185 => :sh_type_gnu_object_only,
    1879048186 => :sh_type_sunw_move,
    1879048187 => :sh_type_sunw_comdat,
    1879048188 => :sh_type_sunw_syminfo,
    1879048189 => :sh_type_gnu_verdef,
    1879048190 => :sh_type_gnu_verneed,
    1879048191 => :sh_type_gnu_versym,
    1879048192 => :sh_type_sparc_gotdata,
    1879048193 => :sh_type_x86_64_unwind,
    1879048194 => :sh_type_arm_preemptmap,
    1879048195 => :sh_type_arm_attributes,
    1879048196 => :sh_type_arm_debugoverlay,
    1879048197 => :sh_type_arm_overlaysection,
    1879048199 => :sh_type_aarch64_memtag_globals_static,
    1879048200 => :sh_type_aarch64_memtag_globals_dynamic,
  }
  I__SH_TYPE = SH_TYPE.invert

  SYMBOL_BINDING = {
    0 => :symbol_binding_local,
    1 => :symbol_binding_global_symbol,
    2 => :symbol_binding_weak,
    10 => :symbol_binding_os10,
    11 => :symbol_binding_os11,
    12 => :symbol_binding_os12,
    13 => :symbol_binding_proc13,
    14 => :symbol_binding_proc14,
    15 => :symbol_binding_proc15,
  }
  I__SYMBOL_BINDING = SYMBOL_BINDING.invert

  SYMBOL_TYPE = {
    0 => :symbol_type_no_type,
    1 => :symbol_type_object,
    2 => :symbol_type_func,
    3 => :symbol_type_section,
    4 => :symbol_type_file,
    5 => :symbol_type_common,
    6 => :symbol_type_tls,
    8 => :symbol_type_relc,
    9 => :symbol_type_srelc,
    10 => :symbol_type_gnu_ifunc,
    11 => :symbol_type_os11,
    12 => :symbol_type_os12,
    13 => :symbol_type_proc13,
    14 => :symbol_type_proc14,
    15 => :symbol_type_proc15,
  }
  I__SYMBOL_TYPE = SYMBOL_TYPE.invert

  SYMBOL_VISIBILITY = {
    0 => :symbol_visibility_default,
    1 => :symbol_visibility_internal,
    2 => :symbol_visibility_hidden,
    3 => :symbol_visibility_protected,
    4 => :symbol_visibility_exported,
    5 => :symbol_visibility_singleton,
    6 => :symbol_visibility_eliminate,
  }
  I__SYMBOL_VISIBILITY = SYMBOL_VISIBILITY.invert

  VERSION_INDEX_SPECIAL = {
    0 => :version_index_special_local,
    1 => :version_index_special_global_symbol,
    65281 => :version_index_special_eliminate,
  }
  I__VERSION_INDEX_SPECIAL = VERSION_INDEX_SPECIAL.invert
  def initialize(_io, _parent = nil, _root = nil)
    super(_io, _parent, _root || self)
    _read
  end

  def _read
    @magic = @_io.read_bytes(4)
    raise Kaitai::Struct::ValidationNotEqualError.new([127, 69, 76, 70].pack('C*'), @magic, @_io, "/seq/0") if not @magic == [127, 69, 76, 70].pack('C*')
    @bits = Kaitai::Struct::Stream::resolve_enum(BITS, @_io.read_u1)
    @endian = Kaitai::Struct::Stream::resolve_enum(ENDIAN, @_io.read_u1)
    @ei_version = @_io.read_u1
    raise Kaitai::Struct::ValidationNotEqualError.new(1, @ei_version, @_io, "/seq/3") if not @ei_version == 1
    @abi = Kaitai::Struct::Stream::resolve_enum(OS_ABI, @_io.read_u1)
    @abi_version = @_io.read_u1
    @pad = @_io.read_bytes(7)
    raise Kaitai::Struct::ValidationNotEqualError.new([0, 0, 0, 0, 0, 0, 0].pack('C*'), @pad, @_io, "/seq/6") if not @pad == [0, 0, 0, 0, 0, 0, 0].pack('C*')
    @header = EndianElf.new(@_io, self, @_root)
    self
  end

  ##
  # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L1008 Source
  # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html#GUID-4336A69A-D905-4FCE-A398-80375A9E6464__CHAPTER6-TBL-53 Source
  class DtFlag1Values < Kaitai::Struct::Struct
    def initialize(_io, _parent = nil, _root = nil, value)
      super(_io, _parent, _root)
      @value = value
      _read
    end

    def _read
      self
    end

    ##
    # Configuration alternative created.
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L1023 Source
    def conf_alt
      return @conf_alt unless @conf_alt.nil?
      @conf_alt = value & 8192 != 0
      @conf_alt
    end

    ##
    # Direct binding enabled.
    def direct
      return @direct unless @direct.nil?
      @direct = value & 256 != 0
      @direct
    end

    ##
    # Displacement relocation done (applied at build time).
    def disp_rel_dne
      return @disp_rel_dne unless @disp_rel_dne.nil?
      @disp_rel_dne = value & 32768 != 0
      @disp_rel_dne
    end

    ##
    # Displacement relocation pending (applied at runtime).
    def disp_rel_pnd
      return @disp_rel_pnd unless @disp_rel_pnd.nil?
      @disp_rel_pnd = value & 65536 != 0
      @disp_rel_pnd
    end

    ##
    # Object is modified after built.
    def edited
      return @edited unless @edited.nil?
      @edited = value & 2097152 != 0
      @edited
    end

    ##
    # Filtee terminates filters search.
    def end_filtee
      return @end_filtee unless @end_filtee.nil?
      @end_filtee = value & 16384 != 0
      @end_filtee
    end

    ##
    # Global auditing required.
    def glob_audit
      return @glob_audit unless @glob_audit.nil?
      @glob_audit = value & 16777216 != 0
      @glob_audit
    end

    ##
    # Set `RTLD_GROUP` for this object.
    def group
      return @group unless @group.nil?
      @group = value & 4 != 0
      @group
    end
    def ign_mul_def
      return @ign_mul_def unless @ign_mul_def.nil?
      @ign_mul_def = value & 262144 != 0
      @ign_mul_def
    end

    ##
    # Set `RTLD_INITFIRST` for this object.
    def init_first
      return @init_first unless @init_first.nil?
      @init_first = value & 32 != 0
      @init_first
    end

    ##
    # Object is used to interpose.
    def interpose
      return @interpose unless @interpose.nil?
      @interpose = value & 1024 != 0
      @interpose
    end

    ##
    # Object is a kernel module.
    def kmod
      return @kmod unless @kmod.nil?
      @kmod = value & 268435456 != 0
      @kmod
    end

    ##
    # Trigger filtee loading at runtime.
    def load_fltr
      return @load_fltr unless @load_fltr.nil?
      @load_fltr = value & 16 != 0
      @load_fltr
    end

    ##
    # No COMMON symbols exist.
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L1040 Source
    def no_common
      return @no_common unless @no_common.nil?
      @no_common = value & 1073741824 != 0
      @no_common
    end

    ##
    # Ignore the default library search path.
    def no_def_lib
      return @no_def_lib unless @no_def_lib.nil?
      @no_def_lib = value & 2048 != 0
      @no_def_lib
    end

    ##
    # Set `RTLD_NODELETE` for this object.
    def no_delete
      return @no_delete unless @no_delete.nil?
      @no_delete = value & 8 != 0
      @no_delete
    end

    ##
    # Object contains non-direct bindings.
    def no_direct
      return @no_direct unless @no_direct.nil?
      @no_direct = value & 131072 != 0
      @no_direct
    end

    ##
    # Object can't be dldump'ed.
    def no_dump
      return @no_dump unless @no_dump.nil?
      @no_dump = value & 4096 != 0
      @no_dump
    end
    def no_hdr
      return @no_hdr unless @no_hdr.nil?
      @no_hdr = value & 1048576 != 0
      @no_hdr
    end
    def no_ksyms
      return @no_ksyms unless @no_ksyms.nil?
      @no_ksyms = value & 524288 != 0
      @no_ksyms
    end

    ##
    # Set `RTLD_NOOPEN` for this object.
    def no_open
      return @no_open unless @no_open.nil?
      @no_open = value & 64 != 0
      @no_open
    end
    def no_reloc
      return @no_reloc unless @no_reloc.nil?
      @no_reloc = value & 4194304 != 0
      @no_reloc
    end

    ##
    # Set `RTLD_NOW` for this object.
    def now
      return @now unless @now.nil?
      @now = value & 1 != 0
      @now
    end

    ##
    # `$ORIGIN` must be handled.
    def origin
      return @origin unless @origin.nil?
      @origin = value & 128 != 0
      @origin
    end

    ##
    # Object is a Position Independent Executable (PIE).
    def pie
      return @pie unless @pie.nil?
      @pie = value & 134217728 != 0
      @pie
    end

    ##
    # Set `RTLD_GLOBAL` for this object.
    def rtld_global
      return @rtld_global unless @rtld_global.nil?
      @rtld_global = value & 2 != 0
      @rtld_global
    end

    ##
    # Singleton symbols are used.
    def singleton
      return @singleton unless @singleton.nil?
      @singleton = value & 33554432 != 0
      @singleton
    end

    ##
    # Object is a stub.
    # See [Stub Objects](https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/stub-objects.html).
    def stub
      return @stub unless @stub.nil?
      @stub = value & 67108864 != 0
      @stub
    end

    ##
    # Object has individual symbol interposers.
    def sym_intpose
      return @sym_intpose unless @sym_intpose.nil?
      @sym_intpose = value & 8388608 != 0
      @sym_intpose
    end

    ##
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L1019 Source
    def trans
      return @trans unless @trans.nil?
      @trans = value & 512 != 0
      @trans
    end

    ##
    # Object is a weak standard filter.
    def weak_filter
      return @weak_filter unless @weak_filter.nil?
      @weak_filter = value & 536870912 != 0
      @weak_filter
    end
    attr_reader :value
  end

  ##
  # @see https://refspecs.linuxbase.org/elf/gabi4+/ch5.dynamic.html Figure 5-11: DT_FLAGS values
  # @see https://github.com/golang/go/blob/48dfddbab3/src/debug/elf/elf.go#L1079-L1095 Source
  # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html#GUID-4336A69A-D905-4FCE-A398-80375A9E6464__CHAPTER7-TBL-5 Source
  class DtFlagValues < Kaitai::Struct::Struct
    def initialize(_io, _parent = nil, _root = nil, value)
      super(_io, _parent, _root)
      @value = value
      _read
    end

    def _read
      self
    end

    ##
    # all relocations for this object must be processed before returning
    # control to the program
    def bind_now
      return @bind_now unless @bind_now.nil?
      @bind_now = value & 8 != 0
      @bind_now
    end

    ##
    # object may reference the $ORIGIN substitution string
    def origin
      return @origin unless @origin.nil?
      @origin = value & 1 != 0
      @origin
    end

    ##
    # object uses static thread-local storage scheme
    def static_tls
      return @static_tls unless @static_tls.nil?
      @static_tls = value & 16 != 0
      @static_tls
    end

    ##
    # symbolic linking
    def symbolic
      return @symbolic unless @symbolic.nil?
      @symbolic = value & 2 != 0
      @symbolic
    end

    ##
    # relocation entries might request modifications to a non-writable segment
    def textrel
      return @textrel unless @textrel.nil?
      @textrel = value & 4 != 0
      @textrel
    end
    attr_reader :value
  end

  ##
  # @see https://gabi.xinuos.com/v42/elf/02-eheader.html Source
  # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/elf-header.html Source
  class EndianElf < Kaitai::Struct::Struct
    def initialize(_io, _parent = nil, _root = nil)
      super(_io, _parent, _root)
      _read
    end

    def _read
      case _root.endian
      when :endian_le
        @_is_le = true
      when :endian_be
        @_is_le = false
      end

      if @_is_le == true
        _read_le
      elsif @_is_le == false
        _read_be
      else
        raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf")
      end
      self
    end

    def _read_le
      @e_type = Kaitai::Struct::Stream::resolve_enum(Elf::OBJ_TYPE, @_io.read_u2le)
      @machine = Kaitai::Struct::Stream::resolve_enum(Elf::MACHINE, @_io.read_u2le)
      raise Kaitai::Struct::ValidationNotInEnumError.new(@machine, @_io, "/types/endian_elf/seq/1") if not Elf::I__MACHINE.key?(@machine)
      @e_version = @_io.read_u4le
      case _root.bits
      when :bits_b32
        @entry_point = @_io.read_u4le
      when :bits_b64
        @entry_point = @_io.read_u8le
      end
      case _root.bits
      when :bits_b32
        @ofs_program_headers = @_io.read_u4le
      when :bits_b64
        @ofs_program_headers = @_io.read_u8le
      end
      case _root.bits
      when :bits_b32
        @ofs_section_headers = @_io.read_u4le
      when :bits_b64
        @ofs_section_headers = @_io.read_u8le
      end
      @flags = @_io.read_bytes(4)
      @e_ehsize = @_io.read_u2le
      @program_header_size = @_io.read_u2le
      @num_program_headers = @_io.read_u2le
      @section_header_size = @_io.read_u2le
      @num_section_headers = @_io.read_u2le
      @section_names_idx = @_io.read_u2le
      self
    end

    def _read_be
      @e_type = Kaitai::Struct::Stream::resolve_enum(Elf::OBJ_TYPE, @_io.read_u2be)
      @machine = Kaitai::Struct::Stream::resolve_enum(Elf::MACHINE, @_io.read_u2be)
      raise Kaitai::Struct::ValidationNotInEnumError.new(@machine, @_io, "/types/endian_elf/seq/1") if not Elf::I__MACHINE.key?(@machine)
      @e_version = @_io.read_u4be
      case _root.bits
      when :bits_b32
        @entry_point = @_io.read_u4be
      when :bits_b64
        @entry_point = @_io.read_u8be
      end
      case _root.bits
      when :bits_b32
        @ofs_program_headers = @_io.read_u4be
      when :bits_b64
        @ofs_program_headers = @_io.read_u8be
      end
      case _root.bits
      when :bits_b32
        @ofs_section_headers = @_io.read_u4be
      when :bits_b64
        @ofs_section_headers = @_io.read_u8be
      end
      @flags = @_io.read_bytes(4)
      @e_ehsize = @_io.read_u2be
      @program_header_size = @_io.read_u2be
      @num_program_headers = @_io.read_u2be
      @section_header_size = @_io.read_u2be
      @num_section_headers = @_io.read_u2be
      @section_names_idx = @_io.read_u2be
      self
    end
    class DynsymSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/dynsym_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << DynsymSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end

      def _read_be
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << DynsymSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end
      def is_string_table_linked
        return @is_string_table_linked unless @is_string_table_linked.nil?
        @is_string_table_linked = _parent.linked_section.type == :sh_type_strtab
        @is_string_table_linked
      end
      attr_reader :entries
    end

    ##
    # @see https://gabi.xinuos.com/elf/05-symtab.html Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/symbol-table-section.html Source
    class DynsymSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/dynsym_section_entry")
        end
        self
      end

      def _read_le
        @ofs_name = @_io.read_u4le
        if _root.bits == :bits_b32
          @value_b32 = @_io.read_u4le
        end
        if _root.bits == :bits_b32
          @size_b32 = @_io.read_u4le
        end
        @bind = Kaitai::Struct::Stream::resolve_enum(Elf::SYMBOL_BINDING, @_io.read_bits_int_be(4))
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::SYMBOL_TYPE, @_io.read_bits_int_be(4))
        @_io.align_to_byte
        @other = @_io.read_u1
        @sh_idx = @_io.read_u2le
        if _root.bits == :bits_b64
          @value_b64 = @_io.read_u8le
        end
        if _root.bits == :bits_b64
          @size_b64 = @_io.read_u8le
        end
        self
      end

      def _read_be
        @ofs_name = @_io.read_u4be
        if _root.bits == :bits_b32
          @value_b32 = @_io.read_u4be
        end
        if _root.bits == :bits_b32
          @size_b32 = @_io.read_u4be
        end
        @bind = Kaitai::Struct::Stream::resolve_enum(Elf::SYMBOL_BINDING, @_io.read_bits_int_be(4))
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::SYMBOL_TYPE, @_io.read_bits_int_be(4))
        @_io.align_to_byte
        @other = @_io.read_u1
        @sh_idx = @_io.read_u2be
        if _root.bits == :bits_b64
          @value_b64 = @_io.read_u8be
        end
        if _root.bits == :bits_b64
          @size_b64 = @_io.read_u8be
        end
        self
      end
      def is_sh_idx_os
        return @is_sh_idx_os unless @is_sh_idx_os.nil?
        @is_sh_idx_os =  ((sh_idx >= _root.sh_idx_lo_os) && (sh_idx <= _root.sh_idx_hi_os)) 
        @is_sh_idx_os
      end
      def is_sh_idx_proc
        return @is_sh_idx_proc unless @is_sh_idx_proc.nil?
        @is_sh_idx_proc =  ((sh_idx >= _root.sh_idx_lo_proc) && (sh_idx <= _root.sh_idx_hi_proc)) 
        @is_sh_idx_proc
      end
      def is_sh_idx_reserved
        return @is_sh_idx_reserved unless @is_sh_idx_reserved.nil?
        @is_sh_idx_reserved =  ((sh_idx >= _root.sh_idx_lo_reserved) && (sh_idx <= _root.sh_idx_hi_reserved)) 
        @is_sh_idx_reserved
      end
      def name
        return @name unless @name.nil?
        if  ((ofs_name != 0) && (_parent.is_string_table_linked)) 
          io = _parent._parent.linked_section.body._io
          _pos = io.pos
          io.seek(ofs_name)
          if @_is_le
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          else
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          end
          io.seek(_pos)
        end
        @name
      end
      def sh_idx_special
        return @sh_idx_special unless @sh_idx_special.nil?
        @sh_idx_special = Kaitai::Struct::Stream::resolve_enum(Elf::SECTION_HEADER_IDX_SPECIAL, sh_idx)
        @sh_idx_special
      end
      def size
        return @size unless @size.nil?
        @size = (_root.bits == :bits_b32 ? size_b32 : (_root.bits == :bits_b64 ? size_b64 : 0))
        @size
      end
      def value
        return @value unless @value.nil?
        @value = (_root.bits == :bits_b32 ? value_b32 : (_root.bits == :bits_b64 ? value_b64 : 0))
        @value
      end

      ##
      # @see https://github.com/xinuos/gabi/commit/acd5ebb2962cf243dca4983bc934442b42ef96f5 Source
      def visibility
        return @visibility unless @visibility.nil?
        @visibility = Kaitai::Struct::Stream::resolve_enum(Elf::SYMBOL_VISIBILITY, other & 7)
        @visibility
      end
      attr_reader :ofs_name
      attr_reader :value_b32
      attr_reader :size_b32
      attr_reader :bind
      attr_reader :type

      ##
      # don't read this field, access `visibility` instead
      attr_reader :other

      ##
      # section header index
      attr_reader :sh_idx
      attr_reader :value_b64
      attr_reader :size_b64
    end
    class NoteSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/note_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << NoteSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end

      def _read_be
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << NoteSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end
      attr_reader :entries
    end

    ##
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/note-section.html Source
    # @see https://refspecs.linuxfoundation.org/elf/gabi4+/ch5.pheader.html#note_section Source
    class NoteSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/note_section_entry")
        end
        self
      end

      def _read_le
        @len_name = @_io.read_u4le
        @len_descriptor = @_io.read_u4le
        @type = @_io.read_u4le
        @name = Kaitai::Struct::Stream::bytes_terminate(@_io.read_bytes(len_name), 0, false)
        @name_padding = @_io.read_bytes(-(len_name) % 4)
        @descriptor = @_io.read_bytes(len_descriptor)
        @descriptor_padding = @_io.read_bytes(-(len_descriptor) % 4)
        self
      end

      def _read_be
        @len_name = @_io.read_u4be
        @len_descriptor = @_io.read_u4be
        @type = @_io.read_u4be
        @name = Kaitai::Struct::Stream::bytes_terminate(@_io.read_bytes(len_name), 0, false)
        @name_padding = @_io.read_bytes(-(len_name) % 4)
        @descriptor = @_io.read_bytes(len_descriptor)
        @descriptor_padding = @_io.read_bytes(-(len_descriptor) % 4)
        self
      end
      attr_reader :len_name
      attr_reader :len_descriptor
      attr_reader :type

      ##
      # Although the ELF specification seems to hint that the `note_name` field
      # is ASCII this isn't the case for Linux binaries that have a
      # `.gnu.build.attributes` section.
      # @see https://fedoraproject.org/wiki/Toolchain/Watermark#Proposed_Specification_for_non-loaded_notes Source
      attr_reader :name
      attr_reader :name_padding
      attr_reader :descriptor
      attr_reader :descriptor_padding
    end

    ##
    # Same type as `sh_dynamic_section`, but it does not use
    # `_parent.linked_section`, which is available only in section headers
    # (i.e. when `_parent` is of type `section_header`). This allows it to
    # be used in program headers (i.e. from the `program_header` type).
    # 
    # The inability to access `linked_section` means that offsets in the
    # string table (which should be stored in the `.dynstr` section) will
    # not be resolved to strings and will be provided only in raw form in
    # the `value_or_ptr` field. In other words, the
    # `ph_dynamic_section_entry` type has no `value_str` instance, unlike
    # the `sh_dynamic_section_entry` type.
    # 
    # There is another way to find the string table referenced by the
    # dynamic section entries that does not rely on `linked_section`, but is
    # a bit more complex (and is therefore considered out of scope of this
    # .ksy spec): the mandatory dynamic tag `dynamic_array_tags::strtab`
    # (`DT_STRTAB`) specifies the virtual address of the string table, and
    # `dynamic_array_tags::strsz` (`DT_STRSZ`) specifies its size in bytes.
    # The virtual address can be converted to a file offset by reading the
    # program headers - see the source code for the `readelf` command:
    # 
    # 1. [`offset_from_vma` call site with an address from `DT_STRTAB` as an
    #   argument](https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/binutils/readelf.c#L13018)
    # 2. [`offset_from_vma` function
    #   definition](https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/binutils/readelf.c#L7788)
    # @see https://gabi.xinuos.com/v42/elf/08-dynamic.html#dynamic-section Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html Source
    class PhDynamicSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/ph_dynamic_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        begin
          _ = PhDynamicSectionEntry.new(@_io, self, @_root, @_is_le)
          @entries << _
          i += 1
        end until _.tag_enum == :dynamic_array_tags_null
        self
      end

      def _read_be
        @entries = []
        i = 0
        begin
          _ = PhDynamicSectionEntry.new(@_io, self, @_root, @_is_le)
          @entries << _
          i += 1
        end until _.tag_enum == :dynamic_array_tags_null
        self
      end
      attr_reader :entries
    end

    ##
    # Same type as `sh_dynamic_section_entry`, but without the `value_str`
    # instance - see the documentation for `ph_dynamic_section` for more
    # details.
    # @see https://gabi.xinuos.com/v42/elf/08-dynamic.html#dynamic-section Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html Source
    class PhDynamicSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/ph_dynamic_section_entry")
        end
        self
      end

      def _read_le
        case _root.bits
        when :bits_b32
          @tag = @_io.read_u4le
        when :bits_b64
          @tag = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @value_or_ptr = @_io.read_u4le
        when :bits_b64
          @value_or_ptr = @_io.read_u8le
        end
        self
      end

      def _read_be
        case _root.bits
        when :bits_b32
          @tag = @_io.read_u4be
        when :bits_b64
          @tag = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @value_or_ptr = @_io.read_u4be
        when :bits_b64
          @value_or_ptr = @_io.read_u8be
        end
        self
      end
      def flag_1_values
        return @flag_1_values unless @flag_1_values.nil?
        if tag_enum == :dynamic_array_tags_flags_1
          if @_is_le
            @flag_1_values = DtFlag1Values.new(@_io, self, @_root, value_or_ptr)
          else
            @flag_1_values = DtFlag1Values.new(@_io, self, @_root, value_or_ptr)
          end
        end
        @flag_1_values
      end
      def flag_values
        return @flag_values unless @flag_values.nil?
        if tag_enum == :dynamic_array_tags_flags
          if @_is_le
            @flag_values = DtFlagValues.new(@_io, self, @_root, value_or_ptr)
          else
            @flag_values = DtFlagValues.new(@_io, self, @_root, value_or_ptr)
          end
        end
        @flag_values
      end
      def is_value_str
        return @is_value_str unless @is_value_str.nil?
        @is_value_str =  ((value_or_ptr != 0) && ( ((tag_enum == :dynamic_array_tags_needed) || (tag_enum == :dynamic_array_tags_soname) || (tag_enum == :dynamic_array_tags_rpath) || (tag_enum == :dynamic_array_tags_runpath) || (tag_enum == :dynamic_array_tags_sunw_auxiliary) || (tag_enum == :dynamic_array_tags_sunw_filter) || (tag_enum == :dynamic_array_tags_auxiliary) || (tag_enum == :dynamic_array_tags_filter) || (tag_enum == :dynamic_array_tags_config) || (tag_enum == :dynamic_array_tags_depaudit) || (tag_enum == :dynamic_array_tags_audit)) )) 
        @is_value_str
      end
      def tag_enum
        return @tag_enum unless @tag_enum.nil?
        @tag_enum = Kaitai::Struct::Stream::resolve_enum(Elf::DYNAMIC_ARRAY_TAGS, tag)
        @tag_enum
      end
      attr_reader :tag
      attr_reader :value_or_ptr
    end

    ##
    # @see https://gabi.xinuos.com/v42/elf/07-pheader.html#program-header-entry Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/program-header.html Source
    class ProgramHeader < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/program_header")
        end
        self
      end

      def _read_le
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::PH_TYPE, @_io.read_u4le)
        if _root.bits == :bits_b64
          @flags64 = @_io.read_u4le
        end
        case _root.bits
        when :bits_b32
          @ofs_body = @_io.read_u4le
        when :bits_b64
          @ofs_body = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @virt_addr = @_io.read_u4le
        when :bits_b64
          @virt_addr = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @phys_addr = @_io.read_u4le
        when :bits_b64
          @phys_addr = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @len_body = @_io.read_u4le
        when :bits_b64
          @len_body = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @memory_size = @_io.read_u4le
        when :bits_b64
          @memory_size = @_io.read_u8le
        end
        if _root.bits == :bits_b32
          @flags32 = @_io.read_u4le
        end
        case _root.bits
        when :bits_b32
          @align = @_io.read_u4le
        when :bits_b64
          @align = @_io.read_u8le
        end
        self
      end

      def _read_be
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::PH_TYPE, @_io.read_u4be)
        if _root.bits == :bits_b64
          @flags64 = @_io.read_u4be
        end
        case _root.bits
        when :bits_b32
          @ofs_body = @_io.read_u4be
        when :bits_b64
          @ofs_body = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @virt_addr = @_io.read_u4be
        when :bits_b64
          @virt_addr = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @phys_addr = @_io.read_u4be
        when :bits_b64
          @phys_addr = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @len_body = @_io.read_u4be
        when :bits_b64
          @len_body = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @memory_size = @_io.read_u4be
        when :bits_b64
          @memory_size = @_io.read_u8be
        end
        if _root.bits == :bits_b32
          @flags32 = @_io.read_u4be
        end
        case _root.bits
        when :bits_b32
          @align = @_io.read_u4be
        when :bits_b64
          @align = @_io.read_u8be
        end
        self
      end

      ##
      # @see https://gabi.xinuos.com/v42/elf/08-dynamic.html#program-interpreter Source
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/program-interpreter.html Source
      class PhInterpreter < Kaitai::Struct::Struct
        def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
          super(_io, _parent, _root)
          @_is_le = _is_le
          _read
        end

        def _read

          if @_is_le == true
            _read_le
          elsif @_is_le == false
            _read_be
          else
            raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/program_header/types/ph_interpreter")
          end
          self
        end

        def _read_le
          @path_name = (@_io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
          self
        end

        def _read_be
          @path_name = (@_io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
          self
        end
        attr_reader :path_name
      end

      ##
      # Note: a program header may not have a valid body in the same ELF
      # file, so accessing `body` may result in reading garbage or
      # triggering EOF errors.
      # 
      # In particular, `*.debug` files produced by elfutils'
      # `eu-strip --strip-debug` (as used by Fedora/RHEL and other
      # RPM-based distros for their `*-debuginfo` packages, e.g.
      # `glibc-debuginfo`) copy the original binary's program header table
      # verbatim, including `ofs_body`/`len_body` (i.e.
      # `p_offset`/`p_filesz`), while dropping the actual contents of most
      # segments. Such segments can be recognized by the fact that the
      # corresponding section headers have type `sh_type::nobits`
      # (`SHT_NOBITS`). However, this Kaitai Struct implementation doesn't
      # know the mapping between program headers and section headers, so
      # this must be handled externally.
      # 
      # `*.debug` files from Debian/Ubuntu `*-dbg` packages (e.g.
      # `libc6-dbg`) are usually not affected by this issue, because they
      # are produced using GNU Binutils (`objcopy --only-keep-debug`),
      # which zeroes `len_body` for segments whose contents were omitted
      # (which reliably tells us that there is no `body`).
      def body
        return @body unless @body.nil?
        if len_body != 0
          io = _root._io
          _pos = io.pos
          io.seek(ofs_body)
          if @_is_le
            case type
            when :ph_type_dynamic
              _io_body = io.substream(len_body)
              @body = PhDynamicSection.new(_io_body, self, @_root, @_is_le)
            when :ph_type_interp
              _io_body = io.substream(len_body)
              @body = PhInterpreter.new(_io_body, self, @_root, @_is_le)
            when :ph_type_note
              _io_body = io.substream(len_body)
              @body = NoteSection.new(_io_body, self, @_root, @_is_le)
            else
              @body = io.read_bytes(len_body)
            end
          else
            case type
            when :ph_type_dynamic
              _io_body = io.substream(len_body)
              @body = PhDynamicSection.new(_io_body, self, @_root, @_is_le)
            when :ph_type_interp
              _io_body = io.substream(len_body)
              @body = PhInterpreter.new(_io_body, self, @_root, @_is_le)
            when :ph_type_note
              _io_body = io.substream(len_body)
              @body = NoteSection.new(_io_body, self, @_root, @_is_le)
            else
              @body = io.read_bytes(len_body)
            end
          end
          io.seek(_pos)
        end
        @body
      end
      def flags_obj
        return @flags_obj unless @flags_obj.nil?
        if @_is_le
          case _root.bits
          when :bits_b32
            @flags_obj = PhdrTypeFlags.new(@_io, self, @_root, flags32)
          when :bits_b64
            @flags_obj = PhdrTypeFlags.new(@_io, self, @_root, flags64)
          end
        else
          case _root.bits
          when :bits_b32
            @flags_obj = PhdrTypeFlags.new(@_io, self, @_root, flags32)
          when :bits_b64
            @flags_obj = PhdrTypeFlags.new(@_io, self, @_root, flags64)
          end
        end
        @flags_obj
      end
      attr_reader :type
      attr_reader :flags64
      attr_reader :ofs_body
      attr_reader :virt_addr
      attr_reader :phys_addr
      attr_reader :len_body
      attr_reader :memory_size
      attr_reader :flags32
      attr_reader :align
      attr_reader :_raw_body
    end

    ##
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/relocation-sections.html Source
    # @see https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.reloc.html Source
    class RelocationSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil, has_addend)
        super(_io, _parent, _root)
        @_is_le = _is_le
        @has_addend = has_addend
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/relocation_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << RelocationSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end

      def _read_be
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << RelocationSectionEntry.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end
      attr_reader :entries
      attr_reader :has_addend
    end
    class RelocationSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/relocation_section_entry")
        end
        self
      end

      def _read_le
        case _root.bits
        when :bits_b32
          @offset = @_io.read_u4le
        when :bits_b64
          @offset = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @info = @_io.read_u4le
        when :bits_b64
          @info = @_io.read_u8le
        end
        if _parent.has_addend
          case _root.bits
          when :bits_b32
            @addend = @_io.read_s4le
          when :bits_b64
            @addend = @_io.read_s8le
          end
        end
        self
      end

      def _read_be
        case _root.bits
        when :bits_b32
          @offset = @_io.read_u4be
        when :bits_b64
          @offset = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @info = @_io.read_u4be
        when :bits_b64
          @info = @_io.read_u8be
        end
        if _parent.has_addend
          case _root.bits
          when :bits_b32
            @addend = @_io.read_s4be
          when :bits_b64
            @addend = @_io.read_s8be
          end
        end
        self
      end
      attr_reader :offset
      attr_reader :info
      attr_reader :addend
    end

    ##
    # @see https://gabi.xinuos.com/v42/elf/03-sheader.html#section-header-table-entry Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html Source
    class SectionHeader < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/section_header")
        end
        self
      end

      def _read_le
        @ofs_name = @_io.read_u4le
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::SH_TYPE, @_io.read_u4le)
        case _root.bits
        when :bits_b32
          @flags = @_io.read_u4le
        when :bits_b64
          @flags = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @addr = @_io.read_u4le
        when :bits_b64
          @addr = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @ofs_body = @_io.read_u4le
        when :bits_b64
          @ofs_body = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @len_body = @_io.read_u4le
        when :bits_b64
          @len_body = @_io.read_u8le
        end
        @linked_section_idx = @_io.read_u4le
        @info = @_io.read_u4le
        case _root.bits
        when :bits_b32
          @align = @_io.read_u4le
        when :bits_b64
          @align = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @entry_size = @_io.read_u4le
        when :bits_b64
          @entry_size = @_io.read_u8le
        end
        self
      end

      def _read_be
        @ofs_name = @_io.read_u4be
        @type = Kaitai::Struct::Stream::resolve_enum(Elf::SH_TYPE, @_io.read_u4be)
        case _root.bits
        when :bits_b32
          @flags = @_io.read_u4be
        when :bits_b64
          @flags = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @addr = @_io.read_u4be
        when :bits_b64
          @addr = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @ofs_body = @_io.read_u4be
        when :bits_b64
          @ofs_body = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @len_body = @_io.read_u4be
        when :bits_b64
          @len_body = @_io.read_u8be
        end
        @linked_section_idx = @_io.read_u4be
        @info = @_io.read_u4be
        case _root.bits
        when :bits_b32
          @align = @_io.read_u4be
        when :bits_b64
          @align = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @entry_size = @_io.read_u4be
        when :bits_b64
          @entry_size = @_io.read_u8be
        end
        self
      end
      def body
        return @body unless @body.nil?
        if type != :sh_type_nobits
          io = _root._io
          _pos = io.pos
          io.seek(ofs_body)
          if @_is_le
            case type
            when :sh_type_dynamic
              _io_body = io.substream(len_body)
              @body = ShDynamicSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_dynsym
              _io_body = io.substream(len_body)
              @body = DynsymSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_verdef
              _io_body = io.substream(len_body)
              @body = VerdefSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_verneed
              _io_body = io.substream(len_body)
              @body = VerneedSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_versym
              _io_body = io.substream(len_body)
              @body = VersymSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_note
              _io_body = io.substream(len_body)
              @body = NoteSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_rel
              _io_body = io.substream(len_body)
              @body = RelocationSection.new(_io_body, self, @_root, @_is_le, false)
            when :sh_type_rela
              _io_body = io.substream(len_body)
              @body = RelocationSection.new(_io_body, self, @_root, @_is_le, true)
            when :sh_type_strtab
              _io_body = io.substream(len_body)
              @body = StringsStruct.new(_io_body, self, @_root, @_is_le)
            when :sh_type_symtab
              _io_body = io.substream(len_body)
              @body = DynsymSection.new(_io_body, self, @_root, @_is_le)
            else
              @body = io.read_bytes(len_body)
            end
          else
            case type
            when :sh_type_dynamic
              _io_body = io.substream(len_body)
              @body = ShDynamicSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_dynsym
              _io_body = io.substream(len_body)
              @body = DynsymSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_verdef
              _io_body = io.substream(len_body)
              @body = VerdefSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_verneed
              _io_body = io.substream(len_body)
              @body = VerneedSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_gnu_versym
              _io_body = io.substream(len_body)
              @body = VersymSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_note
              _io_body = io.substream(len_body)
              @body = NoteSection.new(_io_body, self, @_root, @_is_le)
            when :sh_type_rel
              _io_body = io.substream(len_body)
              @body = RelocationSection.new(_io_body, self, @_root, @_is_le, false)
            when :sh_type_rela
              _io_body = io.substream(len_body)
              @body = RelocationSection.new(_io_body, self, @_root, @_is_le, true)
            when :sh_type_strtab
              _io_body = io.substream(len_body)
              @body = StringsStruct.new(_io_body, self, @_root, @_is_le)
            when :sh_type_symtab
              _io_body = io.substream(len_body)
              @body = DynsymSection.new(_io_body, self, @_root, @_is_le)
            else
              @body = io.read_bytes(len_body)
            end
          end
          io.seek(_pos)
        end
        @body
      end
      def flags_obj
        return @flags_obj unless @flags_obj.nil?
        if @_is_le
          @flags_obj = SectionHeaderFlags.new(@_io, self, @_root, flags)
        else
          @flags_obj = SectionHeaderFlags.new(@_io, self, @_root, flags)
        end
        @flags_obj
      end

      ##
      # may reference a later section header, so don't try to access too early (use only lazy `instances`)
      # @see https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.sheader.html#sh_link Source
      def linked_section
        return @linked_section unless @linked_section.nil?
        if  ((linked_section_idx != (Elf::I__SECTION_HEADER_IDX_SPECIAL[:section_header_idx_special_undefined] || :section_header_idx_special_undefined)) && (linked_section_idx < _root.header.num_section_headers)) 
          @linked_section = _root.header.section_headers[linked_section_idx]
        end
        @linked_section
      end
      def name
        return @name unless @name.nil?
        io = _root.header.section_names._io
        _pos = io.pos
        io.seek(ofs_name)
        if @_is_le
          @name = (io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
        else
          @name = (io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
        end
        io.seek(_pos)
        @name
      end
      attr_reader :ofs_name
      attr_reader :type
      attr_reader :flags
      attr_reader :addr
      attr_reader :ofs_body
      attr_reader :len_body
      attr_reader :linked_section_idx
      attr_reader :info
      attr_reader :align
      attr_reader :entry_size
      attr_reader :_raw_body
    end

    ##
    # Same type as `ph_dynamic_section`, but it depends on
    # `_parent.linked_section`, so it can be used only in the
    # `section_header` type. See the documentation for `ph_dynamic_section`
    # for more details.
    # @see https://gabi.xinuos.com/v42/elf/08-dynamic.html#dynamic-section Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html Source
    class ShDynamicSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/sh_dynamic_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        begin
          _ = ShDynamicSectionEntry.new(@_io, self, @_root, @_is_le)
          @entries << _
          i += 1
        end until _.tag_enum == :dynamic_array_tags_null
        self
      end

      def _read_be
        @entries = []
        i = 0
        begin
          _ = ShDynamicSectionEntry.new(@_io, self, @_root, @_is_le)
          @entries << _
          i += 1
        end until _.tag_enum == :dynamic_array_tags_null
        self
      end
      def is_string_table_linked
        return @is_string_table_linked unless @is_string_table_linked.nil?
        @is_string_table_linked = _parent.linked_section.type == :sh_type_strtab
        @is_string_table_linked
      end
      attr_reader :entries
    end

    ##
    # Same type as `ph_dynamic_section_entry`, but with the `value_str`
    # instance - see the documentation for `ph_dynamic_section` for more
    # details.
    # @see https://gabi.xinuos.com/v42/elf/08-dynamic.html#dynamic-section Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/dynamic-section.html Source
    class ShDynamicSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/sh_dynamic_section_entry")
        end
        self
      end

      def _read_le
        case _root.bits
        when :bits_b32
          @tag = @_io.read_u4le
        when :bits_b64
          @tag = @_io.read_u8le
        end
        case _root.bits
        when :bits_b32
          @value_or_ptr = @_io.read_u4le
        when :bits_b64
          @value_or_ptr = @_io.read_u8le
        end
        self
      end

      def _read_be
        case _root.bits
        when :bits_b32
          @tag = @_io.read_u4be
        when :bits_b64
          @tag = @_io.read_u8be
        end
        case _root.bits
        when :bits_b32
          @value_or_ptr = @_io.read_u4be
        when :bits_b64
          @value_or_ptr = @_io.read_u8be
        end
        self
      end
      def flag_1_values
        return @flag_1_values unless @flag_1_values.nil?
        if tag_enum == :dynamic_array_tags_flags_1
          if @_is_le
            @flag_1_values = DtFlag1Values.new(@_io, self, @_root, value_or_ptr)
          else
            @flag_1_values = DtFlag1Values.new(@_io, self, @_root, value_or_ptr)
          end
        end
        @flag_1_values
      end
      def flag_values
        return @flag_values unless @flag_values.nil?
        if tag_enum == :dynamic_array_tags_flags
          if @_is_le
            @flag_values = DtFlagValues.new(@_io, self, @_root, value_or_ptr)
          else
            @flag_values = DtFlagValues.new(@_io, self, @_root, value_or_ptr)
          end
        end
        @flag_values
      end
      def is_value_str
        return @is_value_str unless @is_value_str.nil?
        @is_value_str =  ((value_or_ptr != 0) && ( ((tag_enum == :dynamic_array_tags_needed) || (tag_enum == :dynamic_array_tags_soname) || (tag_enum == :dynamic_array_tags_rpath) || (tag_enum == :dynamic_array_tags_runpath) || (tag_enum == :dynamic_array_tags_sunw_auxiliary) || (tag_enum == :dynamic_array_tags_sunw_filter) || (tag_enum == :dynamic_array_tags_auxiliary) || (tag_enum == :dynamic_array_tags_filter) || (tag_enum == :dynamic_array_tags_config) || (tag_enum == :dynamic_array_tags_depaudit) || (tag_enum == :dynamic_array_tags_audit)) )) 
        @is_value_str
      end
      def tag_enum
        return @tag_enum unless @tag_enum.nil?
        @tag_enum = Kaitai::Struct::Stream::resolve_enum(Elf::DYNAMIC_ARRAY_TAGS, tag)
        @tag_enum
      end
      def value_str
        return @value_str unless @value_str.nil?
        if  ((is_value_str) && (_parent.is_string_table_linked)) 
          io = _parent._parent.linked_section.body._io
          _pos = io.pos
          io.seek(value_or_ptr)
          if @_is_le
            @value_str = (io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
          else
            @value_str = (io.read_bytes_term(0, false, true, true)).force_encoding("ASCII").encode('UTF-8')
          end
          io.seek(_pos)
        end
        @value_str
      end
      attr_reader :tag
      attr_reader :value_or_ptr
    end
    class StringsStruct < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/strings_struct")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << (@_io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          i += 1
        end
        self
      end

      def _read_be
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << (@_io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          i += 1
        end
        self
      end
      attr_reader :entries
    end

    ##
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#VERDEFEXTS Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-definition-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VerdauxEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/verdaux_entry")
        end
        self
      end

      def _read_le
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @ofs_name = @_io.read_u4le
        @ofs_next = @_io.read_u4le
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verdaux_entry/seq/2") if not  ((_ == 0) || (_ >= 8)) 
        self
      end

      def _read_be
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @ofs_name = @_io.read_u4be
        @ofs_next = @_io.read_u4be
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verdaux_entry/seq/2") if not  ((_ == 0) || (_ >= 8)) 
        self
      end
      def name
        return @name unless @name.nil?
        if _parent.is_string_table_linked
          io = _parent._parent.linked_section.body._io
          _pos = io.pos
          io.seek(ofs_name)
          if @_is_le
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          else
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          end
          io.seek(_pos)
        end
        @name
      end
      def next
        return @next unless @next.nil?
        if ofs_next != 0
          _pos = @_io.pos
          @_io.seek(ofs_start + ofs_next)
          if @_is_le
            @next = VerdauxEntry.new(@_io, _parent, @_root, @_is_le)
          else
            @next = VerdauxEntry.new(@_io, _parent, @_root, @_is_le)
          end
          @_io.seek(_pos)
        end
        @next
      end
      def ofs_start
        return @ofs_start unless @ofs_start.nil?
        @ofs_start = _io.pos
        @ofs_start
      end
      attr_reader :_unnamed0

      ##
      # Byte offset to the version or dependency name string in the linked
      # string table.
      attr_reader :ofs_name

      ##
      # Byte offset to the next verdaux entry, relative to the start of
      # this `verdaux_entry`. A value of zero means that there is no next
      # entry.
      attr_reader :ofs_next
    end

    ##
    # Version Definitions, contained in the special section named
    # `.gnu.version_d` with the section type `sh_type::gnu_verdef`
    # (`SHT_GNU_verdef`).
    # 
    # The number of entries in this section must match the value of the
    # dynamic tag `dynamic_array_tags::verdefnum` (`DT_VERDEFNUM`) in the
    # Dynamic Section (`.dynamic`).
    # 
    # `_parent.linked_section` must be the string table that contains the
    # strings referenced by this section. Specifically, the string table in
    # the `.dynstr` section should be used (side note: the `readelf` command
    # doesn't even check which string table `sh_link` points to, and always
    # uses `.dynstr` for the lookups - see
    # <https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/binutils/readelf.c#L13787>).
    # 
    # The `is_string_table_linked` value instance indicates whether the
    # string table is linked. If it is not, version names (the `name`
    # instance in the `verdaux_entry` type) will not be available.
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMVERDEFS Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-definition-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VerdefSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/verdef_section")
        end
        self
      end

      def _read_le
        @first_entry = VerdefSectionEntry.new(@_io, self, @_root, @_is_le)
        self
      end

      def _read_be
        @first_entry = VerdefSectionEntry.new(@_io, self, @_root, @_is_le)
        self
      end

      ##
      # Indicates whether a string table is linked. This should always be
      # `true` in spec-compliant ELF files. If it is `false`, the string
      # offsets in this section will not be resolved to strings.
      def is_string_table_linked
        return @is_string_table_linked unless @is_string_table_linked.nil?
        @is_string_table_linked = _parent.linked_section.type == :sh_type_strtab
        @is_string_table_linked
      end

      ##
      # Number of entries (version definitions)
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html#GUID-2CBE4879-2E76-426E-BB7F-CF0CB1D87C52__CHAPTER6-47976 Source
      def num_entries
        return @num_entries unless @num_entries.nil?
        @num_entries = _parent.info
        @num_entries
      end
      attr_reader :first_entry
    end

    ##
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#VERDEFENTRIES Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-definition-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VerdefSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/verdef_section_entry")
        end
        self
      end

      def _read_le
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @version = @_io.read_u2le
        raise Kaitai::Struct::ValidationNotEqualError.new(1, @version, @_io, "/types/endian_elf/types/verdef_section_entry/seq/1") if not @version == 1
        @flags = @_io.read_u2le
        @version_index = @_io.read_u2le
        _ = @version_index
        raise Kaitai::Struct::ValidationExprError.new(@version_index, @_io, "/types/endian_elf/types/verdef_section_entry/seq/3") if not _ & 32768 == 0
        @num_aux_entries = @_io.read_u2le
        raise Kaitai::Struct::ValidationLessThanError.new(1, @num_aux_entries, @_io, "/types/endian_elf/types/verdef_section_entry/seq/4") if not @num_aux_entries >= 1
        @hash = @_io.read_u4le
        @ofs_first_aux = @_io.read_u4le
        raise Kaitai::Struct::ValidationLessThanError.new(20, @ofs_first_aux, @_io, "/types/endian_elf/types/verdef_section_entry/seq/6") if not @ofs_first_aux >= 20
        @ofs_next = @_io.read_u4le
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verdef_section_entry/seq/7") if not  ((_ == 0) || (_ >= 20)) 
        self
      end

      def _read_be
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @version = @_io.read_u2be
        raise Kaitai::Struct::ValidationNotEqualError.new(1, @version, @_io, "/types/endian_elf/types/verdef_section_entry/seq/1") if not @version == 1
        @flags = @_io.read_u2be
        @version_index = @_io.read_u2be
        _ = @version_index
        raise Kaitai::Struct::ValidationExprError.new(@version_index, @_io, "/types/endian_elf/types/verdef_section_entry/seq/3") if not _ & 32768 == 0
        @num_aux_entries = @_io.read_u2be
        raise Kaitai::Struct::ValidationLessThanError.new(1, @num_aux_entries, @_io, "/types/endian_elf/types/verdef_section_entry/seq/4") if not @num_aux_entries >= 1
        @hash = @_io.read_u4be
        @ofs_first_aux = @_io.read_u4be
        raise Kaitai::Struct::ValidationLessThanError.new(20, @ofs_first_aux, @_io, "/types/endian_elf/types/verdef_section_entry/seq/6") if not @ofs_first_aux >= 20
        @ofs_next = @_io.read_u4be
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verdef_section_entry/seq/7") if not  ((_ == 0) || (_ >= 20)) 
        self
      end

      ##
      # First auxiliary entry of type `verdaux_entry` (`Elfxx_Verdaux`).
      # The rest follow its `next` instance.
      def first_aux
        return @first_aux unless @first_aux.nil?
        _pos = @_io.pos
        @_io.seek(ofs_start + ofs_first_aux)
        if @_is_le
          @first_aux = VerdauxEntry.new(@_io, _parent, @_root, @_is_le)
        else
          @first_aux = VerdauxEntry.new(@_io, _parent, @_root, @_is_le)
        end
        @_io.seek(_pos)
        @first_aux
      end
      def flags_obj
        return @flags_obj unless @flags_obj.nil?
        if @_is_le
          @flags_obj = VersionFlags.new(@_io, self, @_root, @_is_le, flags)
        else
          @flags_obj = VersionFlags.new(@_io, self, @_root, @_is_le, flags)
        end
        @flags_obj
      end
      def next
        return @next unless @next.nil?
        if ofs_next != 0
          _pos = @_io.pos
          @_io.seek(ofs_start + ofs_next)
          if @_is_le
            @next = VerdefSectionEntry.new(@_io, _parent, @_root, @_is_le)
          else
            @next = VerdefSectionEntry.new(@_io, _parent, @_root, @_is_le)
          end
          @_io.seek(_pos)
        end
        @next
      end
      def ofs_start
        return @ofs_start unless @ofs_start.nil?
        @ofs_start = _io.pos
        @ofs_start
      end
      def version_index_special
        return @version_index_special unless @version_index_special.nil?
        @version_index_special = Kaitai::Struct::Stream::resolve_enum(Elf::VERSION_INDEX_SPECIAL, version_index)
        @version_index_special
      end
      attr_reader :_unnamed0

      ##
      # Version of the structure. Must be set to 1.
      attr_reader :version

      ##
      # Version information flag bitmask. Access `flags_obj` instead.
      attr_reader :flags

      ##
      # Version index assigned to this version definition. A unique index
      # that entries in the Symbol Version Table (the `versym_section`
      # type) use to reference the corresponding version definition.
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-definition-section.html Source
      attr_reader :version_index

      ##
      # Number of associated auxiliary entries.
      attr_reader :num_aux_entries

      ##
      # Version name hash value (ELF hash function).
      attr_reader :hash

      ##
      # Byte offset to the first `verdaux_entry` (`Elfxx_Verdaux`)
      # associated with this version definition. The offset is relative to
      # the start of this `verdef_section_entry`.
      attr_reader :ofs_first_aux

      ##
      # Byte offset to the next verdef entry, relative to the start of
      # this `verdef_section_entry`. A value of zero means that there is
      # no next entry.
      attr_reader :ofs_next
    end

    ##
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#VERNEEDEXTFIG Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-dependency-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VernauxEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/vernaux_entry")
        end
        self
      end

      def _read_le
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @hash = @_io.read_u4le
        @flags = @_io.read_u2le
        @version_index = VersionIndex.new(@_io, self, @_root, @_is_le)
        @ofs_name = @_io.read_u4le
        @ofs_next = @_io.read_u4le
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/vernaux_entry/seq/5") if not  ((_ == 0) || (_ >= 16)) 
        self
      end

      def _read_be
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @hash = @_io.read_u4be
        @flags = @_io.read_u2be
        @version_index = VersionIndex.new(@_io, self, @_root, @_is_le)
        @ofs_name = @_io.read_u4be
        @ofs_next = @_io.read_u4be
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/vernaux_entry/seq/5") if not  ((_ == 0) || (_ >= 16)) 
        self
      end
      def flags_obj
        return @flags_obj unless @flags_obj.nil?
        if @_is_le
          @flags_obj = VersionFlags.new(@_io, self, @_root, @_is_le, flags)
        else
          @flags_obj = VersionFlags.new(@_io, self, @_root, @_is_le, flags)
        end
        @flags_obj
      end
      def name
        return @name unless @name.nil?
        if _parent.is_string_table_linked
          io = _parent._parent.linked_section.body._io
          _pos = io.pos
          io.seek(ofs_name)
          if @_is_le
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          else
            @name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          end
          io.seek(_pos)
        end
        @name
      end
      def next
        return @next unless @next.nil?
        if ofs_next != 0
          _pos = @_io.pos
          @_io.seek(ofs_start + ofs_next)
          if @_is_le
            @next = VernauxEntry.new(@_io, _parent, @_root, @_is_le)
          else
            @next = VernauxEntry.new(@_io, _parent, @_root, @_is_le)
          end
          @_io.seek(_pos)
        end
        @next
      end
      def ofs_start
        return @ofs_start unless @ofs_start.nil?
        @ofs_start = _io.pos
        @ofs_start
      end
      attr_reader :_unnamed0

      ##
      # Dependency name hash value (ELF hash function).
      attr_reader :hash

      ##
      # Dependency information flag bitmask. Access `flags_obj` instead.
      attr_reader :flags

      ##
      # Version index assigned to this dependency version. A unique index
      # that entries in the Symbol Version Table (the `versym_section`
      # type) use to reference the corresponding dependency version.
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-dependency-section.html Source
      attr_reader :version_index

      ##
      # Byte offset to the dependency name string in the linked string
      # table.
      attr_reader :ofs_name

      ##
      # Byte offset to the next vernaux entry, relative to the start of
      # this `vernaux_entry`. A value of zero means that there is no next
      # entry.
      attr_reader :ofs_next
    end

    ##
    # Version Requirements, contained in the special section named
    # `.gnu.version_r` with the section type `sh_type::gnu_verneed`
    # (`SHT_GNU_verneed`). This section defines the required versions of
    # dynamic symbols from other shared objects.
    # 
    # The number of entries in this section must match the value of the
    # dynamic tag `dynamic_array_tags::verneednum` (`DT_VERNEEDNUM`) in the
    # Dynamic Section (`.dynamic`).
    # 
    # `_parent.linked_section` must be the string table that contains the
    # strings referenced by this section. Specifically, the string table in
    # the `.dynstr` section should be used (side note: the `readelf` command
    # doesn't even check which string table `sh_link` points to, and always
    # uses `.dynstr` for the lookups - see
    # <https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/binutils/readelf.c#L13941>).
    # 
    # The `is_string_table_linked` value instance indicates whether the
    # string table is linked. If it is not, file names (the `file_name`
    # instance in the `verneed_section_entry` type) or version names (the
    # `name` instance in the `vernaux_entry` type) will not be available.
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMVERRQMTS Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-dependency-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VerneedSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/verneed_section")
        end
        self
      end

      def _read_le
        @first_entry = VerneedSectionEntry.new(@_io, self, @_root, @_is_le)
        self
      end

      def _read_be
        @first_entry = VerneedSectionEntry.new(@_io, self, @_root, @_is_le)
        self
      end

      ##
      # Indicates whether a string table is linked. This should always be
      # `true` in spec-compliant ELF files. If it is `false`, the string
      # offsets in this section will not be resolved to strings.
      def is_string_table_linked
        return @is_string_table_linked unless @is_string_table_linked.nil?
        @is_string_table_linked = _parent.linked_section.type == :sh_type_strtab
        @is_string_table_linked
      end

      ##
      # Number of entries (dependency versions)
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html#GUID-2CBE4879-2E76-426E-BB7F-CF0CB1D87C52__CHAPTER6-47976 Source
      def num_entries
        return @num_entries unless @num_entries.nil?
        @num_entries = _parent.info
        @num_entries
      end
      attr_reader :first_entry
    end

    ##
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#VERNEEDFIG Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-dependency-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VerneedSectionEntry < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/verneed_section_entry")
        end
        self
      end

      def _read_le
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @version = @_io.read_u2le
        raise Kaitai::Struct::ValidationNotEqualError.new(1, @version, @_io, "/types/endian_elf/types/verneed_section_entry/seq/1") if not @version == 1
        @num_aux_entries = @_io.read_u2le
        raise Kaitai::Struct::ValidationLessThanError.new(1, @num_aux_entries, @_io, "/types/endian_elf/types/verneed_section_entry/seq/2") if not @num_aux_entries >= 1
        @ofs_file_name = @_io.read_u4le
        @ofs_first_aux = @_io.read_u4le
        raise Kaitai::Struct::ValidationLessThanError.new(16, @ofs_first_aux, @_io, "/types/endian_elf/types/verneed_section_entry/seq/4") if not @ofs_first_aux >= 16
        @ofs_next = @_io.read_u4le
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verneed_section_entry/seq/5") if not  ((_ == 0) || (_ >= 16)) 
        self
      end

      def _read_be
        if ofs_start < 0
          @_unnamed0 = @_io.read_bytes(0)
        end
        @version = @_io.read_u2be
        raise Kaitai::Struct::ValidationNotEqualError.new(1, @version, @_io, "/types/endian_elf/types/verneed_section_entry/seq/1") if not @version == 1
        @num_aux_entries = @_io.read_u2be
        raise Kaitai::Struct::ValidationLessThanError.new(1, @num_aux_entries, @_io, "/types/endian_elf/types/verneed_section_entry/seq/2") if not @num_aux_entries >= 1
        @ofs_file_name = @_io.read_u4be
        @ofs_first_aux = @_io.read_u4be
        raise Kaitai::Struct::ValidationLessThanError.new(16, @ofs_first_aux, @_io, "/types/endian_elf/types/verneed_section_entry/seq/4") if not @ofs_first_aux >= 16
        @ofs_next = @_io.read_u4be
        _ = @ofs_next
        raise Kaitai::Struct::ValidationExprError.new(@ofs_next, @_io, "/types/endian_elf/types/verneed_section_entry/seq/5") if not  ((_ == 0) || (_ >= 16)) 
        self
      end
      def file_name
        return @file_name unless @file_name.nil?
        if _parent.is_string_table_linked
          io = _parent._parent.linked_section.body._io
          _pos = io.pos
          io.seek(ofs_file_name)
          if @_is_le
            @file_name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          else
            @file_name = (io.read_bytes_term(0, false, true, true)).force_encoding("UTF-8")
          end
          io.seek(_pos)
        end
        @file_name
      end

      ##
      # First auxiliary entry of type `vernaux_entry` (`Elfxx_Vernaux`).
      # The rest follow its `next` instance.
      def first_aux
        return @first_aux unless @first_aux.nil?
        _pos = @_io.pos
        @_io.seek(ofs_start + ofs_first_aux)
        if @_is_le
          @first_aux = VernauxEntry.new(@_io, _parent, @_root, @_is_le)
        else
          @first_aux = VernauxEntry.new(@_io, _parent, @_root, @_is_le)
        end
        @_io.seek(_pos)
        @first_aux
      end
      def next
        return @next unless @next.nil?
        if ofs_next != 0
          _pos = @_io.pos
          @_io.seek(ofs_start + ofs_next)
          if @_is_le
            @next = VerneedSectionEntry.new(@_io, _parent, @_root, @_is_le)
          else
            @next = VerneedSectionEntry.new(@_io, _parent, @_root, @_is_le)
          end
          @_io.seek(_pos)
        end
        @next
      end
      def ofs_start
        return @ofs_start unless @ofs_start.nil?
        @ofs_start = _io.pos
        @ofs_start
      end
      attr_reader :_unnamed0

      ##
      # Version of the structure. Must be set to 1.
      attr_reader :version

      ##
      # Number of associated auxiliary entries.
      attr_reader :num_aux_entries

      ##
      # Byte offset to the file name string in the linked string table.
      attr_reader :ofs_file_name

      ##
      # Byte offset to the first associated `vernaux_entry`
      # (`Elfxx_Vernaux`). The offset is relative to the start of this
      # `verneed_section_entry`.
      attr_reader :ofs_first_aux

      ##
      # Byte offset to the next verneed entry, relative to the start of
      # this `verneed_section_entry`. A value of zero means that there is
      # no next entry.
      attr_reader :ofs_next
    end

    ##
    # Version information flag bitmask, shared by the `flags` (`vd_flags`)
    # field of `verdef_section_entry` (`Elfxx_Verdef`) and the `flags`
    # (`vna_flags`) field of `vernaux_entry` (`Elfxx_Vernaux`).
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMSTARTSEQ Source
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L1078 Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VersionFlags < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil, value)
        super(_io, _parent, _root)
        @_is_le = _is_le
        @value = value
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/version_flags")
        end
        self
      end

      def _read_le
        self
      end

      def _read_be
        self
      end

      ##
      # Version definition of the file itself (the base definition).
      def base
        return @base unless @base.nil?
        @base = value & 1 != 0
        @base
      end

      ##
      # Version reference exists for informational purposes and does not
      # need to be validated at runtime.
      # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-dependency-section.html Source
      def info
        return @info unless @info.nil?
        @info = value & 4 != 0
        @info
      end

      ##
      # Weak version identifier.
      # 
      # A weak version definition has no symbols associated with the
      # version. See [Creating a Weak Version
      # Definition](https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/creating-weak-version-definition.html).
      def weak
        return @weak unless @weak.nil?
        @weak = value & 2 != 0
        @weak
      end
      attr_reader :value
    end
    class VersionIndex < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/version_index")
        end
        self
      end

      def _read_le
        @raw = @_io.read_u2le
        self
      end

      def _read_be
        @raw = @_io.read_u2be
        self
      end

      ##
      # This bit is set if the symbol is hidden, and is only visible with
      # an explicit version number. This is a GNU extension.
      # @see https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/include/elf/common.h#L1379 Source
      def is_hidden
        return @is_hidden unless @is_hidden.nil?
        @is_hidden = raw & 32768 != 0
        @is_hidden
      end

      ##
      # The values `version_index_special::local` (0) and
      # `version_index_special::global_symbol` (1) have special meanings.
      # The `version_index_special` value instance converts the integer
      # value to the `version_index_special` enum.
      def value
        return @value unless @value.nil?
        @value = raw & 32767
        @value
      end

      ##
      # Note: we match special constants against the full 16-bit integer
      # value (called `raw` in this .ksy implementation), because that's
      # what the `readelf` command does when deciding whether to print
      # `0 (*local*)` or `1 (*global*)` in the `.gnu.version`
      # (`SHT_GNU_versym`) section - see
      # <https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/binutils/readelf.c#L14079>.
      # 
      # Besides, `version_index_special::eliminate` (`VER_NDX_ELIMINATE`)
      # has a value of `0xff01`, which is a 16-bit value. If we matched
      # against `value` instead, `version_index_special::eliminate` would
      # be unreachable, because `value` contains only the lower 15 bits,
      # so its maximum possible value is `0x7fff`.
      def version_index_special
        return @version_index_special unless @version_index_special.nil?
        @version_index_special = Kaitai::Struct::Stream::resolve_enum(Elf::VERSION_INDEX_SPECIAL, raw)
        @version_index_special
      end

      ##
      # Raw value, don't read this field - access `value`,
      # `version_index_special` and `is_hidden` instead.
      attr_reader :raw
    end

    ##
    # Symbol Version Table, contained in the special section named
    # `.gnu.version` with the section type `sh_type::gnu_versym`
    # (`SHT_GNU_versym`).
    # 
    # This section must have the same number of entries as the Dynamic
    # Symbol Table in the `.dynsym` section (section type `sh_type::dynsym`
    # / `SHT_DYNSYM`). Each entry specifies the version defined for or
    # required by the corresponding symbol in the Dynamic Symbol Table.
    # @see https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMVERTBL Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/version-symbol-section.html Source
    # @see https://www.akkadia.org/drepper/symbol-versioning Source
    class VersymSection < Kaitai::Struct::Struct
      def initialize(_io, _parent = nil, _root = nil, _is_le = nil)
        super(_io, _parent, _root)
        @_is_le = _is_le
        _read
      end

      def _read

        if @_is_le == true
          _read_le
        elsif @_is_le == false
          _read_be
        else
          raise Kaitai::Struct::UndecidedEndiannessError.new("/types/endian_elf/types/versym_section")
        end
        self
      end

      def _read_le
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << VersionIndex.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end

      def _read_be
        @entries = []
        i = 0
        while not @_io.eof?
          @entries << VersionIndex.new(@_io, self, @_root, @_is_le)
          i += 1
        end
        self
      end

      ##
      # Version indexes for the corresponding symbols in the Dynamic
      # Symbol Table (`.dynsym` section).
      # 
      # These values are not the versions themselves: they are keys that
      # are matched against the `version_index` (`vd_ndx`) field of the
      # `verdef_section_entry` (`Elfxx_Verdef`) type if the symbol is
      # defined in this object, or the `version_index` (`vna_other`) field
      # of the `vernaux_entry` (`Elfxx_Vernaux`) type if the symbol is
      # required from another object. The `name` instance of the matched
      # entry specifies the version of the symbol.
      attr_reader :entries
    end
    def program_headers
      return @program_headers unless @program_headers.nil?
      _pos = @_io.pos
      @_io.seek(ofs_program_headers)
      if @_is_le
        @_raw_program_headers = []
        @program_headers = []
        (num_program_headers).times { |i|
          _io_program_headers = @_io.substream(program_header_size)
          @program_headers << ProgramHeader.new(_io_program_headers, self, @_root, @_is_le)
        }
      else
        @_raw_program_headers = []
        @program_headers = []
        (num_program_headers).times { |i|
          _io_program_headers = @_io.substream(program_header_size)
          @program_headers << ProgramHeader.new(_io_program_headers, self, @_root, @_is_le)
        }
      end
      @_io.seek(_pos)
      @program_headers
    end
    def section_headers
      return @section_headers unless @section_headers.nil?
      _pos = @_io.pos
      @_io.seek(ofs_section_headers)
      if @_is_le
        @_raw_section_headers = []
        @section_headers = []
        (num_section_headers).times { |i|
          _io_section_headers = @_io.substream(section_header_size)
          @section_headers << SectionHeader.new(_io_section_headers, self, @_root, @_is_le)
        }
      else
        @_raw_section_headers = []
        @section_headers = []
        (num_section_headers).times { |i|
          _io_section_headers = @_io.substream(section_header_size)
          @section_headers << SectionHeader.new(_io_section_headers, self, @_root, @_is_le)
        }
      end
      @_io.seek(_pos)
      @section_headers
    end
    def section_names
      return @section_names unless @section_names.nil?
      if  ((section_names_idx != (Elf::I__SECTION_HEADER_IDX_SPECIAL[:section_header_idx_special_undefined] || :section_header_idx_special_undefined)) && (section_names_idx < _root.header.num_section_headers)) 
        _pos = @_io.pos
        @_io.seek(section_headers[section_names_idx].ofs_body)
        if @_is_le
          _io_section_names = @_io.substream(section_headers[section_names_idx].len_body)
          @section_names = StringsStruct.new(_io_section_names, self, @_root, @_is_le)
        else
          _io_section_names = @_io.substream(section_headers[section_names_idx].len_body)
          @section_names = StringsStruct.new(_io_section_names, self, @_root, @_is_le)
        end
        @_io.seek(_pos)
      end
      @section_names
    end
    attr_reader :e_type
    attr_reader :machine
    attr_reader :e_version
    attr_reader :entry_point
    attr_reader :ofs_program_headers
    attr_reader :ofs_section_headers
    attr_reader :flags
    attr_reader :e_ehsize
    attr_reader :program_header_size
    attr_reader :num_program_headers
    attr_reader :section_header_size
    attr_reader :num_section_headers
    attr_reader :section_names_idx
    attr_reader :_raw_program_headers
    attr_reader :_raw_section_headers
    attr_reader :_raw_section_names
  end
  class PhdrTypeFlags < Kaitai::Struct::Struct
    def initialize(_io, _parent = nil, _root = nil, value)
      super(_io, _parent, _root)
      @value = value
      _read
    end

    def _read
      self
    end
    def execute
      return @execute unless @execute.nil?
      @execute = value & 1 != 0
      @execute
    end
    def mask_proc
      return @mask_proc unless @mask_proc.nil?
      @mask_proc = value & 4026531840 != 0
      @mask_proc
    end
    def read
      return @read unless @read.nil?
      @read = value & 4 != 0
      @read
    end
    def write
      return @write unless @write.nil?
      @write = value & 2 != 0
      @write
    end
    attr_reader :value
  end

  ##
  # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html#GUID-2CBE4879-2E76-426E-BB7F-CF0CB1D87C52__CHAPTER6-10675 Source
  # @see https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/include/elf/common.h#L614 Source
  # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L468 Source
  class SectionHeaderFlags < Kaitai::Struct::Struct
    def initialize(_io, _parent = nil, _root = nil, value)
      super(_io, _parent, _root)
      @value = value
      _read
    end

    def _read
      self
    end

    ##
    # Occupies memory during execution
    def alloc
      return @alloc unless @alloc.nil?
      @alloc = value & 2 != 0
      @alloc
    end

    ##
    # Section with compressed data
    def compressed
      return @compressed unless @compressed.nil?
      @compressed = value & 2048 != 0
      @compressed
    end

    ##
    # Section is excluded unless referenced or allocated (Solaris)
    def exclude
      return @exclude unless @exclude.nil?
      @exclude = value & 2147483648 != 0
      @exclude
    end

    ##
    # Executable machine instructions
    def exec_instr
      return @exec_instr unless @exec_instr.nil?
      @exec_instr = value & 4 != 0
      @exec_instr
    end

    ##
    # Mbind section
    # @see https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/include/elf/common.h#L631 Source
    def gnu_mbind
      return @gnu_mbind unless @gnu_mbind.nil?
      @gnu_mbind = value & 16777216 != 0
      @gnu_mbind
    end

    ##
    # Member of a section group
    def group
      return @group unless @group.nil?
      @group = value & 512 != 0
      @group
    end

    ##
    # Section header's `sh_info` field holds a section header table index
    def info_link
      return @info_link unless @info_link.nil?
      @info_link = value & 64 != 0
      @info_link
    end

    ##
    # Preserve section ordering when linking
    def link_order
      return @link_order unless @link_order.nil?
      @link_order = value & 128 != 0
      @link_order
    end

    ##
    # OS-specific semantics
    def mask_os
      return @mask_os unless @mask_os.nil?
      @mask_os = value & 267386880 != 0
      @mask_os
    end

    ##
    # Processor-specific semantics
    def mask_proc
      return @mask_proc unless @mask_proc.nil?
      @mask_proc = value & 4026531840 != 0
      @mask_proc
    end

    ##
    # Data in this section can be merged to eliminate duplication
    def merge
      return @merge unless @merge.nil?
      @merge = value & 16 != 0
      @merge
    end

    ##
    # Special ordering requirement (Solaris)
    # 
    # From <https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html#GUID-2CBE4879-2E76-426E-BB7F-CF0CB1D87C52__CHAPTER6-10675>:
    # 
    # > `SHF_ORDERED` is an older version of the functionality provided by
    # > `SHF_LINK_ORDER`, and has been superseded by `SHF_LINK_ORDER`.
    # > `SHF_ORDERED` is no longer supported.
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L485 Source
    # @see https://docs.oracle.com/en/operating-systems/solaris/oracle-solaris/11.4/linkers-libraries/section-headers.html#GUID-2CBE4879-2E76-426E-BB7F-CF0CB1D87C52__CHAPTER6-10675 Source
    def ordered
      return @ordered unless @ordered.nil?
      @ordered = value & 1073741824 != 0
      @ordered
    end

    ##
    # Special OS-specific handling required
    def os_nonconforming
      return @os_nonconforming unless @os_nonconforming.nil?
      @os_nonconforming = value & 256 != 0
      @os_nonconforming
    end

    ##
    # Section should not be garbage collected by the linker
    # @see https://forge.sourceware.org/binutils-gdb/binutils-gdb-mirror/src/tag/binutils-2_46_1/include/elf/common.h#L630 Source
    # @see https://forge.sourceware.org/glibc/glibc-mirror/src/tag/glibc-2.43/elf/elf.h#L484 Source
    def retain
      return @retain unless @retain.nil?
      @retain = value & 2097152 != 0
      @retain
    end

    ##
    # Contains null-terminated character strings
    def strings
      return @strings unless @strings.nil?
      @strings = value & 32 != 0
      @strings
    end

    ##
    # Thread-local storage section (`.tbss` or `.tdata` according to [ELF
    # Handling For Thread-Local
    # Storage](https://www.akkadia.org/drepper/tls.pdf))
    def tls
      return @tls unless @tls.nil?
      @tls = value & 1024 != 0
      @tls
    end

    ##
    # Writable during execution
    def write
      return @write unless @write.nil?
      @write = value & 1 != 0
      @write
    end
    attr_reader :value
  end
  def sh_idx_hi_os
    return @sh_idx_hi_os unless @sh_idx_hi_os.nil?
    @sh_idx_hi_os = 65343
    @sh_idx_hi_os
  end
  def sh_idx_hi_proc
    return @sh_idx_hi_proc unless @sh_idx_hi_proc.nil?
    @sh_idx_hi_proc = 65311
    @sh_idx_hi_proc
  end
  def sh_idx_hi_reserved
    return @sh_idx_hi_reserved unless @sh_idx_hi_reserved.nil?
    @sh_idx_hi_reserved = 65535
    @sh_idx_hi_reserved
  end
  def sh_idx_lo_os
    return @sh_idx_lo_os unless @sh_idx_lo_os.nil?
    @sh_idx_lo_os = 65312
    @sh_idx_lo_os
  end
  def sh_idx_lo_proc
    return @sh_idx_lo_proc unless @sh_idx_lo_proc.nil?
    @sh_idx_lo_proc = 65280
    @sh_idx_lo_proc
  end
  def sh_idx_lo_reserved
    return @sh_idx_lo_reserved unless @sh_idx_lo_reserved.nil?
    @sh_idx_lo_reserved = 65280
    @sh_idx_lo_reserved
  end

  ##
  # File identification, must be 0x7f + "ELF".
  attr_reader :magic

  ##
  # File class: designates target machine word size (32 or 64
  # bits). The size of many integer fields in this format will
  # depend on this setting.
  attr_reader :bits

  ##
  # Endianness used for all integers.
  attr_reader :endian

  ##
  # ELF header version.
  attr_reader :ei_version

  ##
  # Specifies which OS- and ABI-related extensions will be used
  # in this ELF file.
  attr_reader :abi

  ##
  # Version of ABI targeted by this ELF file. Interpretation
  # depends on `abi` attribute.
  attr_reader :abi_version
  attr_reader :pad
  attr_reader :header
end