14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_AOT_FILE_ELF_CHECKER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_AOT_FILE_ELF_CHECKER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_manager.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/binary_section.h"
214514f5e3Sopenharmony_ci#include <fcntl.h>
224514f5e3Sopenharmony_ci#include <stddef.h>
234514f5e3Sopenharmony_ci#include <stdint.h>
244514f5e3Sopenharmony_ci#include <string>
254514f5e3Sopenharmony_ci#include <unistd.h>
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_ci#if BYTE_ORDER == LITTLE_ENDIAN
284514f5e3Sopenharmony_ci#define ELF_BYTEORDER llvm::ELF::ELFDATA2LSB
294514f5e3Sopenharmony_ci#else
304514f5e3Sopenharmony_ci#define ELF_BYTEORDER llvm::ELF::ELFDATA2MSB
314514f5e3Sopenharmony_ci#endif
324514f5e3Sopenharmony_ci#if (defined __i386__ || defined __x86_64__) && !CHECK_UNDEFINED
334514f5e3Sopenharmony_ci#define ALLOW_UNALIGNED 1
344514f5e3Sopenharmony_ci#else
354514f5e3Sopenharmony_ci#define ALLOW_UNALIGNED 0
364514f5e3Sopenharmony_ci#endif
374514f5e3Sopenharmony_ci
384514f5e3Sopenharmony_cinamespace panda::ecmascript {
394514f5e3Sopenharmony_ciclass ElfChecker {
404514f5e3Sopenharmony_cipublic:
414514f5e3Sopenharmony_ci    enum { ELF_F_MMAPPED = 0x40, ELF_F_MALLOCED = 0x80, ELF_F_FILEDATA = 0x100 };
424514f5e3Sopenharmony_ci
434514f5e3Sopenharmony_ci    /* Identification values for recognized object files.  */
444514f5e3Sopenharmony_ci    enum ElfKind {
454514f5e3Sopenharmony_ci        ELF_KIND_NONE, /* Unknown.  */
464514f5e3Sopenharmony_ci        ELF_KIND_COFF, /* Stupid old COFF.  */
474514f5e3Sopenharmony_ci        ELF_KIND_ELF, /* ELF file.  */
484514f5e3Sopenharmony_ci        /* Keep this the last entry.  */
494514f5e3Sopenharmony_ci        ELF_KIND_NUM
504514f5e3Sopenharmony_ci    };
514514f5e3Sopenharmony_ci
524514f5e3Sopenharmony_ci    /* Commands for `...'.  */
534514f5e3Sopenharmony_ci    enum ElfCommand {
544514f5e3Sopenharmony_ci        ELF_CMD_NULL, /* Nothing, terminate, or compute only.  */
554514f5e3Sopenharmony_ci        ELF_CMD_READ, /* Read .. */
564514f5e3Sopenharmony_ci        ELF_CMD_RDWR, /* Read and write .. */
574514f5e3Sopenharmony_ci        ELF_CMD_WRITE, /* Write .. */
584514f5e3Sopenharmony_ci        ELF_CMD_CLR, /* Clear flag.  */
594514f5e3Sopenharmony_ci        ELF_CMD_SET, /* Set flag.  */
604514f5e3Sopenharmony_ci        ELF_CMD_FDDONE, /* Signal that file descriptor will not be
614514f5e3Sopenharmony_ci                 used anymore.  */
624514f5e3Sopenharmony_ci        ELF_CMD_FDREAD, /* Read rest of data so that file descriptor
634514f5e3Sopenharmony_ci                 is not used anymore.  */
644514f5e3Sopenharmony_ci        /* The following are extensions.  */
654514f5e3Sopenharmony_ci        ELF_CMD_READ_MMAP, /* Read, but mmap the file if possible.  */
664514f5e3Sopenharmony_ci        ELF_CMD_RDWR_MMAP, /* Read and write, with mmap.  */
674514f5e3Sopenharmony_ci        ELF_CMD_WRITE_MMAP, /* Write, with mmap.  */
684514f5e3Sopenharmony_ci        ELF_CMD_READ_MMAP_PRIVATE, /* Read, but memory is writable, results are
694514f5e3Sopenharmony_ci                        not written to the file.  */
704514f5e3Sopenharmony_ci        ELF_CMD_EMPTY, /* Copy basic file data but not the content. */
714514f5e3Sopenharmony_ci        /* Keep this the last entry.  */
724514f5e3Sopenharmony_ci        ELF_CMD_NUM
734514f5e3Sopenharmony_ci    };
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ci    /* Known translation types.  */
764514f5e3Sopenharmony_ci    enum ElfType {
774514f5e3Sopenharmony_ci        ELF_TYPE_BYTE, /* unsigned char */
784514f5e3Sopenharmony_ci        ELF_TYPE_ADDR, /* Elf32_Addr, Elf64_Addr, ... */
794514f5e3Sopenharmony_ci        ELF_TYPE_DYN, /* Dynamic section record.  */
804514f5e3Sopenharmony_ci        ELF_TYPE_EHDR, /* ELF header.  */
814514f5e3Sopenharmony_ci        ELF_TYPE_HALF, /* Elf32_Half, Elf64_Half, ... */
824514f5e3Sopenharmony_ci        ELF_TYPE_OFF, /* Elf32_Off, Elf64_Off, ... */
834514f5e3Sopenharmony_ci        ELF_TYPE_PHDR, /* Program header.  */
844514f5e3Sopenharmony_ci        ELF_TYPE_RELA, /* Relocation entry with addend.  */
854514f5e3Sopenharmony_ci        ELF_TYPE_REL, /* Relocation entry.  */
864514f5e3Sopenharmony_ci        ELF_TYPE_SHDR, /* Section header.  */
874514f5e3Sopenharmony_ci        ELF_TYPE_SWORD, /* Elf32_Sword, Elf64_Sword, ... */
884514f5e3Sopenharmony_ci        ELF_TYPE_SYM, /* Symbol record.  */
894514f5e3Sopenharmony_ci        ELF_TYPE_WORD, /* Elf32_Word, Elf64_Word, ... */
904514f5e3Sopenharmony_ci        ELF_TYPE_XWORD, /* Elf32_Xword, Elf64_Xword, ... */
914514f5e3Sopenharmony_ci        ELF_TYPE_SXWORD, /* Elf32_Sxword, Elf64_Sxword, ... */
924514f5e3Sopenharmony_ci        ELF_TYPE_VDEF, /* Elf32_Verdef, Elf64_Verdef, ... */
934514f5e3Sopenharmony_ci        ELF_TYPE_VDAUX, /* Elf32_Verdaux, Elf64_Verdaux, ... */
944514f5e3Sopenharmony_ci        ELF_TYPE_VNEED, /* Elf32_Verneed, Elf64_Verneed, ... */
954514f5e3Sopenharmony_ci        ELF_TYPE_VNAUX, /* Elf32_Vernaux, Elf64_Vernaux, ... */
964514f5e3Sopenharmony_ci        ELF_TYPE_NHDR, /* Elf32_Nhdr, Elf64_Nhdr, ... */
974514f5e3Sopenharmony_ci        ELF_TYPE_SYMINFO, /* Elf32_Syminfo, Elf64_Syminfo, ... */
984514f5e3Sopenharmony_ci        ELF_TYPE_MOVE, /* Elf32_Move, Elf64_Move, ... */
994514f5e3Sopenharmony_ci        ELF_TYPE_LIB, /* Elf32_Lib, Elf64_Lib, ... */
1004514f5e3Sopenharmony_ci        ELF_TYPE_GNUHASH, /* GNU-style hash section.  */
1014514f5e3Sopenharmony_ci        ELF_TYPE_AUXV, /* Elf32_auxv_t, Elf64_auxv_t, ... */
1024514f5e3Sopenharmony_ci        ELF_TYPE_CHDR, /* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
1034514f5e3Sopenharmony_ci        ELF_TYPE_NHDR8, /* Special GNU Properties note.  Same as Nhdr,
1044514f5e3Sopenharmony_ci                except padding.  */
1054514f5e3Sopenharmony_ci        /* Keep this the last entry.  */
1064514f5e3Sopenharmony_ci        ELF_TYPE_NUM
1074514f5e3Sopenharmony_ci    };
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_ci    /* Error values.  */
1104514f5e3Sopenharmony_ci    enum {
1114514f5e3Sopenharmony_ci        ELF_ERR_NOERROR = 0,
1124514f5e3Sopenharmony_ci        ELF_ERR_UNKNOWN_ERROR,
1134514f5e3Sopenharmony_ci        ELF_ERR_UNKNOWN_VERSION,
1144514f5e3Sopenharmony_ci        ELF_ERR_UNKNOWN_TYPE,
1154514f5e3Sopenharmony_ci        ELF_ERR_INVALID_HANDLE,
1164514f5e3Sopenharmony_ci        ELF_ERR_SOURCE_SIZE,
1174514f5e3Sopenharmony_ci        ELF_ERR_DEST_SIZE,
1184514f5e3Sopenharmony_ci        ELF_ERR_INVALID_ENCODING,
1194514f5e3Sopenharmony_ci        ELF_ERR_NOMEM,
1204514f5e3Sopenharmony_ci        ELF_ERR_INVALID_FILE,
1214514f5e3Sopenharmony_ci        ELF_ERR_INVALID_ELF,
1224514f5e3Sopenharmony_ci        ELF_ERR_INVALID_OP,
1234514f5e3Sopenharmony_ci        ELF_ERR_NO_VERSION,
1244514f5e3Sopenharmony_ci        ELF_ERR_INVALID_CMD,
1254514f5e3Sopenharmony_ci        ELF_ERR_RANGE,
1264514f5e3Sopenharmony_ci        ELF_ERR_ARCHIVE_FMAG,
1274514f5e3Sopenharmony_ci        ELF_ERR_INVALID_ARCHIVE,
1284514f5e3Sopenharmony_ci        ELF_ERR_NO_ARCHIVE,
1294514f5e3Sopenharmony_ci        ELF_ERR_NO_INDEX,
1304514f5e3Sopenharmony_ci        ELF_ERR_READ_ERROR,
1314514f5e3Sopenharmony_ci        ELF_ERR_WRITE_ERROR,
1324514f5e3Sopenharmony_ci        ELF_ERR_INVALID_CLASS,
1334514f5e3Sopenharmony_ci        ELF_ERR_INVALID_INDEX,
1344514f5e3Sopenharmony_ci        ELF_ERR_INVALID_OPERAND,
1354514f5e3Sopenharmony_ci        ELF_ERR_INVALID_SECTION,
1364514f5e3Sopenharmony_ci        ELF_ERR_INVALID_COMMAND,
1374514f5e3Sopenharmony_ci        ELF_ERR_WRONG_ORDER_EHDR,
1384514f5e3Sopenharmony_ci        ELF_ERR_FD_DISABLED,
1394514f5e3Sopenharmony_ci        ELF_ERR_FD_MISMATCH,
1404514f5e3Sopenharmony_ci        ELF_ERR_OFFSET_RANGE,
1414514f5e3Sopenharmony_ci        ELF_ERR_NOT_NUL_SECTION,
1424514f5e3Sopenharmony_ci        ELF_ERR_DATA_MISMATCH,
1434514f5e3Sopenharmony_ci        ELF_ERR_INVALID_SECTION_HEADER,
1444514f5e3Sopenharmony_ci        ELF_ERR_INVALID_DATA,
1454514f5e3Sopenharmony_ci        ELF_ERR_DATA_ENCODING,
1464514f5e3Sopenharmony_ci        ELF_ERR_SECTION_TOO_SMALL,
1474514f5e3Sopenharmony_ci        ELF_ERR_INVALID_ALIGN,
1484514f5e3Sopenharmony_ci        ELF_ERR_INVALID_SHENTSIZE,
1494514f5e3Sopenharmony_ci        ELF_ERR_UPDATE_RO,
1504514f5e3Sopenharmony_ci        ELF_ERR_NOFILE,
1514514f5e3Sopenharmony_ci        ELF_ERR_GROUP_NOT_REL,
1524514f5e3Sopenharmony_ci        ELF_ERR_INVALID_PHDR,
1534514f5e3Sopenharmony_ci        ELF_ERR_NO_PHDR,
1544514f5e3Sopenharmony_ci        ELF_ERR_INVALID_OFFSET,
1554514f5e3Sopenharmony_ci        ELF_ERR_INVALID_SECTION_TYPE,
1564514f5e3Sopenharmony_ci        ELF_ERR_INVALID_SECTION_FLAGS,
1574514f5e3Sopenharmony_ci        ELF_ERR_NOT_COMPRESSED,
1584514f5e3Sopenharmony_ci        ELF_ERR_ALREADY_COMPRESSED,
1594514f5e3Sopenharmony_ci        ELF_ERR_UNKNOWN_COMPRESSION_TYPE,
1604514f5e3Sopenharmony_ci        ELF_ERR_COMPRESS_ERROR,
1614514f5e3Sopenharmony_ci        ELF_ERR_DECOMPRESS_ERROR,
1624514f5e3Sopenharmony_ci        /* Keep this as the last entry.  */
1634514f5e3Sopenharmony_ci        ELF_ERR_NUM
1644514f5e3Sopenharmony_ci    };
1654514f5e3Sopenharmony_ci
1664514f5e3Sopenharmony_ci    /* Descriptor for data to be converted to or from memory format.  */
1674514f5e3Sopenharmony_ci    struct ElfData {
1684514f5e3Sopenharmony_ci        void* dataBuffer; /* Pointer to the actual data.  */
1694514f5e3Sopenharmony_ci        ElfType dataType; /* Type of this piece of data.  */
1704514f5e3Sopenharmony_ci        unsigned int dataVersion; /* ELF version.  */
1714514f5e3Sopenharmony_ci        size_t dataSize; /* Size in bytes.  */
1724514f5e3Sopenharmony_ci        int64_t sectionOffset; /* Offset into section.  */
1734514f5e3Sopenharmony_ci        size_t sectionAlignment; /* Alignment in section.  */
1744514f5e3Sopenharmony_ci    };
1754514f5e3Sopenharmony_ci
1764514f5e3Sopenharmony_ci    struct ElfSectionBase;
1774514f5e3Sopenharmony_ci    struct ElfSectionList;
1784514f5e3Sopenharmony_ci    struct Elf;
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_ci    /* The visible `ElfData' type is not sufficient for some operations due
1814514f5e3Sopenharmony_ci       to a misdesigned interface.  Extend it for internal purposes.  */
1824514f5e3Sopenharmony_ci    struct ElfSectionData {
1834514f5e3Sopenharmony_ci        ElfData data;
1844514f5e3Sopenharmony_ci        ElfSectionBase* sectionPtr;
1854514f5e3Sopenharmony_ci    };
1864514f5e3Sopenharmony_ci
1874514f5e3Sopenharmony_ci    /* List of `ElfData' descriptors.  This is what makes up the section
1884514f5e3Sopenharmony_ci       contents.  */
1894514f5e3Sopenharmony_ci    struct ElfDataList {
1904514f5e3Sopenharmony_ci        /* `data' *must* be the first element in the struct.  */
1914514f5e3Sopenharmony_ci        ElfSectionData data;
1924514f5e3Sopenharmony_ci        struct ElfDataList* next;
1934514f5e3Sopenharmony_ci        int flags;
1944514f5e3Sopenharmony_ci    };
1954514f5e3Sopenharmony_ci
1964514f5e3Sopenharmony_ci    /* Descriptor for ELF section.  */
1974514f5e3Sopenharmony_ci    struct ElfSectionBase {
1984514f5e3Sopenharmony_ci        /* Describe for elf sections */
1994514f5e3Sopenharmony_ci        ElfDataList dataList; /* List of data buffers.  */
2004514f5e3Sopenharmony_ci        ElfDataList* dataListRear; /* Pointer to the rear of the data list. */
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_ci        ElfSectionData rawData; /* Uninterpreted data of the section.  */
2034514f5e3Sopenharmony_ci
2044514f5e3Sopenharmony_ci        int dataRead; /* Nonzero if the section was created by the
2054514f5e3Sopenharmony_ci                      user or if the data from the file/memory
2064514f5e3Sopenharmony_ci                      is read.  */
2074514f5e3Sopenharmony_ci        int extendSectionHeaderIndex; /* Index of the extended section index
2084514f5e3Sopenharmony_ci                  table for this symbol table (if this
2094514f5e3Sopenharmony_ci                  section is a symbol table).  */
2104514f5e3Sopenharmony_ci
2114514f5e3Sopenharmony_ci        size_t index; /* Index of this section.  */
2124514f5e3Sopenharmony_ci        struct Elf* elf; /* The underlying ELF file.  */
2134514f5e3Sopenharmony_ci
2144514f5e3Sopenharmony_ci        union {
2154514f5e3Sopenharmony_ci            llvm::ELF::Elf32_Shdr* e32; /* Pointer to 32bit section header.  */
2164514f5e3Sopenharmony_ci            llvm::ELF::Elf64_Shdr* e64; /* Pointer to 64bit section header.  */
2174514f5e3Sopenharmony_ci        } shdr;
2184514f5e3Sopenharmony_ci
2194514f5e3Sopenharmony_ci        unsigned int sectionHeaderFlags; /* Section header modified?  */
2204514f5e3Sopenharmony_ci        unsigned int flags; /* Section changed in size? */
2214514f5e3Sopenharmony_ci
2224514f5e3Sopenharmony_ci        char* rawDataBase; /* The unmodified data of the section.  */
2234514f5e3Sopenharmony_ci        char* dataBase; /* The converted data of the section.  */
2244514f5e3Sopenharmony_ci
2254514f5e3Sopenharmony_ci        char* zipDataBase; /* The uncompressed data of the section.  */
2264514f5e3Sopenharmony_ci        size_t zipDataSize; /* If zipDataBase != NULL, the size of data.  */
2274514f5e3Sopenharmony_ci        size_t zipDataAlign; /* If zipDataBase != NULL, the addralign.  */
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_ci        ElfSectionList* list; /* Pointer to the section list element the
2304514f5e3Sopenharmony_ci                         data is in.  */
2314514f5e3Sopenharmony_ci    };
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ci    /* List of section.  */
2344514f5e3Sopenharmony_ci    struct ElfSectionList {
2354514f5e3Sopenharmony_ci        unsigned int cnt; /* Number of elements of 'data' used.  */
2364514f5e3Sopenharmony_ci        unsigned int max; /* Number of elements of 'data' allocated.  */
2374514f5e3Sopenharmony_ci        struct ElfSectionList* next; /* Next block of sections.  */
2384514f5e3Sopenharmony_ci        ElfSectionBase* data()
2394514f5e3Sopenharmony_ci        {
2404514f5e3Sopenharmony_ci            return reinterpret_cast<ElfSectionBase*>(reinterpret_cast<char*>(this) + sizeof(ElfSectionList));
2414514f5e3Sopenharmony_ci        }
2424514f5e3Sopenharmony_ci    };
2434514f5e3Sopenharmony_ci
2444514f5e3Sopenharmony_ci    /* elf_getdata_rawchunk result.  */
2454514f5e3Sopenharmony_ci    struct ElfDataChunk {
2464514f5e3Sopenharmony_ci        ElfSectionData data;
2474514f5e3Sopenharmony_ci        union {
2484514f5e3Sopenharmony_ci            ElfSectionBase dummySection;
2494514f5e3Sopenharmony_ci            struct ElfDataChunk* next;
2504514f5e3Sopenharmony_ci        };
2514514f5e3Sopenharmony_ci        int64_t offset; /* The original raw offset in the Elf image.  */
2524514f5e3Sopenharmony_ci    };
2534514f5e3Sopenharmony_ci
2544514f5e3Sopenharmony_ci    struct Elf {
2554514f5e3Sopenharmony_ci        /* Address to which the file was mapped.  NULL if not mapped.  */
2564514f5e3Sopenharmony_ci        void* mapAddress;
2574514f5e3Sopenharmony_ci
2584514f5e3Sopenharmony_ci        /* When created for an archive member this points to the descriptor
2594514f5e3Sopenharmony_ci           for the archive. */
2604514f5e3Sopenharmony_ci        Elf* parent;
2614514f5e3Sopenharmony_ci        Elf* next; /* Used in list of archive descriptors.  */
2624514f5e3Sopenharmony_ci
2634514f5e3Sopenharmony_ci        /* What kind of file is underneath (ELF file, archive...).  */
2644514f5e3Sopenharmony_ci        ElfKind kind;
2654514f5e3Sopenharmony_ci
2664514f5e3Sopenharmony_ci        /* Command used to create this descriptor.  */
2674514f5e3Sopenharmony_ci        ElfCommand cmd;
2684514f5e3Sopenharmony_ci
2694514f5e3Sopenharmony_ci        /* The binary class.  */
2704514f5e3Sopenharmony_ci        unsigned int binaryClass;
2714514f5e3Sopenharmony_ci
2724514f5e3Sopenharmony_ci        /* The used file descriptor.  -1 if not available anymore.  */
2734514f5e3Sopenharmony_ci        int fildes;
2744514f5e3Sopenharmony_ci
2754514f5e3Sopenharmony_ci        /* Offset in the archive this file starts or zero.  */
2764514f5e3Sopenharmony_ci        int64_t startOffset;
2774514f5e3Sopenharmony_ci
2784514f5e3Sopenharmony_ci        /* Size of the file in the archive or the entire file size, or ~0
2794514f5e3Sopenharmony_ci           for an (yet) unknown size.  */
2804514f5e3Sopenharmony_ci        size_t maxSize;
2814514f5e3Sopenharmony_ci
2824514f5e3Sopenharmony_ci        /* Describes the way the memory was allocated and if the dirty bit is
2834514f5e3Sopenharmony_ci           signalled it means that the whole file has to be rewritten since
2844514f5e3Sopenharmony_ci           the layout changed.  */
2854514f5e3Sopenharmony_ci        int flags;
2864514f5e3Sopenharmony_ci
2874514f5e3Sopenharmony_ci        /* Reference counting for the descriptor.  */
2884514f5e3Sopenharmony_ci        int refCount;
2894514f5e3Sopenharmony_ci
2904514f5e3Sopenharmony_ci        union {
2914514f5e3Sopenharmony_ci            struct {
2924514f5e3Sopenharmony_ci                void* elfHeaderPtr;
2934514f5e3Sopenharmony_ci                void* secHeaderPtr;
2944514f5e3Sopenharmony_ci                void* proHeaderPtr;
2954514f5e3Sopenharmony_ci
2964514f5e3Sopenharmony_ci                ElfSectionList* sectionLast; /* Last element in the section list.
2974514f5e3Sopenharmony_ci                             If NULL the data has not yet been
2984514f5e3Sopenharmony_ci                             read from the file.  */
2994514f5e3Sopenharmony_ci                ElfDataChunk* rawChunks; /* List of elf_getdata_rawchunk results.  */
3004514f5e3Sopenharmony_ci                unsigned int scnincr; /* Number of sections allocate the last
3014514f5e3Sopenharmony_ci                             time.  */
3024514f5e3Sopenharmony_ci                int elfHeaderFlags; /* Flags (dirty) for ELF header.  */
3034514f5e3Sopenharmony_ci                int progHeaderFlags; /* Flags (dirty|malloc) for program header.  */
3044514f5e3Sopenharmony_ci                int secHeaderMalloced; /* Nonzero if shdr array was allocated.  */
3054514f5e3Sopenharmony_ci                off_t sizeStrOffset; /* Offset of the size string in the parent
3064514f5e3Sopenharmony_ci                             if this is an archive member.  */
3074514f5e3Sopenharmony_ci            } elf;
3084514f5e3Sopenharmony_ci
3094514f5e3Sopenharmony_ci            struct {
3104514f5e3Sopenharmony_ci                llvm::ELF::Elf32_Ehdr* ehdr; /* Pointer to the ELF header.  This is
3114514f5e3Sopenharmony_ci                       never malloced.  */
3124514f5e3Sopenharmony_ci                llvm::ELF::Elf32_Shdr* shdr; /* Used when reading from a file.  */
3134514f5e3Sopenharmony_ci                llvm::ELF::Elf32_Phdr* phdr; /* Pointer to the program header array.  */
3144514f5e3Sopenharmony_ci                ElfSectionList* sectionLast; /* Last element in the section list.
3154514f5e3Sopenharmony_ci                             If NULL the data has not yet been
3164514f5e3Sopenharmony_ci                             read from the file.  */
3174514f5e3Sopenharmony_ci                ElfDataChunk* rawChunks; /* List of elf_getdata_rawchunk results.  */
3184514f5e3Sopenharmony_ci                unsigned int scnincr; /* Number of sections allocate the last
3194514f5e3Sopenharmony_ci                             time.  */
3204514f5e3Sopenharmony_ci                int elfHeaderFlags; /* Flags (dirty) for ELF header.  */
3214514f5e3Sopenharmony_ci                int progHeaderFlags; /* Flags (dirty|malloc) for program header.  */
3224514f5e3Sopenharmony_ci                int secHeaderMalloced; /* Nonzero if shdr array was allocated.  */
3234514f5e3Sopenharmony_ci                int64_t sizeStrOffset; /* Offset of the size string in the parent
3244514f5e3Sopenharmony_ci                             if this is an archive member.  */
3254514f5e3Sopenharmony_ci                llvm::ELF::Elf32_Ehdr elfHeaderMem; /* Memory used for ELF header when
3264514f5e3Sopenharmony_ci                            not mmaped.  */
3274514f5e3Sopenharmony_ci                char fillToAlign[sizeof(llvm::ELF::Elf64_Ehdr) - sizeof(llvm::ELF::Elf32_Ehdr)];
3284514f5e3Sopenharmony_ci
3294514f5e3Sopenharmony_ci                /* The section array.  */
3304514f5e3Sopenharmony_ci                ElfSectionList sections;
3314514f5e3Sopenharmony_ci            } elf32;
3324514f5e3Sopenharmony_ci
3334514f5e3Sopenharmony_ci            struct {
3344514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Ehdr* ehdr; /* Pointer to the ELF header.  This is
3354514f5e3Sopenharmony_ci                       never malloced.  */
3364514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Shdr* shdr; /* Used when reading from a file.  */
3374514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Phdr* phdr; /* Pointer to the program header array.  */
3384514f5e3Sopenharmony_ci                ElfSectionList* sectionLast; /* Last element in the section list.
3394514f5e3Sopenharmony_ci                             If NULL the data has not yet been
3404514f5e3Sopenharmony_ci                             read from the file.  */
3414514f5e3Sopenharmony_ci                ElfDataChunk* rawChunks; /* List of elf_getdata_rawchunk results.  */
3424514f5e3Sopenharmony_ci                unsigned int scnincr; /* Number of sections allocate the last
3434514f5e3Sopenharmony_ci                             time.  */
3444514f5e3Sopenharmony_ci                int elfHeaderFlags; /* Flags (dirty) for ELF header.  */
3454514f5e3Sopenharmony_ci                int progHeaderFlags; /* Flags (dirty|malloc) for program header.  */
3464514f5e3Sopenharmony_ci                int secHeaderMalloced; /* Nonzero if shdr array was allocated.  */
3474514f5e3Sopenharmony_ci                int64_t sizeStrOffset; /* Offset of the size string in the parent
3484514f5e3Sopenharmony_ci                             if this is an archive member.  */
3494514f5e3Sopenharmony_ci                llvm::ELF::Elf64_Ehdr elfHeaderMem; /* Memory used for ELF header when
3504514f5e3Sopenharmony_ci                            not mmaped.  */
3514514f5e3Sopenharmony_ci
3524514f5e3Sopenharmony_ci                /* The section array.  */
3534514f5e3Sopenharmony_ci                ElfSectionList sections;
3544514f5e3Sopenharmony_ci            } elf64;
3554514f5e3Sopenharmony_ci        } state;
3564514f5e3Sopenharmony_ci
3574514f5e3Sopenharmony_ci        /* There absolutely never must be anything following the union.  */
3584514f5e3Sopenharmony_ci    };
3594514f5e3Sopenharmony_ci
3604514f5e3Sopenharmony_ci    ElfChecker() = delete;
3614514f5e3Sopenharmony_ci    ElfChecker(const ElfChecker&) = delete;
3624514f5e3Sopenharmony_ci    explicit ElfChecker(const void* data, int len);
3634514f5e3Sopenharmony_ci    explicit ElfChecker(const std::string&);
3644514f5e3Sopenharmony_ci    explicit ElfChecker(const MemMap&);
3654514f5e3Sopenharmony_ci    ~ElfChecker();
3664514f5e3Sopenharmony_ci    bool CheckValidElf();
3674514f5e3Sopenharmony_ci
3684514f5e3Sopenharmony_ciprivate:
3694514f5e3Sopenharmony_ci    int CheckIfError(void) const;
3704514f5e3Sopenharmony_ci    void SetErrorCode(int value);
3714514f5e3Sopenharmony_ci
3724514f5e3Sopenharmony_ci    Elf* ElfAllocate(
3734514f5e3Sopenharmony_ci        void* map_address, int64_t offset, size_t maxsize, ElfCommand cmd, Elf* parent, ElfKind kind, size_t extra);
3744514f5e3Sopenharmony_ci
3754514f5e3Sopenharmony_ci    ElfKind GetElfKind(void* buf) const;
3764514f5e3Sopenharmony_ci
3774514f5e3Sopenharmony_ci    template <typename FromElfHeader, typename FromElfSectionHeader, typename SizeType>
3784514f5e3Sopenharmony_ci    size_t GetSectionHeaderNum(
3794514f5e3Sopenharmony_ci        FromElfHeader* ehdr, size_t maxsize, unsigned char* eIdent, void* mapAddress, int64_t offset);
3804514f5e3Sopenharmony_ci    size_t GetShnum(void* map_address, unsigned char* e_ident, int64_t offset, size_t maxsize);
3814514f5e3Sopenharmony_ci    /* Create descriptor for ELF file in memory.  */
3824514f5e3Sopenharmony_ci    template <typename ElfEhdr, typename ElfShdr, typename ElfItemField>
3834514f5e3Sopenharmony_ci    Elf* GetElfItem(ElfItemField& elfItemField, void* mapAddress, unsigned char* eIdent, int64_t offset, size_t maxSize,
3844514f5e3Sopenharmony_ci        ElfCommand cmd, size_t scnCnt, Elf* elf);
3854514f5e3Sopenharmony_ci    Elf* FileReadElf(
3864514f5e3Sopenharmony_ci        void* map_address, unsigned char* e_ident, int64_t offset, size_t maxsize, ElfCommand cmd, Elf* parent);
3874514f5e3Sopenharmony_ci    Elf* ReadMmapedFile(void* map_address, int64_t offset, size_t maxsize, ElfCommand cmd, Elf* parent);
3884514f5e3Sopenharmony_ci    Elf* ElfMemory(char* image, size_t size);
3894514f5e3Sopenharmony_ci    int ElfRelease(Elf* elf) const;
3904514f5e3Sopenharmony_ci    char* elfData_;
3914514f5e3Sopenharmony_ci    size_t elfLen_;
3924514f5e3Sopenharmony_ci    int elfErrorCode_ { 0 };
3934514f5e3Sopenharmony_ci    const bool fromMmap_ { false };
3944514f5e3Sopenharmony_ci};
3954514f5e3Sopenharmony_ci} // namespace panda::ecmascript
3964514f5e3Sopenharmony_ci#endif // ECMASCRIPT_COMPILER_AOT_FILE_ELF_CHECKER_H
397