Executable and Linkable Format: C++/STL parsing library

Application

SVR4 ABI and up, many *nix systems

KS implementation details

License: CC0-1.0
Minimal Kaitai Struct required: 0.8

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

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream).
    • One can open a stream for reading from a local file:
      #include <fstream>
      
      std::ifstream is("path/to/local/file.elf", std::ifstream::binary);
    • Or one can prepare a stream for reading from existing std::string str:
      #include <sstream>
      
      std::istringstream is(str);
    • Or one can parse arbitrary char* buffer in memory, given that we know its size:
      #include <sstream>
      
      const char buf[] = { ... };
      std::string str(buf, sizeof buf);
      std::istringstream is(str);
  2. We need to wrap our input stream into Kaitai stream:
    #include <kaitai/kaitaistream.h>
    
    kaitai::kstream ks(&is);
  3. And finally, we can invoke the parsing:
    elf_t data(&ks);

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

data.magic() // => File identification, must be 0x7f + "ELF".

C++/STL source code to parse Executable and Linkable Format

elf.h

#ifndef ELF_H_
#define ELF_H_

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

#include "kaitai/kaitaistruct.h"

#include <stdint.h>
#include <vector>

#if KAITAI_STRUCT_VERSION < 7000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.7 or later is required"
#endif

/**
 * \sa Source
 */

class elf_t : public kaitai::kstruct {

public:
    class phdr_type_flags_t;
    class section_header_flags_t;
    class dt_flag_1_values_t;
    class endian_elf_t;

    enum endian_t {
        ENDIAN_LE = 1,
        ENDIAN_BE = 2
    };

    enum sh_type_t {
        SH_TYPE_NULL_TYPE = 0,
        SH_TYPE_PROGBITS = 1,
        SH_TYPE_SYMTAB = 2,
        SH_TYPE_STRTAB = 3,
        SH_TYPE_RELA = 4,
        SH_TYPE_HASH = 5,
        SH_TYPE_DYNAMIC = 6,
        SH_TYPE_NOTE = 7,
        SH_TYPE_NOBITS = 8,
        SH_TYPE_REL = 9,
        SH_TYPE_SHLIB = 10,
        SH_TYPE_DYNSYM = 11,
        SH_TYPE_INIT_ARRAY = 14,
        SH_TYPE_FINI_ARRAY = 15,
        SH_TYPE_PREINIT_ARRAY = 16,
        SH_TYPE_GROUP = 17,
        SH_TYPE_SYMTAB_SHNDX = 18,
        SH_TYPE_SUNW_CAPCHAIN = 1879048175,
        SH_TYPE_SUNW_CAPINFO = 1879048176,
        SH_TYPE_SUNW_SYMSORT = 1879048177,
        SH_TYPE_SUNW_TLSSORT = 1879048178,
        SH_TYPE_SUNW_LDYNSYM = 1879048179,
        SH_TYPE_SUNW_DOF = 1879048180,
        SH_TYPE_SUNW_CAP = 1879048181,
        SH_TYPE_SUNW_SIGNATURE = 1879048182,
        SH_TYPE_SUNW_ANNOTATE = 1879048183,
        SH_TYPE_SUNW_DEBUGSTR = 1879048184,
        SH_TYPE_SUNW_DEBUG = 1879048185,
        SH_TYPE_SUNW_MOVE = 1879048186,
        SH_TYPE_SUNW_COMDAT = 1879048187,
        SH_TYPE_SUNW_SYMINFO = 1879048188,
        SH_TYPE_SUNW_VERDEF = 1879048189,
        SH_TYPE_SUNW_VERNEED = 1879048190,
        SH_TYPE_SUNW_VERSYM = 1879048191,
        SH_TYPE_SPARC_GOTDATA = 1879048192,
        SH_TYPE_ARM_EXIDX = 1879048193,
        SH_TYPE_ARM_PREEMPTMAP = 1879048194,
        SH_TYPE_ARM_ATTRIBUTES = 1879048195
    };

    enum os_abi_t {
        OS_ABI_SYSTEM_V = 0,
        OS_ABI_HP_UX = 1,
        OS_ABI_NETBSD = 2,
        OS_ABI_GNU = 3,
        OS_ABI_SOLARIS = 6,
        OS_ABI_AIX = 7,
        OS_ABI_IRIX = 8,
        OS_ABI_FREEBSD = 9,
        OS_ABI_TRU64 = 10,
        OS_ABI_MODESTO = 11,
        OS_ABI_OPENBSD = 12,
        OS_ABI_OPENVMS = 13,
        OS_ABI_NSK = 14,
        OS_ABI_AROS = 15,
        OS_ABI_FENIXOS = 16,
        OS_ABI_CLOUDABI = 17,
        OS_ABI_OPENVOS = 18
    };

    enum machine_t {
        MACHINE_NOT_SET = 0,
        MACHINE_SPARC = 2,
        MACHINE_X86 = 3,
        MACHINE_MIPS = 8,
        MACHINE_POWERPC = 20,
        MACHINE_ARM = 40,
        MACHINE_SUPERH = 42,
        MACHINE_IA_64 = 50,
        MACHINE_X86_64 = 62,
        MACHINE_AARCH64 = 183,
        MACHINE_RISCV = 243,
        MACHINE_BPF = 247
    };

    enum dynamic_array_tags_t {
        DYNAMIC_ARRAY_TAGS_NULL = 0,
        DYNAMIC_ARRAY_TAGS_NEEDED = 1,
        DYNAMIC_ARRAY_TAGS_PLTRELSZ = 2,
        DYNAMIC_ARRAY_TAGS_PLTGOT = 3,
        DYNAMIC_ARRAY_TAGS_HASH = 4,
        DYNAMIC_ARRAY_TAGS_STRTAB = 5,
        DYNAMIC_ARRAY_TAGS_SYMTAB = 6,
        DYNAMIC_ARRAY_TAGS_RELA = 7,
        DYNAMIC_ARRAY_TAGS_RELASZ = 8,
        DYNAMIC_ARRAY_TAGS_RELAENT = 9,
        DYNAMIC_ARRAY_TAGS_STRSZ = 10,
        DYNAMIC_ARRAY_TAGS_SYMENT = 11,
        DYNAMIC_ARRAY_TAGS_INIT = 12,
        DYNAMIC_ARRAY_TAGS_FINI = 13,
        DYNAMIC_ARRAY_TAGS_SONAME = 14,
        DYNAMIC_ARRAY_TAGS_RPATH = 15,
        DYNAMIC_ARRAY_TAGS_SYMBOLIC = 16,
        DYNAMIC_ARRAY_TAGS_REL = 17,
        DYNAMIC_ARRAY_TAGS_RELSZ = 18,
        DYNAMIC_ARRAY_TAGS_RELENT = 19,
        DYNAMIC_ARRAY_TAGS_PLTREL = 20,
        DYNAMIC_ARRAY_TAGS_DEBUG = 21,
        DYNAMIC_ARRAY_TAGS_TEXTREL = 22,
        DYNAMIC_ARRAY_TAGS_JMPREL = 23,
        DYNAMIC_ARRAY_TAGS_BIND_NOW = 24,
        DYNAMIC_ARRAY_TAGS_INIT_ARRAY = 25,
        DYNAMIC_ARRAY_TAGS_FINI_ARRAY = 26,
        DYNAMIC_ARRAY_TAGS_INIT_ARRAYSZ = 27,
        DYNAMIC_ARRAY_TAGS_FINI_ARRAYSZ = 28,
        DYNAMIC_ARRAY_TAGS_RUNPATH = 29,
        DYNAMIC_ARRAY_TAGS_FLAGS = 30,
        DYNAMIC_ARRAY_TAGS_PREINIT_ARRAY = 32,
        DYNAMIC_ARRAY_TAGS_PREINIT_ARRAYSZ = 33,
        DYNAMIC_ARRAY_TAGS_MAXPOSTAGS = 34,
        DYNAMIC_ARRAY_TAGS_SUNW_AUXILIARY = 1610612749,
        DYNAMIC_ARRAY_TAGS_SUNW_FILTER = 1610612750,
        DYNAMIC_ARRAY_TAGS_SUNW_CAP = 1610612752,
        DYNAMIC_ARRAY_TAGS_SUNW_SYMTAB = 1610612753,
        DYNAMIC_ARRAY_TAGS_SUNW_SYMSZ = 1610612754,
        DYNAMIC_ARRAY_TAGS_SUNW_SORTENT = 1610612755,
        DYNAMIC_ARRAY_TAGS_SUNW_SYMSORT = 1610612756,
        DYNAMIC_ARRAY_TAGS_SUNW_SYMSORTSZ = 1610612757,
        DYNAMIC_ARRAY_TAGS_SUNW_TLSSORT = 1610612758,
        DYNAMIC_ARRAY_TAGS_SUNW_TLSSORTSZ = 1610612759,
        DYNAMIC_ARRAY_TAGS_SUNW_CAPINFO = 1610612760,
        DYNAMIC_ARRAY_TAGS_SUNW_STRPAD = 1610612761,
        DYNAMIC_ARRAY_TAGS_SUNW_CAPCHAIN = 1610612762,
        DYNAMIC_ARRAY_TAGS_SUNW_LDMACH = 1610612763,
        DYNAMIC_ARRAY_TAGS_SUNW_CAPCHAINENT = 1610612765,
        DYNAMIC_ARRAY_TAGS_SUNW_CAPCHAINSZ = 1610612767,
        DYNAMIC_ARRAY_TAGS_HIOS = 1879044096,
        DYNAMIC_ARRAY_TAGS_VALRNGLO = 1879047424,
        DYNAMIC_ARRAY_TAGS_GNU_PRELINKED = 1879047669,
        DYNAMIC_ARRAY_TAGS_GNU_CONFLICTSZ = 1879047670,
        DYNAMIC_ARRAY_TAGS_GNU_LIBLISTSZ = 1879047671,
        DYNAMIC_ARRAY_TAGS_CHECKSUM = 1879047672,
        DYNAMIC_ARRAY_TAGS_PLTPADSZ = 1879047673,
        DYNAMIC_ARRAY_TAGS_MOVEENT = 1879047674,
        DYNAMIC_ARRAY_TAGS_MOVESZ = 1879047675,
        DYNAMIC_ARRAY_TAGS_FEATURE_1 = 1879047676,
        DYNAMIC_ARRAY_TAGS_POSFLAG_1 = 1879047677,
        DYNAMIC_ARRAY_TAGS_SYMINSZ = 1879047678,
        DYNAMIC_ARRAY_TAGS_VALRNGHI = 1879047679,
        DYNAMIC_ARRAY_TAGS_ADDRRNGLO = 1879047680,
        DYNAMIC_ARRAY_TAGS_GNU_HASH = 1879047925,
        DYNAMIC_ARRAY_TAGS_TLSDESC_PLT = 1879047926,
        DYNAMIC_ARRAY_TAGS_TLSDESC_GOT = 1879047927,
        DYNAMIC_ARRAY_TAGS_GNU_CONFLICT = 1879047928,
        DYNAMIC_ARRAY_TAGS_GNU_LIBLIST = 1879047929,
        DYNAMIC_ARRAY_TAGS_CONFIG = 1879047930,
        DYNAMIC_ARRAY_TAGS_DEPAUDIT = 1879047931,
        DYNAMIC_ARRAY_TAGS_AUDIT = 1879047932,
        DYNAMIC_ARRAY_TAGS_PLTPAD = 1879047933,
        DYNAMIC_ARRAY_TAGS_MOVETAB = 1879047934,
        DYNAMIC_ARRAY_TAGS_ADDRRNGHI = 1879047935,
        DYNAMIC_ARRAY_TAGS_VERSYM = 1879048176,
        DYNAMIC_ARRAY_TAGS_RELACOUNT = 1879048185,
        DYNAMIC_ARRAY_TAGS_RELCOUNT = 1879048186,
        DYNAMIC_ARRAY_TAGS_FLAGS_1 = 1879048187,
        DYNAMIC_ARRAY_TAGS_VERDEF = 1879048188,
        DYNAMIC_ARRAY_TAGS_VERDEFNUM = 1879048189,
        DYNAMIC_ARRAY_TAGS_VERNEED = 1879048190,
        DYNAMIC_ARRAY_TAGS_VERNEEDNUM = 1879048191,
        DYNAMIC_ARRAY_TAGS_LOPROC = 1879048192,
        DYNAMIC_ARRAY_TAGS_SPARC_REGISTER = 1879048193,
        DYNAMIC_ARRAY_TAGS_AUXILIARY = 2147483645,
        DYNAMIC_ARRAY_TAGS_USED = 2147483646,
        DYNAMIC_ARRAY_TAGS_HIPROC = 2147483647
    };

    enum bits_t {
        BITS_B32 = 1,
        BITS_B64 = 2
    };

    enum ph_type_t {
        PH_TYPE_NULL_TYPE = 0,
        PH_TYPE_LOAD = 1,
        PH_TYPE_DYNAMIC = 2,
        PH_TYPE_INTERP = 3,
        PH_TYPE_NOTE = 4,
        PH_TYPE_SHLIB = 5,
        PH_TYPE_PHDR = 6,
        PH_TYPE_TLS = 7,
        PH_TYPE_GNU_EH_FRAME = 1685382480,
        PH_TYPE_GNU_STACK = 1685382481,
        PH_TYPE_GNU_RELRO = 1685382482,
        PH_TYPE_PAX_FLAGS = 1694766464,
        PH_TYPE_HIOS = 1879048191,
        PH_TYPE_ARM_EXIDX = 1879048193
    };

    enum obj_type_t {
        OBJ_TYPE_RELOCATABLE = 1,
        OBJ_TYPE_EXECUTABLE = 2,
        OBJ_TYPE_SHARED = 3,
        OBJ_TYPE_CORE = 4
    };

    elf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, elf_t* p__root = 0);

private:
    void _read();

public:
    ~elf_t();

    class phdr_type_flags_t : public kaitai::kstruct {

    public:

        phdr_type_flags_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::program_header_t* p__parent = 0, elf_t* p__root = 0);

    private:
        void _read();

    public:
        ~phdr_type_flags_t();

    private:
        bool f_read;
        bool m_read;

    public:
        bool read();

    private:
        bool f_write;
        bool m_write;

    public:
        bool write();

    private:
        bool f_execute;
        bool m_execute;

    public:
        bool execute();

    private:
        bool f_mask_proc;
        bool m_mask_proc;

    public:
        bool mask_proc();

    private:
        uint32_t m_value;
        elf_t* m__root;
        elf_t::endian_elf_t::program_header_t* m__parent;

    public:
        uint32_t value() const { return m_value; }
        elf_t* _root() const { return m__root; }
        elf_t::endian_elf_t::program_header_t* _parent() const { return m__parent; }
    };

    class section_header_flags_t : public kaitai::kstruct {

    public:

        section_header_flags_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::section_header_t* p__parent = 0, elf_t* p__root = 0);

    private:
        void _read();

    public:
        ~section_header_flags_t();

    private:
        bool f_merge;
        bool m_merge;

    public:

        /**
         * might be merged
         */
        bool merge();

    private:
        bool f_mask_os;
        bool m_mask_os;

    public:

        /**
         * OS-specific
         */
        bool mask_os();

    private:
        bool f_exclude;
        bool m_exclude;

    public:

        /**
         * section is excluded unless referenced or allocated (Solaris)
         */
        bool exclude();

    private:
        bool f_mask_proc;
        bool m_mask_proc;

    public:

        /**
         * Processor-specific
         */
        bool mask_proc();

    private:
        bool f_strings;
        bool m_strings;

    public:

        /**
         * contains nul-terminated strings
         */
        bool strings();

    private:
        bool f_os_non_conforming;
        bool m_os_non_conforming;

    public:

        /**
         * non-standard OS specific handling required
         */
        bool os_non_conforming();

    private:
        bool f_alloc;
        bool m_alloc;

    public:

        /**
         * occupies memory during execution
         */
        bool alloc();

    private:
        bool f_exec_instr;
        bool m_exec_instr;

    public:

        /**
         * executable
         */
        bool exec_instr();

    private:
        bool f_info_link;
        bool m_info_link;

    public:

        /**
         * 'sh_info' contains SHT index
         */
        bool info_link();

    private:
        bool f_write;
        bool m_write;

    public:

        /**
         * writable
         */
        bool write();

    private:
        bool f_link_order;
        bool m_link_order;

    public:

        /**
         * preserve order after combining
         */
        bool link_order();

    private:
        bool f_ordered;
        bool m_ordered;

    public:

        /**
         * special ordering requirement (Solaris)
         */
        bool ordered();

    private:
        bool f_tls;
        bool m_tls;

    public:

        /**
         * section hold thread-local data
         */
        bool tls();

    private:
        bool f_group;
        bool m_group;

    public:

        /**
         * section is member of a group
         */
        bool group();

    private:
        uint32_t m_value;
        elf_t* m__root;
        elf_t::endian_elf_t::section_header_t* m__parent;

    public:
        uint32_t value() const { return m_value; }
        elf_t* _root() const { return m__root; }
        elf_t::endian_elf_t::section_header_t* _parent() const { return m__parent; }
    };

    class dt_flag_1_values_t : public kaitai::kstruct {

    public:

        dt_flag_1_values_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::dynamic_section_entry_t* p__parent = 0, elf_t* p__root = 0);

    private:
        void _read();

    public:
        ~dt_flag_1_values_t();

    private:
        bool f_singleton;
        bool m_singleton;

    public:

        /**
         * Singleton symbols are used.
         */
        bool singleton();

    private:
        bool f_ignmuldef;
        bool m_ignmuldef;

    public:
        bool ignmuldef();

    private:
        bool f_loadfltr;
        bool m_loadfltr;

    public:

        /**
         * Trigger filtee loading at runtime.
         */
        bool loadfltr();

    private:
        bool f_initfirst;
        bool m_initfirst;

    public:

        /**
         * Set RTLD_INITFIRST for this object
         */
        bool initfirst();

    private:
        bool f_symintpose;
        bool m_symintpose;

    public:

        /**
         * Object has individual interposers.
         */
        bool symintpose();

    private:
        bool f_noreloc;
        bool m_noreloc;

    public:
        bool noreloc();

    private:
        bool f_confalt;
        bool m_confalt;

    public:

        /**
         * Configuration alternative created.
         */
        bool confalt();

    private:
        bool f_dispreldne;
        bool m_dispreldne;

    public:

        /**
         * Disp reloc applied at build time.
         */
        bool dispreldne();

    private:
        bool f_rtld_global;
        bool m_rtld_global;

    public:

        /**
         * Set RTLD_GLOBAL for this object.
         */
        bool rtld_global();

    private:
        bool f_nodelete;
        bool m_nodelete;

    public:

        /**
         * Set RTLD_NODELETE for this object.
         */
        bool nodelete();

    private:
        bool f_trans;
        bool m_trans;

    public:
        bool trans();

    private:
        bool f_origin;
        bool m_origin;

    public:

        /**
         * $ORIGIN must be handled.
         */
        bool origin();

    private:
        bool f_now;
        bool m_now;

    public:

        /**
         * Set RTLD_NOW for this object.
         */
        bool now();

    private:
        bool f_nohdr;
        bool m_nohdr;

    public:
        bool nohdr();

    private:
        bool f_endfiltee;
        bool m_endfiltee;

    public:

        /**
         * Filtee terminates filters search.
         */
        bool endfiltee();

    private:
        bool f_nodirect;
        bool m_nodirect;

    public:

        /**
         * Object has no-direct binding.
         */
        bool nodirect();

    private:
        bool f_globaudit;
        bool m_globaudit;

    public:

        /**
         * Global auditing required.
         */
        bool globaudit();

    private:
        bool f_noksyms;
        bool m_noksyms;

    public:
        bool noksyms();

    private:
        bool f_interpose;
        bool m_interpose;

    public:

        /**
         * Object is used to interpose.
         */
        bool interpose();

    private:
        bool f_nodump;
        bool m_nodump;

    public:

        /**
         * Object can't be dldump'ed.
         */
        bool nodump();

    private:
        bool f_disprelpnd;
        bool m_disprelpnd;

    public:

        /**
         * Disp reloc applied at run-time.
         */
        bool disprelpnd();

    private:
        bool f_noopen;
        bool m_noopen;

    public:

        /**
         * Set RTLD_NOOPEN for this object.
         */
        bool noopen();

    private:
        bool f_stub;
        bool m_stub;

    public:
        bool stub();

    private:
        bool f_direct;
        bool m_direct;

    public:

        /**
         * Direct binding enabled.
         */
        bool direct();

    private:
        bool f_edited;
        bool m_edited;

    public:

        /**
         * Object is modified after built.
         */
        bool edited();

    private:
        bool f_group;
        bool m_group;

    public:

        /**
         * Set RTLD_GROUP for this object.
         */
        bool group();

    private:
        bool f_pie;
        bool m_pie;

    public:
        bool pie();

    private:
        bool f_nodeflib;
        bool m_nodeflib;

    public:

        /**
         * Ignore default lib search path.
         */
        bool nodeflib();

    private:
        uint32_t m_value;
        elf_t* m__root;
        elf_t::endian_elf_t::dynamic_section_entry_t* m__parent;

    public:
        uint32_t value() const { return m_value; }
        elf_t* _root() const { return m__root; }
        elf_t::endian_elf_t::dynamic_section_entry_t* _parent() const { return m__parent; }
    };

    class endian_elf_t : public kaitai::kstruct {

    public:
        class dynsym_section_entry64_t;
        class program_header_t;
        class dynamic_section_entry_t;
        class section_header_t;
        class dynamic_section_t;
        class dynsym_section_t;
        class dynsym_section_entry32_t;
        class strings_struct_t;

        endian_elf_t(kaitai::kstream* p__io, elf_t* p__parent = 0, elf_t* p__root = 0);

    private:
        int m__is_le;

    public:

    private:
        void _read();

    public:

    private:
        void _read_le();

    public:

    private:
        void _read_be();

    public:
        ~endian_elf_t();

        class dynsym_section_entry64_t : public kaitai::kstruct {

        public:

            dynsym_section_entry64_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynsym_section_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~dynsym_section_entry64_t();

        private:
            uint32_t m_name_offset;
            uint8_t m_info;
            uint8_t m_other;
            uint16_t m_shndx;
            uint64_t m_value;
            uint64_t m_size;
            elf_t* m__root;
            elf_t::endian_elf_t::dynsym_section_t* m__parent;

        public:
            uint32_t name_offset() const { return m_name_offset; }
            uint8_t info() const { return m_info; }
            uint8_t other() const { return m_other; }
            uint16_t shndx() const { return m_shndx; }
            uint64_t value() const { return m_value; }
            uint64_t size() const { return m_size; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t::dynsym_section_t* _parent() const { return m__parent; }
        };

        class program_header_t : public kaitai::kstruct {

        public:

            program_header_t(kaitai::kstream* p__io, elf_t::endian_elf_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~program_header_t();

        private:
            bool f_dynamic;
            dynamic_section_t* m_dynamic;
            bool n_dynamic;

        public:
            bool _is_null_dynamic() { dynamic(); return n_dynamic; };

        private:

        public:
            dynamic_section_t* dynamic();

        private:
            bool f_flags_obj;
            phdr_type_flags_t* m_flags_obj;

        public:
            phdr_type_flags_t* flags_obj();

        private:
            ph_type_t m_type;
            uint32_t m_flags64;
            bool n_flags64;

        public:
            bool _is_null_flags64() { flags64(); return n_flags64; };

        private:
            uint64_t m_offset;
            bool n_offset;

        public:
            bool _is_null_offset() { offset(); return n_offset; };

        private:
            uint64_t m_vaddr;
            bool n_vaddr;

        public:
            bool _is_null_vaddr() { vaddr(); return n_vaddr; };

        private:
            uint64_t m_paddr;
            bool n_paddr;

        public:
            bool _is_null_paddr() { paddr(); return n_paddr; };

        private:
            uint64_t m_filesz;
            bool n_filesz;

        public:
            bool _is_null_filesz() { filesz(); return n_filesz; };

        private:
            uint64_t m_memsz;
            bool n_memsz;

        public:
            bool _is_null_memsz() { memsz(); return n_memsz; };

        private:
            uint32_t m_flags32;
            bool n_flags32;

        public:
            bool _is_null_flags32() { flags32(); return n_flags32; };

        private:
            uint64_t m_align;
            bool n_align;

        public:
            bool _is_null_align() { align(); return n_align; };

        private:
            elf_t* m__root;
            elf_t::endian_elf_t* m__parent;
            std::string m__raw_dynamic;
            kaitai::kstream* m__io__raw_dynamic;

        public:
            ph_type_t type() const { return m_type; }
            uint32_t flags64() const { return m_flags64; }
            uint64_t offset() const { return m_offset; }
            uint64_t vaddr() const { return m_vaddr; }
            uint64_t paddr() const { return m_paddr; }
            uint64_t filesz() const { return m_filesz; }
            uint64_t memsz() const { return m_memsz; }
            uint32_t flags32() const { return m_flags32; }
            uint64_t align() const { return m_align; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t* _parent() const { return m__parent; }
            std::string _raw_dynamic() const { return m__raw_dynamic; }
            kaitai::kstream* _io__raw_dynamic() const { return m__io__raw_dynamic; }
        };

        class dynamic_section_entry_t : public kaitai::kstruct {

        public:

            dynamic_section_entry_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynamic_section_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~dynamic_section_entry_t();

        private:
            bool f_tag_enum;
            dynamic_array_tags_t m_tag_enum;

        public:
            dynamic_array_tags_t tag_enum();

        private:
            bool f_flag_1_values;
            dt_flag_1_values_t* m_flag_1_values;
            bool n_flag_1_values;

        public:
            bool _is_null_flag_1_values() { flag_1_values(); return n_flag_1_values; };

        private:

        public:
            dt_flag_1_values_t* flag_1_values();

        private:
            uint64_t m_tag;
            bool n_tag;

        public:
            bool _is_null_tag() { tag(); return n_tag; };

        private:
            uint64_t m_value_or_ptr;
            bool n_value_or_ptr;

        public:
            bool _is_null_value_or_ptr() { value_or_ptr(); return n_value_or_ptr; };

        private:
            elf_t* m__root;
            elf_t::endian_elf_t::dynamic_section_t* m__parent;

        public:
            uint64_t tag() const { return m_tag; }
            uint64_t value_or_ptr() const { return m_value_or_ptr; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t::dynamic_section_t* _parent() const { return m__parent; }
        };

        class section_header_t : public kaitai::kstruct {

        public:

            section_header_t(kaitai::kstream* p__io, elf_t::endian_elf_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~section_header_t();

        private:
            bool f_body;
            kaitai::kstruct* m_body;

        public:
            kaitai::kstruct* body();

        private:
            bool f_name;
            std::string m_name;

        public:
            std::string name();

        private:
            bool f_flags_obj;
            section_header_flags_t* m_flags_obj;

        public:
            section_header_flags_t* flags_obj();

        private:
            uint32_t m_ofs_name;
            sh_type_t m_type;
            uint64_t m_flags;
            bool n_flags;

        public:
            bool _is_null_flags() { flags(); return n_flags; };

        private:
            uint64_t m_addr;
            bool n_addr;

        public:
            bool _is_null_addr() { addr(); return n_addr; };

        private:
            uint64_t m_ofs_body;
            bool n_ofs_body;

        public:
            bool _is_null_ofs_body() { ofs_body(); return n_ofs_body; };

        private:
            uint64_t m_len_body;
            bool n_len_body;

        public:
            bool _is_null_len_body() { len_body(); return n_len_body; };

        private:
            uint32_t m_linked_section_idx;
            std::string m_info;
            uint64_t m_align;
            bool n_align;

        public:
            bool _is_null_align() { align(); return n_align; };

        private:
            uint64_t m_entry_size;
            bool n_entry_size;

        public:
            bool _is_null_entry_size() { entry_size(); return n_entry_size; };

        private:
            elf_t* m__root;
            elf_t::endian_elf_t* m__parent;
            std::string m__raw_body;
            kaitai::kstream* m__io__raw_body;

        public:
            uint32_t ofs_name() const { return m_ofs_name; }
            sh_type_t type() const { return m_type; }
            uint64_t flags() const { return m_flags; }
            uint64_t addr() const { return m_addr; }
            uint64_t ofs_body() const { return m_ofs_body; }
            uint64_t len_body() const { return m_len_body; }
            uint32_t linked_section_idx() const { return m_linked_section_idx; }
            std::string info() const { return m_info; }
            uint64_t align() const { return m_align; }
            uint64_t entry_size() const { return m_entry_size; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t* _parent() const { return m__parent; }
            std::string _raw_body() const { return m__raw_body; }
            kaitai::kstream* _io__raw_body() const { return m__io__raw_body; }
        };

        class dynamic_section_t : public kaitai::kstruct {

        public:

            dynamic_section_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~dynamic_section_t();

        private:
            std::vector<dynamic_section_entry_t*>* m_entries;
            elf_t* m__root;
            kaitai::kstruct* m__parent;

        public:
            std::vector<dynamic_section_entry_t*>* entries() const { return m_entries; }
            elf_t* _root() const { return m__root; }
            kaitai::kstruct* _parent() const { return m__parent; }
        };

        class dynsym_section_t : public kaitai::kstruct {

        public:

            dynsym_section_t(kaitai::kstream* p__io, elf_t::endian_elf_t::section_header_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~dynsym_section_t();

        private:
            std::vector<kaitai::kstruct*>* m_entries;
            bool n_entries;

        public:
            bool _is_null_entries() { entries(); return n_entries; };

        private:
            elf_t* m__root;
            elf_t::endian_elf_t::section_header_t* m__parent;

        public:
            std::vector<kaitai::kstruct*>* entries() const { return m_entries; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t::section_header_t* _parent() const { return m__parent; }
        };

        class dynsym_section_entry32_t : public kaitai::kstruct {

        public:

            dynsym_section_entry32_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynsym_section_t* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~dynsym_section_entry32_t();

        private:
            uint32_t m_name_offset;
            uint32_t m_value;
            uint32_t m_size;
            uint8_t m_info;
            uint8_t m_other;
            uint16_t m_shndx;
            elf_t* m__root;
            elf_t::endian_elf_t::dynsym_section_t* m__parent;

        public:
            uint32_t name_offset() const { return m_name_offset; }
            uint32_t value() const { return m_value; }
            uint32_t size() const { return m_size; }
            uint8_t info() const { return m_info; }
            uint8_t other() const { return m_other; }
            uint16_t shndx() const { return m_shndx; }
            elf_t* _root() const { return m__root; }
            elf_t::endian_elf_t::dynsym_section_t* _parent() const { return m__parent; }
        };

        class strings_struct_t : public kaitai::kstruct {

        public:

            strings_struct_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, elf_t* p__root = 0, int p_is_le = -1);

        private:
            int m__is_le;

        public:

        private:
            void _read();

        public:

        private:
            void _read_le();

        public:

        private:
            void _read_be();

        public:
            ~strings_struct_t();

        private:
            std::vector<std::string>* m_entries;
            elf_t* m__root;
            kaitai::kstruct* m__parent;

        public:
            std::vector<std::string>* entries() const { return m_entries; }
            elf_t* _root() const { return m__root; }
            kaitai::kstruct* _parent() const { return m__parent; }
        };

    private:
        bool f_program_headers;
        std::vector<program_header_t*>* m_program_headers;

    public:
        std::vector<program_header_t*>* program_headers();

    private:
        bool f_section_headers;
        std::vector<section_header_t*>* m_section_headers;

    public:
        std::vector<section_header_t*>* section_headers();

    private:
        bool f_strings;
        strings_struct_t* m_strings;

    public:
        strings_struct_t* strings();

    private:
        obj_type_t m_e_type;
        machine_t m_machine;
        uint32_t m_e_version;
        uint64_t m_entry_point;
        bool n_entry_point;

    public:
        bool _is_null_entry_point() { entry_point(); return n_entry_point; };

    private:
        uint64_t m_program_header_offset;
        bool n_program_header_offset;

    public:
        bool _is_null_program_header_offset() { program_header_offset(); return n_program_header_offset; };

    private:
        uint64_t m_section_header_offset;
        bool n_section_header_offset;

    public:
        bool _is_null_section_header_offset() { section_header_offset(); return n_section_header_offset; };

    private:
        std::string m_flags;
        uint16_t m_e_ehsize;
        uint16_t m_program_header_entry_size;
        uint16_t m_qty_program_header;
        uint16_t m_section_header_entry_size;
        uint16_t m_qty_section_header;
        uint16_t m_section_names_idx;
        elf_t* m__root;
        elf_t* m__parent;
        std::vector<std::string>* m__raw_program_headers;
        std::vector<kaitai::kstream*>* m__io__raw_program_headers;
        std::vector<std::string>* m__raw_section_headers;
        std::vector<kaitai::kstream*>* m__io__raw_section_headers;
        std::string m__raw_strings;
        kaitai::kstream* m__io__raw_strings;

    public:
        obj_type_t e_type() const { return m_e_type; }
        machine_t machine() const { return m_machine; }
        uint32_t e_version() const { return m_e_version; }
        uint64_t entry_point() const { return m_entry_point; }
        uint64_t program_header_offset() const { return m_program_header_offset; }
        uint64_t section_header_offset() const { return m_section_header_offset; }
        std::string flags() const { return m_flags; }
        uint16_t e_ehsize() const { return m_e_ehsize; }
        uint16_t program_header_entry_size() const { return m_program_header_entry_size; }
        uint16_t qty_program_header() const { return m_qty_program_header; }
        uint16_t section_header_entry_size() const { return m_section_header_entry_size; }
        uint16_t qty_section_header() const { return m_qty_section_header; }
        uint16_t section_names_idx() const { return m_section_names_idx; }
        elf_t* _root() const { return m__root; }
        elf_t* _parent() const { return m__parent; }
        std::vector<std::string>* _raw_program_headers() const { return m__raw_program_headers; }
        std::vector<kaitai::kstream*>* _io__raw_program_headers() const { return m__io__raw_program_headers; }
        std::vector<std::string>* _raw_section_headers() const { return m__raw_section_headers; }
        std::vector<kaitai::kstream*>* _io__raw_section_headers() const { return m__io__raw_section_headers; }
        std::string _raw_strings() const { return m__raw_strings; }
        kaitai::kstream* _io__raw_strings() const { return m__io__raw_strings; }
    };

private:
    std::string m_magic;
    bits_t m_bits;
    endian_t m_endian;
    uint8_t m_ei_version;
    os_abi_t m_abi;
    uint8_t m_abi_version;
    std::string m_pad;
    endian_elf_t* m_header;
    elf_t* m__root;
    kaitai::kstruct* m__parent;

public:

    /**
     * File identification, must be 0x7f + "ELF".
     */
    std::string magic() const { return m_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.
     */
    bits_t bits() const { return m_bits; }

    /**
     * Endianness used for all integers.
     */
    endian_t endian() const { return m_endian; }

    /**
     * ELF header version.
     */
    uint8_t ei_version() const { return m_ei_version; }

    /**
     * Specifies which OS- and ABI-related extensions will be used
     * in this ELF file.
     */
    os_abi_t abi() const { return m_abi; }

    /**
     * Version of ABI targeted by this ELF file. Interpretation
     * depends on `abi` attribute.
     */
    uint8_t abi_version() const { return m_abi_version; }
    std::string pad() const { return m_pad; }
    endian_elf_t* header() const { return m_header; }
    elf_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
};

#endif  // ELF_H_

elf.cpp

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

#include "elf.h"

#include <stdexcept>

elf_t::elf_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, elf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;
    _read();
}

void elf_t::_read() {
    m_magic = m__io->ensure_fixed_contents(std::string("\x7F\x45\x4C\x46", 4));
    m_bits = static_cast<elf_t::bits_t>(m__io->read_u1());
    m_endian = static_cast<elf_t::endian_t>(m__io->read_u1());
    m_ei_version = m__io->read_u1();
    m_abi = static_cast<elf_t::os_abi_t>(m__io->read_u1());
    m_abi_version = m__io->read_u1();
    m_pad = m__io->read_bytes(7);
    m_header = new endian_elf_t(m__io, this, m__root);
}

elf_t::~elf_t() {
    delete m_header;
}

elf_t::phdr_type_flags_t::phdr_type_flags_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::program_header_t* p__parent, elf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_value = p_value;
    f_read = false;
    f_write = false;
    f_execute = false;
    f_mask_proc = false;
    _read();
}

void elf_t::phdr_type_flags_t::_read() {
}

elf_t::phdr_type_flags_t::~phdr_type_flags_t() {
}

bool elf_t::phdr_type_flags_t::read() {
    if (f_read)
        return m_read;
    m_read = (value() & 4) != 0;
    f_read = true;
    return m_read;
}

bool elf_t::phdr_type_flags_t::write() {
    if (f_write)
        return m_write;
    m_write = (value() & 2) != 0;
    f_write = true;
    return m_write;
}

bool elf_t::phdr_type_flags_t::execute() {
    if (f_execute)
        return m_execute;
    m_execute = (value() & 1) != 0;
    f_execute = true;
    return m_execute;
}

bool elf_t::phdr_type_flags_t::mask_proc() {
    if (f_mask_proc)
        return m_mask_proc;
    m_mask_proc = (value() & 4026531840) != 0;
    f_mask_proc = true;
    return m_mask_proc;
}

elf_t::section_header_flags_t::section_header_flags_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::section_header_t* p__parent, elf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_value = p_value;
    f_merge = false;
    f_mask_os = false;
    f_exclude = false;
    f_mask_proc = false;
    f_strings = false;
    f_os_non_conforming = false;
    f_alloc = false;
    f_exec_instr = false;
    f_info_link = false;
    f_write = false;
    f_link_order = false;
    f_ordered = false;
    f_tls = false;
    f_group = false;
    _read();
}

void elf_t::section_header_flags_t::_read() {
}

elf_t::section_header_flags_t::~section_header_flags_t() {
}

bool elf_t::section_header_flags_t::merge() {
    if (f_merge)
        return m_merge;
    m_merge = (value() & 16) != 0;
    f_merge = true;
    return m_merge;
}

bool elf_t::section_header_flags_t::mask_os() {
    if (f_mask_os)
        return m_mask_os;
    m_mask_os = (value() & 267386880) != 0;
    f_mask_os = true;
    return m_mask_os;
}

bool elf_t::section_header_flags_t::exclude() {
    if (f_exclude)
        return m_exclude;
    m_exclude = (value() & 134217728) != 0;
    f_exclude = true;
    return m_exclude;
}

bool elf_t::section_header_flags_t::mask_proc() {
    if (f_mask_proc)
        return m_mask_proc;
    m_mask_proc = (value() & 4026531840) != 0;
    f_mask_proc = true;
    return m_mask_proc;
}

bool elf_t::section_header_flags_t::strings() {
    if (f_strings)
        return m_strings;
    m_strings = (value() & 32) != 0;
    f_strings = true;
    return m_strings;
}

bool elf_t::section_header_flags_t::os_non_conforming() {
    if (f_os_non_conforming)
        return m_os_non_conforming;
    m_os_non_conforming = (value() & 256) != 0;
    f_os_non_conforming = true;
    return m_os_non_conforming;
}

bool elf_t::section_header_flags_t::alloc() {
    if (f_alloc)
        return m_alloc;
    m_alloc = (value() & 2) != 0;
    f_alloc = true;
    return m_alloc;
}

bool elf_t::section_header_flags_t::exec_instr() {
    if (f_exec_instr)
        return m_exec_instr;
    m_exec_instr = (value() & 4) != 0;
    f_exec_instr = true;
    return m_exec_instr;
}

bool elf_t::section_header_flags_t::info_link() {
    if (f_info_link)
        return m_info_link;
    m_info_link = (value() & 64) != 0;
    f_info_link = true;
    return m_info_link;
}

bool elf_t::section_header_flags_t::write() {
    if (f_write)
        return m_write;
    m_write = (value() & 1) != 0;
    f_write = true;
    return m_write;
}

bool elf_t::section_header_flags_t::link_order() {
    if (f_link_order)
        return m_link_order;
    m_link_order = (value() & 128) != 0;
    f_link_order = true;
    return m_link_order;
}

bool elf_t::section_header_flags_t::ordered() {
    if (f_ordered)
        return m_ordered;
    m_ordered = (value() & 67108864) != 0;
    f_ordered = true;
    return m_ordered;
}

bool elf_t::section_header_flags_t::tls() {
    if (f_tls)
        return m_tls;
    m_tls = (value() & 1024) != 0;
    f_tls = true;
    return m_tls;
}

bool elf_t::section_header_flags_t::group() {
    if (f_group)
        return m_group;
    m_group = (value() & 512) != 0;
    f_group = true;
    return m_group;
}

elf_t::dt_flag_1_values_t::dt_flag_1_values_t(uint32_t p_value, kaitai::kstream* p__io, elf_t::endian_elf_t::dynamic_section_entry_t* p__parent, elf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m_value = p_value;
    f_singleton = false;
    f_ignmuldef = false;
    f_loadfltr = false;
    f_initfirst = false;
    f_symintpose = false;
    f_noreloc = false;
    f_confalt = false;
    f_dispreldne = false;
    f_rtld_global = false;
    f_nodelete = false;
    f_trans = false;
    f_origin = false;
    f_now = false;
    f_nohdr = false;
    f_endfiltee = false;
    f_nodirect = false;
    f_globaudit = false;
    f_noksyms = false;
    f_interpose = false;
    f_nodump = false;
    f_disprelpnd = false;
    f_noopen = false;
    f_stub = false;
    f_direct = false;
    f_edited = false;
    f_group = false;
    f_pie = false;
    f_nodeflib = false;
    _read();
}

void elf_t::dt_flag_1_values_t::_read() {
}

elf_t::dt_flag_1_values_t::~dt_flag_1_values_t() {
}

bool elf_t::dt_flag_1_values_t::singleton() {
    if (f_singleton)
        return m_singleton;
    m_singleton = (value() & 33554432) != 0;
    f_singleton = true;
    return m_singleton;
}

bool elf_t::dt_flag_1_values_t::ignmuldef() {
    if (f_ignmuldef)
        return m_ignmuldef;
    m_ignmuldef = (value() & 262144) != 0;
    f_ignmuldef = true;
    return m_ignmuldef;
}

bool elf_t::dt_flag_1_values_t::loadfltr() {
    if (f_loadfltr)
        return m_loadfltr;
    m_loadfltr = (value() & 16) != 0;
    f_loadfltr = true;
    return m_loadfltr;
}

bool elf_t::dt_flag_1_values_t::initfirst() {
    if (f_initfirst)
        return m_initfirst;
    m_initfirst = (value() & 32) != 0;
    f_initfirst = true;
    return m_initfirst;
}

bool elf_t::dt_flag_1_values_t::symintpose() {
    if (f_symintpose)
        return m_symintpose;
    m_symintpose = (value() & 8388608) != 0;
    f_symintpose = true;
    return m_symintpose;
}

bool elf_t::dt_flag_1_values_t::noreloc() {
    if (f_noreloc)
        return m_noreloc;
    m_noreloc = (value() & 4194304) != 0;
    f_noreloc = true;
    return m_noreloc;
}

bool elf_t::dt_flag_1_values_t::confalt() {
    if (f_confalt)
        return m_confalt;
    m_confalt = (value() & 8192) != 0;
    f_confalt = true;
    return m_confalt;
}

bool elf_t::dt_flag_1_values_t::dispreldne() {
    if (f_dispreldne)
        return m_dispreldne;
    m_dispreldne = (value() & 32768) != 0;
    f_dispreldne = true;
    return m_dispreldne;
}

bool elf_t::dt_flag_1_values_t::rtld_global() {
    if (f_rtld_global)
        return m_rtld_global;
    m_rtld_global = (value() & 2) != 0;
    f_rtld_global = true;
    return m_rtld_global;
}

bool elf_t::dt_flag_1_values_t::nodelete() {
    if (f_nodelete)
        return m_nodelete;
    m_nodelete = (value() & 8) != 0;
    f_nodelete = true;
    return m_nodelete;
}

bool elf_t::dt_flag_1_values_t::trans() {
    if (f_trans)
        return m_trans;
    m_trans = (value() & 512) != 0;
    f_trans = true;
    return m_trans;
}

bool elf_t::dt_flag_1_values_t::origin() {
    if (f_origin)
        return m_origin;
    m_origin = (value() & 128) != 0;
    f_origin = true;
    return m_origin;
}

bool elf_t::dt_flag_1_values_t::now() {
    if (f_now)
        return m_now;
    m_now = (value() & 1) != 0;
    f_now = true;
    return m_now;
}

bool elf_t::dt_flag_1_values_t::nohdr() {
    if (f_nohdr)
        return m_nohdr;
    m_nohdr = (value() & 1048576) != 0;
    f_nohdr = true;
    return m_nohdr;
}

bool elf_t::dt_flag_1_values_t::endfiltee() {
    if (f_endfiltee)
        return m_endfiltee;
    m_endfiltee = (value() & 16384) != 0;
    f_endfiltee = true;
    return m_endfiltee;
}

bool elf_t::dt_flag_1_values_t::nodirect() {
    if (f_nodirect)
        return m_nodirect;
    m_nodirect = (value() & 131072) != 0;
    f_nodirect = true;
    return m_nodirect;
}

bool elf_t::dt_flag_1_values_t::globaudit() {
    if (f_globaudit)
        return m_globaudit;
    m_globaudit = (value() & 16777216) != 0;
    f_globaudit = true;
    return m_globaudit;
}

bool elf_t::dt_flag_1_values_t::noksyms() {
    if (f_noksyms)
        return m_noksyms;
    m_noksyms = (value() & 524288) != 0;
    f_noksyms = true;
    return m_noksyms;
}

bool elf_t::dt_flag_1_values_t::interpose() {
    if (f_interpose)
        return m_interpose;
    m_interpose = (value() & 1024) != 0;
    f_interpose = true;
    return m_interpose;
}

bool elf_t::dt_flag_1_values_t::nodump() {
    if (f_nodump)
        return m_nodump;
    m_nodump = (value() & 4096) != 0;
    f_nodump = true;
    return m_nodump;
}

bool elf_t::dt_flag_1_values_t::disprelpnd() {
    if (f_disprelpnd)
        return m_disprelpnd;
    m_disprelpnd = (value() & 65536) != 0;
    f_disprelpnd = true;
    return m_disprelpnd;
}

bool elf_t::dt_flag_1_values_t::noopen() {
    if (f_noopen)
        return m_noopen;
    m_noopen = (value() & 64) != 0;
    f_noopen = true;
    return m_noopen;
}

bool elf_t::dt_flag_1_values_t::stub() {
    if (f_stub)
        return m_stub;
    m_stub = (value() & 67108864) != 0;
    f_stub = true;
    return m_stub;
}

bool elf_t::dt_flag_1_values_t::direct() {
    if (f_direct)
        return m_direct;
    m_direct = (value() & 256) != 0;
    f_direct = true;
    return m_direct;
}

bool elf_t::dt_flag_1_values_t::edited() {
    if (f_edited)
        return m_edited;
    m_edited = (value() & 2097152) != 0;
    f_edited = true;
    return m_edited;
}

bool elf_t::dt_flag_1_values_t::group() {
    if (f_group)
        return m_group;
    m_group = (value() & 4) != 0;
    f_group = true;
    return m_group;
}

bool elf_t::dt_flag_1_values_t::pie() {
    if (f_pie)
        return m_pie;
    m_pie = (value() & 134217728) != 0;
    f_pie = true;
    return m_pie;
}

bool elf_t::dt_flag_1_values_t::nodeflib() {
    if (f_nodeflib)
        return m_nodeflib;
    m_nodeflib = (value() & 2048) != 0;
    f_nodeflib = true;
    return m_nodeflib;
}

elf_t::endian_elf_t::endian_elf_t(kaitai::kstream* p__io, elf_t* p__parent, elf_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = -1;
    f_program_headers = false;
    f_section_headers = false;
    f_strings = false;
    _read();
}

void elf_t::endian_elf_t::_read() {
    switch (_root()->endian()) {
    case ENDIAN_LE: {
        m__is_le = true;
        break;
    }
    case ENDIAN_BE: {
        m__is_le = false;
        break;
    }
    }

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::_read_le() {
    m_e_type = static_cast<elf_t::obj_type_t>(m__io->read_u2le());
    m_machine = static_cast<elf_t::machine_t>(m__io->read_u2le());
    m_e_version = m__io->read_u4le();
    n_entry_point = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_entry_point = false;
        m_entry_point = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_entry_point = false;
        m_entry_point = m__io->read_u8le();
        break;
    }
    }
    n_program_header_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_program_header_offset = false;
        m_program_header_offset = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_program_header_offset = false;
        m_program_header_offset = m__io->read_u8le();
        break;
    }
    }
    n_section_header_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_section_header_offset = false;
        m_section_header_offset = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_section_header_offset = false;
        m_section_header_offset = m__io->read_u8le();
        break;
    }
    }
    m_flags = m__io->read_bytes(4);
    m_e_ehsize = m__io->read_u2le();
    m_program_header_entry_size = m__io->read_u2le();
    m_qty_program_header = m__io->read_u2le();
    m_section_header_entry_size = m__io->read_u2le();
    m_qty_section_header = m__io->read_u2le();
    m_section_names_idx = m__io->read_u2le();
}

void elf_t::endian_elf_t::_read_be() {
    m_e_type = static_cast<elf_t::obj_type_t>(m__io->read_u2be());
    m_machine = static_cast<elf_t::machine_t>(m__io->read_u2be());
    m_e_version = m__io->read_u4be();
    n_entry_point = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_entry_point = false;
        m_entry_point = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_entry_point = false;
        m_entry_point = m__io->read_u8be();
        break;
    }
    }
    n_program_header_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_program_header_offset = false;
        m_program_header_offset = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_program_header_offset = false;
        m_program_header_offset = m__io->read_u8be();
        break;
    }
    }
    n_section_header_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_section_header_offset = false;
        m_section_header_offset = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_section_header_offset = false;
        m_section_header_offset = m__io->read_u8be();
        break;
    }
    }
    m_flags = m__io->read_bytes(4);
    m_e_ehsize = m__io->read_u2be();
    m_program_header_entry_size = m__io->read_u2be();
    m_qty_program_header = m__io->read_u2be();
    m_section_header_entry_size = m__io->read_u2be();
    m_qty_section_header = m__io->read_u2be();
    m_section_names_idx = m__io->read_u2be();
}

elf_t::endian_elf_t::~endian_elf_t() {
    if (!n_entry_point) {
    }
    if (!n_program_header_offset) {
    }
    if (!n_section_header_offset) {
    }
    if (f_program_headers) {
        delete m__raw_program_headers;
        for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_program_headers->begin(); it != m__io__raw_program_headers->end(); ++it) {
            delete *it;
        }
        delete m__io__raw_program_headers;
        for (std::vector<program_header_t*>::iterator it = m_program_headers->begin(); it != m_program_headers->end(); ++it) {
            delete *it;
        }
        delete m_program_headers;
    }
    if (f_section_headers) {
        delete m__raw_section_headers;
        for (std::vector<kaitai::kstream*>::iterator it = m__io__raw_section_headers->begin(); it != m__io__raw_section_headers->end(); ++it) {
            delete *it;
        }
        delete m__io__raw_section_headers;
        for (std::vector<section_header_t*>::iterator it = m_section_headers->begin(); it != m_section_headers->end(); ++it) {
            delete *it;
        }
        delete m_section_headers;
    }
    if (f_strings) {
        delete m__io__raw_strings;
        delete m_strings;
    }
}

elf_t::endian_elf_t::dynsym_section_entry64_t::dynsym_section_entry64_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynsym_section_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    _read();
}

void elf_t::endian_elf_t::dynsym_section_entry64_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::dynsym_section_entry64_t::_read_le() {
    m_name_offset = m__io->read_u4le();
    m_info = m__io->read_u1();
    m_other = m__io->read_u1();
    m_shndx = m__io->read_u2le();
    m_value = m__io->read_u8le();
    m_size = m__io->read_u8le();
}

void elf_t::endian_elf_t::dynsym_section_entry64_t::_read_be() {
    m_name_offset = m__io->read_u4be();
    m_info = m__io->read_u1();
    m_other = m__io->read_u1();
    m_shndx = m__io->read_u2be();
    m_value = m__io->read_u8be();
    m_size = m__io->read_u8be();
}

elf_t::endian_elf_t::dynsym_section_entry64_t::~dynsym_section_entry64_t() {
}

elf_t::endian_elf_t::program_header_t::program_header_t(kaitai::kstream* p__io, elf_t::endian_elf_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    f_dynamic = false;
    f_flags_obj = false;
    _read();
}

void elf_t::endian_elf_t::program_header_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::program_header_t::_read_le() {
    m_type = static_cast<elf_t::ph_type_t>(m__io->read_u4le());
    n_flags64 = true;
    if (_root()->bits() == BITS_B64) {
        n_flags64 = false;
        m_flags64 = m__io->read_u4le();
    }
    n_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_offset = false;
        m_offset = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_offset = false;
        m_offset = m__io->read_u8le();
        break;
    }
    }
    n_vaddr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_vaddr = false;
        m_vaddr = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_vaddr = false;
        m_vaddr = m__io->read_u8le();
        break;
    }
    }
    n_paddr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_paddr = false;
        m_paddr = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_paddr = false;
        m_paddr = m__io->read_u8le();
        break;
    }
    }
    n_filesz = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_filesz = false;
        m_filesz = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_filesz = false;
        m_filesz = m__io->read_u8le();
        break;
    }
    }
    n_memsz = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_memsz = false;
        m_memsz = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_memsz = false;
        m_memsz = m__io->read_u8le();
        break;
    }
    }
    n_flags32 = true;
    if (_root()->bits() == BITS_B32) {
        n_flags32 = false;
        m_flags32 = m__io->read_u4le();
    }
    n_align = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_align = false;
        m_align = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_align = false;
        m_align = m__io->read_u8le();
        break;
    }
    }
}

void elf_t::endian_elf_t::program_header_t::_read_be() {
    m_type = static_cast<elf_t::ph_type_t>(m__io->read_u4be());
    n_flags64 = true;
    if (_root()->bits() == BITS_B64) {
        n_flags64 = false;
        m_flags64 = m__io->read_u4be();
    }
    n_offset = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_offset = false;
        m_offset = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_offset = false;
        m_offset = m__io->read_u8be();
        break;
    }
    }
    n_vaddr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_vaddr = false;
        m_vaddr = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_vaddr = false;
        m_vaddr = m__io->read_u8be();
        break;
    }
    }
    n_paddr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_paddr = false;
        m_paddr = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_paddr = false;
        m_paddr = m__io->read_u8be();
        break;
    }
    }
    n_filesz = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_filesz = false;
        m_filesz = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_filesz = false;
        m_filesz = m__io->read_u8be();
        break;
    }
    }
    n_memsz = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_memsz = false;
        m_memsz = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_memsz = false;
        m_memsz = m__io->read_u8be();
        break;
    }
    }
    n_flags32 = true;
    if (_root()->bits() == BITS_B32) {
        n_flags32 = false;
        m_flags32 = m__io->read_u4be();
    }
    n_align = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_align = false;
        m_align = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_align = false;
        m_align = m__io->read_u8be();
        break;
    }
    }
}

elf_t::endian_elf_t::program_header_t::~program_header_t() {
    if (!n_flags64) {
    }
    if (!n_offset) {
    }
    if (!n_vaddr) {
    }
    if (!n_paddr) {
    }
    if (!n_filesz) {
    }
    if (!n_memsz) {
    }
    if (!n_flags32) {
    }
    if (!n_align) {
    }
    if (f_dynamic && !n_dynamic) {
        delete m__io__raw_dynamic;
        delete m_dynamic;
    }
    if (f_flags_obj) {
        delete m_flags_obj;
    }
}

elf_t::endian_elf_t::dynamic_section_t* elf_t::endian_elf_t::program_header_t::dynamic() {
    if (f_dynamic)
        return m_dynamic;
    n_dynamic = true;
    if (type() == PH_TYPE_DYNAMIC) {
        n_dynamic = false;
        kaitai::kstream *io = _root()->_io();
        std::streampos _pos = io->pos();
        io->seek(offset());
        if (m__is_le == 1) {
            m__raw_dynamic = io->read_bytes(filesz());
            m__io__raw_dynamic = new kaitai::kstream(m__raw_dynamic);
            m_dynamic = new dynamic_section_t(m__io__raw_dynamic, this, m__root, m__is_le);
        } else {
            m__raw_dynamic = io->read_bytes(filesz());
            m__io__raw_dynamic = new kaitai::kstream(m__raw_dynamic);
            m_dynamic = new dynamic_section_t(m__io__raw_dynamic, this, m__root, m__is_le);
        }
        io->seek(_pos);
    }
    f_dynamic = true;
    return m_dynamic;
}

elf_t::phdr_type_flags_t* elf_t::endian_elf_t::program_header_t::flags_obj() {
    if (f_flags_obj)
        return m_flags_obj;
    if (m__is_le == 1) {
        m_flags_obj = new phdr_type_flags_t((flags64() | flags32()), m__io, this, m__root);
    } else {
        m_flags_obj = new phdr_type_flags_t((flags64() | flags32()), m__io, this, m__root);
    }
    f_flags_obj = true;
    return m_flags_obj;
}

elf_t::endian_elf_t::dynamic_section_entry_t::dynamic_section_entry_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynamic_section_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    f_tag_enum = false;
    f_flag_1_values = false;
    _read();
}

void elf_t::endian_elf_t::dynamic_section_entry_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::dynamic_section_entry_t::_read_le() {
    n_tag = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_tag = false;
        m_tag = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_tag = false;
        m_tag = m__io->read_u8le();
        break;
    }
    }
    n_value_or_ptr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_value_or_ptr = false;
        m_value_or_ptr = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_value_or_ptr = false;
        m_value_or_ptr = m__io->read_u8le();
        break;
    }
    }
}

void elf_t::endian_elf_t::dynamic_section_entry_t::_read_be() {
    n_tag = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_tag = false;
        m_tag = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_tag = false;
        m_tag = m__io->read_u8be();
        break;
    }
    }
    n_value_or_ptr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_value_or_ptr = false;
        m_value_or_ptr = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_value_or_ptr = false;
        m_value_or_ptr = m__io->read_u8be();
        break;
    }
    }
}

elf_t::endian_elf_t::dynamic_section_entry_t::~dynamic_section_entry_t() {
    if (!n_tag) {
    }
    if (!n_value_or_ptr) {
    }
    if (f_flag_1_values && !n_flag_1_values) {
        delete m_flag_1_values;
    }
}

elf_t::dynamic_array_tags_t elf_t::endian_elf_t::dynamic_section_entry_t::tag_enum() {
    if (f_tag_enum)
        return m_tag_enum;
    m_tag_enum = static_cast<elf_t::dynamic_array_tags_t>(tag());
    f_tag_enum = true;
    return m_tag_enum;
}

elf_t::dt_flag_1_values_t* elf_t::endian_elf_t::dynamic_section_entry_t::flag_1_values() {
    if (f_flag_1_values)
        return m_flag_1_values;
    n_flag_1_values = true;
    if (tag_enum() == DYNAMIC_ARRAY_TAGS_FLAGS_1) {
        n_flag_1_values = false;
        if (m__is_le == 1) {
            m_flag_1_values = new dt_flag_1_values_t(value_or_ptr(), m__io, this, m__root);
        } else {
            m_flag_1_values = new dt_flag_1_values_t(value_or_ptr(), m__io, this, m__root);
        }
    }
    f_flag_1_values = true;
    return m_flag_1_values;
}

elf_t::endian_elf_t::section_header_t::section_header_t(kaitai::kstream* p__io, elf_t::endian_elf_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    f_body = false;
    f_name = false;
    f_flags_obj = false;
    _read();
}

void elf_t::endian_elf_t::section_header_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::section_header_t::_read_le() {
    m_ofs_name = m__io->read_u4le();
    m_type = static_cast<elf_t::sh_type_t>(m__io->read_u4le());
    n_flags = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_flags = false;
        m_flags = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_flags = false;
        m_flags = m__io->read_u8le();
        break;
    }
    }
    n_addr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_addr = false;
        m_addr = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_addr = false;
        m_addr = m__io->read_u8le();
        break;
    }
    }
    n_ofs_body = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_ofs_body = false;
        m_ofs_body = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_ofs_body = false;
        m_ofs_body = m__io->read_u8le();
        break;
    }
    }
    n_len_body = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_len_body = false;
        m_len_body = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_len_body = false;
        m_len_body = m__io->read_u8le();
        break;
    }
    }
    m_linked_section_idx = m__io->read_u4le();
    m_info = m__io->read_bytes(4);
    n_align = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_align = false;
        m_align = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_align = false;
        m_align = m__io->read_u8le();
        break;
    }
    }
    n_entry_size = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_entry_size = false;
        m_entry_size = m__io->read_u4le();
        break;
    }
    case BITS_B64: {
        n_entry_size = false;
        m_entry_size = m__io->read_u8le();
        break;
    }
    }
}

void elf_t::endian_elf_t::section_header_t::_read_be() {
    m_ofs_name = m__io->read_u4be();
    m_type = static_cast<elf_t::sh_type_t>(m__io->read_u4be());
    n_flags = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_flags = false;
        m_flags = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_flags = false;
        m_flags = m__io->read_u8be();
        break;
    }
    }
    n_addr = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_addr = false;
        m_addr = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_addr = false;
        m_addr = m__io->read_u8be();
        break;
    }
    }
    n_ofs_body = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_ofs_body = false;
        m_ofs_body = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_ofs_body = false;
        m_ofs_body = m__io->read_u8be();
        break;
    }
    }
    n_len_body = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_len_body = false;
        m_len_body = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_len_body = false;
        m_len_body = m__io->read_u8be();
        break;
    }
    }
    m_linked_section_idx = m__io->read_u4be();
    m_info = m__io->read_bytes(4);
    n_align = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_align = false;
        m_align = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_align = false;
        m_align = m__io->read_u8be();
        break;
    }
    }
    n_entry_size = true;
    switch (_root()->bits()) {
    case BITS_B32: {
        n_entry_size = false;
        m_entry_size = m__io->read_u4be();
        break;
    }
    case BITS_B64: {
        n_entry_size = false;
        m_entry_size = m__io->read_u8be();
        break;
    }
    }
}

elf_t::endian_elf_t::section_header_t::~section_header_t() {
    if (!n_flags) {
    }
    if (!n_addr) {
    }
    if (!n_ofs_body) {
    }
    if (!n_len_body) {
    }
    if (!n_align) {
    }
    if (!n_entry_size) {
    }
    if (f_body && !n_body) {
        delete m__io__raw_body;
        delete m_body;
    }
    if (f_name) {
    }
    if (f_flags_obj) {
        delete m_flags_obj;
    }
}

kaitai::kstruct* elf_t::endian_elf_t::section_header_t::body() {
    if (f_body)
        return m_body;
    kaitai::kstream *io = _root()->_io();
    std::streampos _pos = io->pos();
    io->seek(ofs_body());
    if (m__is_le == 1) {
        n_body = true;
        switch (type()) {
        case SH_TYPE_DYNAMIC: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new dynamic_section_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_STRTAB: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new strings_struct_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_DYNSTR: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new strings_struct_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_DYNSYM: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new dynsym_section_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        default: {
            m__raw_body = io->read_bytes(len_body());
            break;
        }
        }
    } else {
        n_body = true;
        switch (type()) {
        case SH_TYPE_DYNAMIC: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new dynamic_section_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_STRTAB: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new strings_struct_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_DYNSTR: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new strings_struct_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        case SH_TYPE_DYNSYM: {
            n_body = false;
            m__raw_body = io->read_bytes(len_body());
            m__io__raw_body = new kaitai::kstream(m__raw_body);
            m_body = new dynsym_section_t(m__io__raw_body, this, m__root, m__is_le);
            break;
        }
        default: {
            m__raw_body = io->read_bytes(len_body());
            break;
        }
        }
    }
    io->seek(_pos);
    f_body = true;
    return m_body;
}

std::string elf_t::endian_elf_t::section_header_t::name() {
    if (f_name)
        return m_name;
    kaitai::kstream *io = _root()->header()->strings()->_io();
    std::streampos _pos = io->pos();
    io->seek(ofs_name());
    if (m__is_le == 1) {
        m_name = kaitai::kstream::bytes_to_str(io->read_bytes_term(0, false, true, true), std::string("ASCII"));
    } else {
        m_name = kaitai::kstream::bytes_to_str(io->read_bytes_term(0, false, true, true), std::string("ASCII"));
    }
    io->seek(_pos);
    f_name = true;
    return m_name;
}

elf_t::section_header_flags_t* elf_t::endian_elf_t::section_header_t::flags_obj() {
    if (f_flags_obj)
        return m_flags_obj;
    if (m__is_le == 1) {
        m_flags_obj = new section_header_flags_t(flags(), m__io, this, m__root);
    } else {
        m_flags_obj = new section_header_flags_t(flags(), m__io, this, m__root);
    }
    f_flags_obj = true;
    return m_flags_obj;
}

elf_t::endian_elf_t::dynamic_section_t::dynamic_section_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    _read();
}

void elf_t::endian_elf_t::dynamic_section_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::dynamic_section_t::_read_le() {
    m_entries = new std::vector<dynamic_section_entry_t*>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            m_entries->push_back(new dynamic_section_entry_t(m__io, this, m__root, m__is_le));
            i++;
        }
    }
}

void elf_t::endian_elf_t::dynamic_section_t::_read_be() {
    m_entries = new std::vector<dynamic_section_entry_t*>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            m_entries->push_back(new dynamic_section_entry_t(m__io, this, m__root, m__is_le));
            i++;
        }
    }
}

elf_t::endian_elf_t::dynamic_section_t::~dynamic_section_t() {
    for (std::vector<dynamic_section_entry_t*>::iterator it = m_entries->begin(); it != m_entries->end(); ++it) {
        delete *it;
    }
    delete m_entries;
}

elf_t::endian_elf_t::dynsym_section_t::dynsym_section_t(kaitai::kstream* p__io, elf_t::endian_elf_t::section_header_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    _read();
}

void elf_t::endian_elf_t::dynsym_section_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::dynsym_section_t::_read_le() {
    m_entries = new std::vector<kaitai::kstruct*>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            n_entries = true;
            switch (_root()->bits()) {
            case BITS_B32: {
                n_entries = false;
                m_entries->push_back(new dynsym_section_entry32_t(m__io, this, m__root, m__is_le));
                break;
            }
            case BITS_B64: {
                n_entries = false;
                m_entries->push_back(new dynsym_section_entry64_t(m__io, this, m__root, m__is_le));
                break;
            }
            }
            i++;
        }
    }
}

void elf_t::endian_elf_t::dynsym_section_t::_read_be() {
    m_entries = new std::vector<kaitai::kstruct*>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            n_entries = true;
            switch (_root()->bits()) {
            case BITS_B32: {
                n_entries = false;
                m_entries->push_back(new dynsym_section_entry32_t(m__io, this, m__root, m__is_le));
                break;
            }
            case BITS_B64: {
                n_entries = false;
                m_entries->push_back(new dynsym_section_entry64_t(m__io, this, m__root, m__is_le));
                break;
            }
            }
            i++;
        }
    }
}

elf_t::endian_elf_t::dynsym_section_t::~dynsym_section_t() {
    if (!n_entries) {
        for (std::vector<kaitai::kstruct*>::iterator it = m_entries->begin(); it != m_entries->end(); ++it) {
            delete *it;
        }
        delete m_entries;
    }
}

elf_t::endian_elf_t::dynsym_section_entry32_t::dynsym_section_entry32_t(kaitai::kstream* p__io, elf_t::endian_elf_t::dynsym_section_t* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    _read();
}

void elf_t::endian_elf_t::dynsym_section_entry32_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::dynsym_section_entry32_t::_read_le() {
    m_name_offset = m__io->read_u4le();
    m_value = m__io->read_u4le();
    m_size = m__io->read_u4le();
    m_info = m__io->read_u1();
    m_other = m__io->read_u1();
    m_shndx = m__io->read_u2le();
}

void elf_t::endian_elf_t::dynsym_section_entry32_t::_read_be() {
    m_name_offset = m__io->read_u4be();
    m_value = m__io->read_u4be();
    m_size = m__io->read_u4be();
    m_info = m__io->read_u1();
    m_other = m__io->read_u1();
    m_shndx = m__io->read_u2be();
}

elf_t::endian_elf_t::dynsym_section_entry32_t::~dynsym_section_entry32_t() {
}

elf_t::endian_elf_t::strings_struct_t::strings_struct_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, elf_t* p__root, int p_is_le) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    m__is_le = p_is_le;
    _read();
}

void elf_t::endian_elf_t::strings_struct_t::_read() {

    if (m__is_le == -1) {
        throw std::runtime_error("unable to decide on endianness");
    } else if (m__is_le == 1) {
        _read_le();
    } else {
        _read_be();
    }
}

void elf_t::endian_elf_t::strings_struct_t::_read_le() {
    m_entries = new std::vector<std::string>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            m_entries->push_back(kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), std::string("ASCII")));
            i++;
        }
    }
}

void elf_t::endian_elf_t::strings_struct_t::_read_be() {
    m_entries = new std::vector<std::string>();
    {
        int i = 0;
        while (!m__io->is_eof()) {
            m_entries->push_back(kaitai::kstream::bytes_to_str(m__io->read_bytes_term(0, false, true, true), std::string("ASCII")));
            i++;
        }
    }
}

elf_t::endian_elf_t::strings_struct_t::~strings_struct_t() {
    delete m_entries;
}

std::vector<elf_t::endian_elf_t::program_header_t*>* elf_t::endian_elf_t::program_headers() {
    if (f_program_headers)
        return m_program_headers;
    std::streampos _pos = m__io->pos();
    m__io->seek(program_header_offset());
    if (m__is_le == 1) {
        int l_program_headers = qty_program_header();
        m__raw_program_headers = new std::vector<std::string>();
        m__raw_program_headers->reserve(l_program_headers);
        m__io__raw_program_headers = new std::vector<kaitai::kstream*>();
        m__io__raw_program_headers->reserve(l_program_headers);
        m_program_headers = new std::vector<program_header_t*>();
        m_program_headers->reserve(l_program_headers);
        for (int i = 0; i < l_program_headers; i++) {
            m__raw_program_headers->push_back(m__io->read_bytes(program_header_entry_size()));
            kaitai::kstream* io__raw_program_headers = new kaitai::kstream(m__raw_program_headers->at(m__raw_program_headers->size() - 1));
            m__io__raw_program_headers->push_back(io__raw_program_headers);
            m_program_headers->push_back(new program_header_t(io__raw_program_headers, this, m__root, m__is_le));
        }
    } else {
        int l_program_headers = qty_program_header();
        m__raw_program_headers = new std::vector<std::string>();
        m__raw_program_headers->reserve(l_program_headers);
        m__io__raw_program_headers = new std::vector<kaitai::kstream*>();
        m__io__raw_program_headers->reserve(l_program_headers);
        m_program_headers = new std::vector<program_header_t*>();
        m_program_headers->reserve(l_program_headers);
        for (int i = 0; i < l_program_headers; i++) {
            m__raw_program_headers->push_back(m__io->read_bytes(program_header_entry_size()));
            kaitai::kstream* io__raw_program_headers = new kaitai::kstream(m__raw_program_headers->at(m__raw_program_headers->size() - 1));
            m__io__raw_program_headers->push_back(io__raw_program_headers);
            m_program_headers->push_back(new program_header_t(io__raw_program_headers, this, m__root, m__is_le));
        }
    }
    m__io->seek(_pos);
    f_program_headers = true;
    return m_program_headers;
}

std::vector<elf_t::endian_elf_t::section_header_t*>* elf_t::endian_elf_t::section_headers() {
    if (f_section_headers)
        return m_section_headers;
    std::streampos _pos = m__io->pos();
    m__io->seek(section_header_offset());
    if (m__is_le == 1) {
        int l_section_headers = qty_section_header();
        m__raw_section_headers = new std::vector<std::string>();
        m__raw_section_headers->reserve(l_section_headers);
        m__io__raw_section_headers = new std::vector<kaitai::kstream*>();
        m__io__raw_section_headers->reserve(l_section_headers);
        m_section_headers = new std::vector<section_header_t*>();
        m_section_headers->reserve(l_section_headers);
        for (int i = 0; i < l_section_headers; i++) {
            m__raw_section_headers->push_back(m__io->read_bytes(section_header_entry_size()));
            kaitai::kstream* io__raw_section_headers = new kaitai::kstream(m__raw_section_headers->at(m__raw_section_headers->size() - 1));
            m__io__raw_section_headers->push_back(io__raw_section_headers);
            m_section_headers->push_back(new section_header_t(io__raw_section_headers, this, m__root, m__is_le));
        }
    } else {
        int l_section_headers = qty_section_header();
        m__raw_section_headers = new std::vector<std::string>();
        m__raw_section_headers->reserve(l_section_headers);
        m__io__raw_section_headers = new std::vector<kaitai::kstream*>();
        m__io__raw_section_headers->reserve(l_section_headers);
        m_section_headers = new std::vector<section_header_t*>();
        m_section_headers->reserve(l_section_headers);
        for (int i = 0; i < l_section_headers; i++) {
            m__raw_section_headers->push_back(m__io->read_bytes(section_header_entry_size()));
            kaitai::kstream* io__raw_section_headers = new kaitai::kstream(m__raw_section_headers->at(m__raw_section_headers->size() - 1));
            m__io__raw_section_headers->push_back(io__raw_section_headers);
            m_section_headers->push_back(new section_header_t(io__raw_section_headers, this, m__root, m__is_le));
        }
    }
    m__io->seek(_pos);
    f_section_headers = true;
    return m_section_headers;
}

elf_t::endian_elf_t::strings_struct_t* elf_t::endian_elf_t::strings() {
    if (f_strings)
        return m_strings;
    std::streampos _pos = m__io->pos();
    m__io->seek(section_headers()->at(section_names_idx())->ofs_body());
    if (m__is_le == 1) {
        m__raw_strings = m__io->read_bytes(section_headers()->at(section_names_idx())->len_body());
        m__io__raw_strings = new kaitai::kstream(m__raw_strings);
        m_strings = new strings_struct_t(m__io__raw_strings, this, m__root, m__is_le);
    } else {
        m__raw_strings = m__io->read_bytes(section_headers()->at(section_names_idx())->len_body());
        m__io__raw_strings = new kaitai::kstream(m__raw_strings);
        m_strings = new strings_struct_t(m__io__raw_strings, this, m__root, m__is_le);
    }
    m__io->seek(_pos);
    f_strings = true;
    return m_strings;
}