/* Copyright (c) 2013-2019, David Anderson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef READELFOBJ_H #define READELFOBJ_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Use this for .rel. too. */ struct generic_rela { Dwarf_Unsigned gr_offset; Dwarf_Unsigned gr_info; Dwarf_Unsigned gr_sym; /* From info */ Dwarf_Unsigned gr_type; /* From info */ Dwarf_Signed gr_addend; unsigned char gr_type2; /*MIPS64*/ unsigned char gr_type3; /*MIPS64*/ /* The following TRUE if .rela. and FALSE if .rel. if FALSE, gr_addend will be zero. */ int gr_is_rela; }; /* The following are generic to simplify handling Elf32 and Elf64. Some fields added where the two sizes have different extraction code. */ struct generic_ehdr { unsigned char ge_ident[EI_NIDENT]; Dwarf_Unsigned ge_type; Dwarf_Unsigned ge_machine; Dwarf_Unsigned ge_version; Dwarf_Unsigned ge_entry; Dwarf_Unsigned ge_phoff; Dwarf_Unsigned ge_shoff; Dwarf_Unsigned ge_flags; Dwarf_Unsigned ge_ehsize; Dwarf_Unsigned ge_phentsize; Dwarf_Unsigned ge_phnum; Dwarf_Unsigned ge_shentsize; Dwarf_Unsigned ge_shnum; Dwarf_Unsigned ge_shstrndx; }; struct generic_phdr { Dwarf_Unsigned gp_type; Dwarf_Unsigned gp_flags; Dwarf_Unsigned gp_offset; Dwarf_Unsigned gp_vaddr; Dwarf_Unsigned gp_paddr; Dwarf_Unsigned gp_filesz; Dwarf_Unsigned gp_memsz; Dwarf_Unsigned gp_align; }; struct generic_shdr { Dwarf_Unsigned gh_secnum; Dwarf_Unsigned gh_name; const char * gh_namestring; Dwarf_Unsigned gh_type; Dwarf_Unsigned gh_flags; Dwarf_Unsigned gh_addr; Dwarf_Unsigned gh_offset; Dwarf_Unsigned gh_size; Dwarf_Unsigned gh_link; /* Section index (in an SHT_REL or SHT_RELA section) of the target section from gh_link. Otherwise 0. */ Dwarf_Unsigned gh_reloc_target_secnum; Dwarf_Unsigned gh_info; Dwarf_Unsigned gh_addralign; Dwarf_Unsigned gh_entsize; /* Zero unless content read in. Malloc space of size gh_size, in bytes. For dwarf and strings mainly. free() this if not null*/ char * gh_content; /* If a .rel or .rela section this will point to generic relocation records if such have been loaded. free() this if not null. */ Dwarf_Unsigned gh_relcount; struct generic_rela * gh_rels; /* For SHT_GROUP based grouping, which group is this section in. 0 unknown, 1 DW_GROUP_NUMBER_BASE base DWARF, 2 DW_GROUPNUMBER_DWO dwo sections, 3+ are in an SHT_GROUP. GNU uses this. set with group number (3+) from SHT_GROUP and the flags should have SHF_GROUP set if in SHT_GROUP. Must only be in one group? */ Dwarf_Unsigned gh_section_group_number; /* Content of an SHT_GROUP section as an array of integers. [0] is the version, which can only be one(1) . */ Dwarf_Unsigned * gh_sht_group_array; /* Number of elements in the gh_sht_group_array. */ Dwarf_Unsigned gh_sht_group_array_count; /* TRUE if .debug_info .eh_frame etc. */ char gh_is_dwarf; }; struct generic_dynentry { Dwarf_Unsigned gd_tag; /* gd_val stands in for d_ptr and d_val union, the union adds nothing in practice since we expect ptrsize <= ulongest. */ Dwarf_Unsigned gd_val; Dwarf_Unsigned gd_dyn_file_offset; }; struct generic_symentry { Dwarf_Unsigned gs_name; Dwarf_Unsigned gs_value; Dwarf_Unsigned gs_size; Dwarf_Unsigned gs_info; Dwarf_Unsigned gs_other; Dwarf_Unsigned gs_shndx; /* derived */ Dwarf_Unsigned gs_bind; Dwarf_Unsigned gs_type; }; struct location { const char *g_name; Dwarf_Unsigned g_offset; Dwarf_Unsigned g_count; Dwarf_Unsigned g_entrysize; Dwarf_Unsigned g_totalsize; }; typedef struct elf_filedata_s { /* f_ident[0] == 'E' means it is elf and elf_filedata_s is the struct involved. Other means error/corruption of some kind. f_ident[1] is a version number. Only version 1 is defined. */ char f_ident[8]; char * f_path; /* non-null if known. Must be freed */ int f_fd; int f_machine; /* EM_* */ int f_destruct_close_fd; int f_is_64bit; unsigned f_endian; Dwarf_Unsigned f_filesize; /* Elf size, not DWARF. 32 or 64 */ Dwarf_Small f_offsetsize; Dwarf_Small f_pointersize; int f_ftype; Dwarf_Unsigned f_max_secdata_offset; Dwarf_Unsigned f_max_progdata_offset; void (*f_copy_word) (void *, const void *, unsigned long); struct location f_loc_ehdr; struct generic_ehdr* f_ehdr; struct location f_loc_shdr; struct generic_shdr* f_shdr; struct location f_loc_phdr; struct generic_phdr* f_phdr; char *f_elf_shstrings_data; /* section name strings */ /* length of currentsection. Might be zero..*/ Dwarf_Unsigned f_elf_shstrings_length; /* size of malloc-d space */ Dwarf_Unsigned f_elf_shstrings_max; /* This is the .dynamic section */ struct location f_loc_dynamic; struct generic_dynentry * f_dynamic; Dwarf_Unsigned f_dynamic_sect_index; /* .dynsym, .dynstr */ struct location f_loc_dynsym; struct generic_symentry* f_dynsym; char *f_dynsym_sect_strings; Dwarf_Unsigned f_dynsym_sect_strings_max; Dwarf_Unsigned f_dynsym_sect_strings_sect_index; Dwarf_Unsigned f_dynsym_sect_index; /* .symtab .strtab */ struct location f_loc_symtab; struct generic_symentry* f_symtab; char * f_symtab_sect_strings; Dwarf_Unsigned f_symtab_sect_strings_max; Dwarf_Unsigned f_symtab_sect_strings_sect_index; Dwarf_Unsigned f_symtab_sect_index; /* Starts at 3. 0,1,2 used specially. */ Dwarf_Unsigned f_sg_next_group_number; /* Both the following will be zero unless there are explicit Elf groups. */ Dwarf_Unsigned f_sht_group_type_section_count; Dwarf_Unsigned f_shf_group_flag_section_count; Dwarf_Unsigned f_dwo_group_section_count; } dwarf_elf_object_access_internals_t; int dwarf_construct_elf_access(int fd, const char *path, dwarf_elf_object_access_internals_t **ep,int *errcode); int dwarf_destruct_elf_access(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_header(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_sectheaders(dwarf_elf_object_access_internals_t* ep,int *errcode); int _dwarf_load_elf_symtab_symbols(dwarf_elf_object_access_internals_t *ep,int *errcode); int _dwarf_load_elf_symstr( dwarf_elf_object_access_internals_t *ep, int *errcode); /* These two enums used for type safety in passing values. */ enum RelocRela { RelocIsRela = 1, RelocIsRel = 2 }; enum RelocOffsetSize { RelocOffset32 = 4, RelocOffset64 = 8 }; int _dwarf_load_elf_relx(dwarf_elf_object_access_internals_t *ep, Dwarf_Unsigned secnum,enum RelocRela,int *errcode); #ifndef EI_NIDENT #define EI_NIDENT 16 #endif /* EI_NIDENT */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* READELFOBJ_H */