/* p_elf_enum.h --

   This file is part of the UPX executable compressor.

   Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
   Copyright (C) 1996-2025 Laszlo Molnar
   All Rights Reserved.

   UPX and the UCL library are free software; you can redistribute them
   and/or modify them under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.
   If not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Markus F.X.J. Oberhumer              Laszlo Molnar
   <markus@oberhumer.com>               <ezerotven+github@gmail.com>
 */

/*************************************************************************
// Use the preprocessor to work around
//   - that the types embedding these enums have to be PODs, and
//     deriving from an empty base class (which is the usual C++ way
//     of "importing" enums) does not yield a POD any more
//   - that older compilers do not correctly perform EBCO
**************************************************************************/

#if CLANG_FORMAT_DUMMY_CLASS
class Dummy {
#endif

#ifdef WANT_EHDR_ENUM
#undef WANT_EHDR_ENUM
    enum { // indices for e_ident[16]
        EI_CLASS = 4,
        EI_DATA = 5, // Data encoding
        EI_VERSION = 6,
        EI_OSABI = 7,
        EI_ABIVERSION = 8,
    };
    enum {              // e_ident[EI_CLASS]
        ELFCLASS32 = 1, // 32-bit objects
        ELFCLASS64 = 2, // 64-bit objects
    };
    enum {               // e_ident[EI_DATA]
        ELFDATA2LSB = 1, // 2's complement, little endian
        ELFDATA2MSB = 2, // 2's complement, big endian
    };
    enum {                 // e_ident[EI_OSABI]
        ELFOSABI_NONE = 0, // == ELFOSABI_SYSV
        ELFOSABI_NETBSD = 2,
        ELFOSABI_LINUX = 3,
        ELFOSABI_SOLARIS = 6,
        ELFOSABI_AIX = 7,
        ELFOSABI_FREEBSD = 9,
        ELFOSABI_OPENBSD = 12,
        ELFOSABI_ARM = 97,
        ELFOSABI_STANDALONE = 255 // Standalone (embedded) application
    };
    enum {           // e_type
        ET_NONE = 0, /* No file type */
        ET_REL = 1,  /* Relocatable file */
        ET_EXEC = 2, /* Executable file */
        ET_DYN = 3,  /* Shared object file */
        ET_CORE = 4, /* Core file */
    };
    enum {           // e_machine
        EM_NONE = 0, // No machine
        EM_386 = 3,  // i386
        EM_MIPS = 8,
        EM_MIPS_RS3_LE = 10, // MIPS R3000 little-endian
        EM_PPC = 20,
        EM_PPC64 = 21,
        EM_ARM = 40,
        EM_X86_64 = 62, // amd64
        EM_AMD64 = EM_X86_64,
        EM_AARCH64 = 183, // arm64
        EM_ARM64 = EM_AARCH64,
        EM_RISCV = 243, // risc-v
        EM_LOONGARCH = 258,
    };
    enum { // e_version
        EV_CURRENT = 1,
    };
#endif // WANT_EHDR_ENUM

#ifdef WANT_PHDR_ENUM
#undef WANT_PHDR_ENUM
    enum {                         // p_type
        PT_NULL = 0,               /* Ignore: a "comment" */
        PT_LOAD = 1,               /* Loadable program segment */
        PT_DYNAMIC = 2,            /* Dynamic linking information */
        PT_INTERP = 3,             /* Name of program interpreter */
        PT_NOTE = 4,               /* Auxiliary information (esp. OpenBSD) */
        PT_PHDR = 6,               /* Entry for header table itself */
        PT_NUM = 8,                /* Number of defined types in low range */
        PT_GNU_STACK = 0x6474e551, /* Indicates stack executability */
        PT_GNU_RELRO = 0x6474e552, /* Read-only after relocation */
        PT_MIPS_REGINFO = 0x70000000,
        /* Register usage information. */ //
        //      PT_MIPS_RTPROC =   0x70000001, /* Runtime procedure table. */
        //      PT_MIPS_OPTIONS =  0x70000002,
        PT_MIPS_ABIFLAGS = 0x70000003, /* FP mode requirement. */
    };

    enum {        // p_flags
        PF_X = 1, /* Segment is executable */
        PF_W = 2, /* Segment is writable */
        PF_R = 4, /* Segment is readable */
    };
#endif // WANT_PHDR_ENUM

#ifdef WANT_SHDR_ENUM
#undef WANT_SHDR_ENUM
    enum {                // sh_type
        SHT_NULL = 0,     /* Section header table entry unused */
        SHT_PROGBITS = 1, /* Program data */
        SHT_SYMTAB = 2,   /* Symbol table */
        SHT_STRTAB = 3,   /* String table */
        SHT_RELA = 4,     /* Relocation entries with addends */
        SHT_HASH = 5,     /* Symbol hash table */
        SHT_DYNAMIC = 6,  /* Dynamic linking information */
        SHT_NOTE = 7,     /* Notes */
        SHT_NOBITS = 8,   /* Program space with no data (bss) */
        SHT_REL = 9,      /* Relocation entries, no addends */
        SHT_SHLIB = 10,   /* Reserved */
        SHT_DYNSYM = 11,  /* Dynamic linker symbol table */
        /* 12, 13  hole */
        SHT_INIT_ARRAY = 14,          /* Array of constructors */
        SHT_FINI_ARRAY = 15,          /* Array of destructors */
        SHT_PREINIT_ARRAY = 16,       /* Array of pre-constructors */
        SHT_GROUP = 17,               /* Section group */
        SHT_SYMTAB_SHNDX = 18,        /* Extended section indices */
        SHT_RELR = 19,                /* RELR relative relocations */
        SHT_GNU_HASH = 0x6ffffff6,    /* GNU-style hash table.  */
        SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
        SHT_GNU_verdef = 0x6ffffffd,  /* Version definition section.  */
        SHT_GNU_verneed = 0x6ffffffe, /* Version needs section.  */
        SHT_GNU_versym = 0x6fffffff,  /* Version symbol table.  */

        SHT_LOOS = 0x60000000,                 /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
        SHT_LOPROC = 0x70000000,               /* Start of processor-specific */
        SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section.  */
    };

    enum {                         // sh_flags
        SHF_WRITE = (1 << 0),      /* Writable */
        SHF_ALLOC = (1 << 1),      /* Occupies memory during execution */
        SHF_EXECINSTR = (1 << 2),  /* Executable */
        SHF_MERGE = (1 << 4),      /* Might be merged */
        SHF_STRINGS = (1 << 5),    /* Contains nul-terminated strings */
        SHF_INFO_LINK = (1 << 6),  /* 'sh_info' contains SHT index */
        SHF_LINK_ORDER = (1 << 7), /* Preserve order after combining */
    };
#endif // WANT_SHDR_ENUM

#ifdef WANT_DYN_ENUM
#undef WANT_DYN_ENUM
    enum {               // d_tag
        DT_NULL = 0,     /* End flag */
        DT_NEEDED = 1,   /* Name of needed library */
        DT_PLTRELSZ = 2, /* Size in bytes of PLT relocs */
        DT_PLTGOT = 3,   /* Processor defined value */
        DT_HASH = 4,     /* Hash table of symbol names */
        DT_STRTAB = 5,   /* String table */
        DT_SYMTAB = 6,   /* Symbol table */
        DT_RELA = 7,     /* Relocations which do contain an addend */
        DT_RELASZ = 8,   /* Total size of Rela relocs */
        DT_RELAENT = 9,  /* Size of one RELA relocation */
        DT_STRSZ = 10,   /* Size of string table */
        DT_SYMENT = 11,  /* Size of one symbol table entry */
        DT_INIT = 12,    /* Address of init function */
        DT_FINI = 13,    /* Address of termination function */

        DT_REL = 17,             /* Relocations which contain no addend */
        DT_RELSZ = 18,           /* Total size of Rel relocs */
        DT_RELENT = 19,          /* Size of one Rel relocation */
        DT_PLTREL = 20,          /* Type of reloc in PLT */
        DT_TEXTREL = 22,         /* Reloc might modify .text */
        DT_JMPREL = 23,          /* Address of PLT relocs */
        DT_INIT_ARRAY = 25,      /* Array with addresses of init fct */
        DT_FINI_ARRAY = 26,      /* Array with addresses of fini fct */
        DT_INIT_ARRAYSZ = 27,    /* size in bytes */
        DT_FINI_ARRAYSZ = 28,    /* size in bytes */
        DT_PREINIT_ARRAY = 32,   /* Array with addresses of preinit fct*/
        DT_PREINIT_ARRAYSZ = 33, /* size in bytes */
        DT_NUM = 35,             /* end of easy range */

        DT_CHECKSUM = 0x6ffffdf8, /* Only for prelink? */
        DT_GNU_HASH = 0x6ffffef5, /* GNU-style hash table */
        DT_VERSYM = 0x6ffffff0,   /* version[] for each symbol */
        DT_FLAGS_1 = 0x6ffffffb,  /* DF_1_* */
        DT_VERDEF = 0x6ffffffc,   /* version definitions[] */
        DT_VERNEED = 0x6ffffffe,  /* version[] needed */
    };
    enum {                     // DT_FLAGS_1
        DF_1_NOW = 0x00000001, /* Set RTLD_NOW for this object.  */
        DF_1_PIE = 0x08000000, // Position-Independent Executable (main program)
    };
#endif // WANT_DYN_ENUM

#ifdef WANT_SYM_ENUM
#undef WANT_SYM_ENUM
    enum {              // st_bind (high 4 bits of st_info)
        STB_LOCAL = 0,  /* Local symbol */
        STB_GLOBAL = 1, /* Global symbol */
        STB_WEAK = 2,   /* Weak symbol */
    };

    enum {               // st_type (low 4 bits of st_info)
        STT_NOTYPE = 0,  /* Symbol type is unspecified */
        STT_OBJECT = 1,  /* Symbol is a data object */
        STT_FUNC = 2,    /* Symbol is a code object */
        STT_SECTION = 3, /* Symbol associated with a section */
        STT_FILE = 4,    /* Symbol's name is file name */
        STT_COMMON = 5,  /* Symbol is a common data object */
        STT_TLS = 6,     /* Symbol is thread-local data object*/
    };

    enum {                 // st_other (visibility)
        STV_DEFAULT = 0,   /* Default symbol visibility rules */
        STV_INTERNAL = 1,  /* Processor specific hidden class */
        STV_HIDDEN = 2,    /* Sym unavailable in other modules */
        STV_PROTECTED = 3, /* Not preemptible, not exported */
    };

    enum {                   // st_shndx
        SHN_UNDEF = 0,       /* Undefined section */
        SHN_ABS = 0xfff1,    /* Associated symbol is absolute */
        SHN_COMMON = 0xfff2, /* Associated symbol is common */
    };
#endif // WANT_SYM_ENUM

#ifdef WANT_REL_ENUM
#undef WANT_REL_ENUM
    static constexpr inline unsigned ELF32_R_TYPE(unsigned x) noexcept { return 0xff & x; }
    static constexpr inline unsigned ELF64_R_TYPE(upx_uint64_t x) noexcept {
        return 0xffffffff & (unsigned) x;
    }
    static constexpr inline unsigned ELF32_R_SYM(unsigned x) noexcept { return x >> 8; }
    static constexpr inline unsigned ELF64_R_SYM(upx_uint64_t x) noexcept { return x >> 32; }
    static constexpr inline unsigned ELF32_R_INFO(unsigned sym, unsigned type) noexcept {
        return (sym << 8) + (type & 0xff);
    }
    static constexpr inline upx_int64_t ELF64_R_INFO(unsigned sym, unsigned type) {
        return ((upx_uint64_t) sym << 32) + type;
    }

#undef R_PPC_RELATIVE
#undef R_PPC64_RELATIVE
#undef R_PPC_JMP_SLOT
#undef R_PPC64_JMP_SLOT
    enum { // relocation types
        R_386_RELATIVE = 8,
        R_AARCH64_RELATIVE = 1027,
        R_ARM_RELATIVE = 23,
        R_PPC_RELATIVE = 22,
        R_PPC64_RELATIVE = R_PPC_RELATIVE,
        R_X86_64_RELATIVE = 8,

        R_386_JMP_SLOT = 7,
        R_AARCH64_JUMP_SLOT = 1026,
        R_ARM_JUMP_SLOT = 22,
        R_PPC_JMP_SLOT = 21,
        R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT,
        R_X86_64_JUMP_SLOT = 7,

        R_386_32 = 1,
        R_ARM_ABS32 = 2,
        R_ARM_GLOB_DAT = 21,
        R_MIPS_32 = 2,

        R_386_GLOB_DAT = 6,
        R_X86_64_64 = 1,
        R_AARCH64_ABS64 = 257,
        R_AARCH64_GLOB_DAT = 1025,

    };
#endif // WANT_REL_ENUM

#ifdef WANT_NHDR_ENUM
#undef WANT_NHDR_ENUM
    enum { // ELF PT_NOTE types
#define ELF_NOTE_GNU_NAME "GNU\0"
        NT_GNU_ABI_TAG = 1,
        NT_GNU_HWCAP = 2,
        NT_GNU_BUILD_ID = 3,

#define ELF_NOTE_OPENBSD_NAME "OpenBSD\0"
        NHDR_OPENBSD_TAG = 1,

#define ELF_NOTE_NETBSD_NAME "NetBSD\0"
        NHDR_NETBSD_TAG = 1,
        NHDR_CHECKSUM_TAG = 2,
        NHDR_PAX_TAG = 3,
    };

    enum {                   // descsz descriptor sizes
        GNU_ABI_DESCSZ = 16, // int GNU_OS, major, minor, subminor;
        NETBSD_DESCSZ = 4,   // major_ver * (10**8) + minor
        OPENBSD_DESCSZ = 4,  // 32-bit zero
                             // CHECKSUM_DESCSZ is 2*sizeof(short) + sizeof(checksum)
        PAX_DESCSZ = 4,      // 32-bit mask
    };

    enum { // GNU OS/version
        GNU_OS_LINUX = 0,
        GNU_OS_HURD = 1,
        GNU_OS_SOLARIS = 2,
    };

    enum { // NetBSD checksum methods
        CHECKSUM_CRC32 = 1,
        CHECKSUM_MD5 = 2,
        CHECKSUM_SHA1 = 3,
        CHECKSUM_SHA256 = 4,
    };

#define ELF_NOTE_PAX_NAME "PaX\0"
    enum {                         // NetBSD PaX bit values
        PAX_MPROTECT = (1 << 0),   /* force  enable Mprotect */
        PAX_NOMPROTECT = (1 << 1), /* force disable Mprotect */
        PAX_GUARD = (1 << 2),      /* force  enable SEGVguard */
        PAX_NOGUARD = (1 << 3),    /* force disable SEGVguard */
        PAX_ASLR = (1 << 4),       /* force  enable ASLR */
        PAX_NOASLR = (1 << 5),     /* force disable ASLR */
    };
#endif // WANT_NHDR_ENUM

#if CLANG_FORMAT_DUMMY_CLASS
}; // class
#endif

/* vim:set ts=4 sw=4 et: */
