1a1b5ec25Sjsg /*- 2a1b5ec25Sjsg * Copyright (c) 2006,2008-2011 Joseph Koshy 3a1b5ec25Sjsg * All rights reserved. 4a1b5ec25Sjsg * 5a1b5ec25Sjsg * Redistribution and use in source and binary forms, with or without 6a1b5ec25Sjsg * modification, are permitted provided that the following conditions 7a1b5ec25Sjsg * are met: 8a1b5ec25Sjsg * 1. Redistributions of source code must retain the above copyright 9a1b5ec25Sjsg * notice, this list of conditions and the following disclaimer. 10a1b5ec25Sjsg * 2. Redistributions in binary form must reproduce the above copyright 11a1b5ec25Sjsg * notice, this list of conditions and the following disclaimer in the 12a1b5ec25Sjsg * documentation and/or other materials provided with the distribution. 13a1b5ec25Sjsg * 14a1b5ec25Sjsg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15a1b5ec25Sjsg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16a1b5ec25Sjsg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17a1b5ec25Sjsg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18a1b5ec25Sjsg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19a1b5ec25Sjsg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20a1b5ec25Sjsg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21a1b5ec25Sjsg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22a1b5ec25Sjsg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23a1b5ec25Sjsg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24a1b5ec25Sjsg * SUCH DAMAGE. 25a1b5ec25Sjsg * 26*63b93652Sjsg * $Id: _libelf.h,v 1.3 2020/05/18 06:46:23 jsg Exp $ 27a1b5ec25Sjsg */ 28a1b5ec25Sjsg 29a1b5ec25Sjsg #ifndef __LIBELF_H_ 30a1b5ec25Sjsg #define __LIBELF_H_ 31a1b5ec25Sjsg 32a1b5ec25Sjsg #include <sys/queue.h> 33a1b5ec25Sjsg 34a1b5ec25Sjsg #include "_libelf_config.h" 35a1b5ec25Sjsg 36a1b5ec25Sjsg #include "_elftc.h" 37a1b5ec25Sjsg 38a1b5ec25Sjsg /* 39a1b5ec25Sjsg * Library-private data structures. 40a1b5ec25Sjsg */ 41a1b5ec25Sjsg 42a1b5ec25Sjsg #define LIBELF_MSG_SIZE 256 43a1b5ec25Sjsg 44a1b5ec25Sjsg struct _libelf_globals { 45a1b5ec25Sjsg int libelf_arch; 46a1b5ec25Sjsg unsigned int libelf_byteorder; 47a1b5ec25Sjsg int libelf_class; 48a1b5ec25Sjsg int libelf_error; 49a1b5ec25Sjsg int libelf_fillchar; 50a1b5ec25Sjsg unsigned int libelf_version; 51a1b5ec25Sjsg unsigned char libelf_msg[LIBELF_MSG_SIZE]; 52a1b5ec25Sjsg }; 53a1b5ec25Sjsg 54a1b5ec25Sjsg extern struct _libelf_globals _libelf; 55a1b5ec25Sjsg 56a1b5ec25Sjsg #define LIBELF_PRIVATE(N) (_libelf.libelf_##N) 57a1b5ec25Sjsg 58a1b5ec25Sjsg #define LIBELF_ELF_ERROR_MASK 0xFF 59a1b5ec25Sjsg #define LIBELF_OS_ERROR_SHIFT 8 60a1b5ec25Sjsg 61a1b5ec25Sjsg #define LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ 62a1b5ec25Sjsg ((O) << LIBELF_OS_ERROR_SHIFT)) 63a1b5ec25Sjsg 64a1b5ec25Sjsg #define LIBELF_SET_ERROR(E, O) do { \ 65a1b5ec25Sjsg LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ 66a1b5ec25Sjsg } while (0) 67a1b5ec25Sjsg 68a1b5ec25Sjsg #define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) 69a1b5ec25Sjsg 70a1b5ec25Sjsg /* 71a1b5ec25Sjsg * Flags for library internal use. These use the upper 16 bits of the 72a1b5ec25Sjsg * `e_flags' field. 73a1b5ec25Sjsg */ 74a1b5ec25Sjsg #define LIBELF_F_API_MASK 0x00FFFFU /* Flags defined by the API. */ 75a1b5ec25Sjsg #define LIBELF_F_AR_HEADER 0x010000U /* translated header available */ 76a1b5ec25Sjsg #define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */ 77a1b5ec25Sjsg #define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ 78a1b5ec25Sjsg #define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ 79a1b5ec25Sjsg #define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ 80a1b5ec25Sjsg #define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ 81a1b5ec25Sjsg #define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ 82a1b5ec25Sjsg 83a1b5ec25Sjsg struct _Elf { 84a1b5ec25Sjsg int e_activations; /* activation count */ 85a1b5ec25Sjsg unsigned int e_byteorder; /* ELFDATA* */ 86a1b5ec25Sjsg int e_class; /* ELFCLASS* */ 87a1b5ec25Sjsg Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ 88a1b5ec25Sjsg int e_fd; /* associated file descriptor */ 89a1b5ec25Sjsg unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ 90a1b5ec25Sjsg Elf_Kind e_kind; /* ELF_K_* */ 91a1b5ec25Sjsg Elf *e_parent; /* non-NULL for archive members */ 92a1b5ec25Sjsg unsigned char *e_rawfile; /* uninterpreted bytes */ 93e219834fSjsg off_t e_rawsize; /* size of uninterpreted bytes */ 94a1b5ec25Sjsg unsigned int e_version; /* file version */ 95a1b5ec25Sjsg 96a1b5ec25Sjsg /* 97a1b5ec25Sjsg * Header information for archive members. See the 98a1b5ec25Sjsg * LIBELF_F_AR_HEADER flag. 99a1b5ec25Sjsg */ 100a1b5ec25Sjsg union { 101a1b5ec25Sjsg Elf_Arhdr *e_arhdr; /* translated header */ 102a1b5ec25Sjsg unsigned char *e_rawhdr; /* untranslated header */ 103a1b5ec25Sjsg } e_hdr; 104a1b5ec25Sjsg 105a1b5ec25Sjsg union { 106a1b5ec25Sjsg struct { /* ar(1) archives */ 107a1b5ec25Sjsg off_t e_next; /* set by elf_rand()/elf_next() */ 108a1b5ec25Sjsg int e_nchildren; 109a1b5ec25Sjsg unsigned char *e_rawstrtab; /* file name strings */ 110a1b5ec25Sjsg size_t e_rawstrtabsz; 111a1b5ec25Sjsg unsigned char *e_rawsymtab; /* symbol table */ 112a1b5ec25Sjsg size_t e_rawsymtabsz; 113a1b5ec25Sjsg Elf_Arsym *e_symtab; 114a1b5ec25Sjsg size_t e_symtabsz; 115a1b5ec25Sjsg } e_ar; 116a1b5ec25Sjsg struct { /* regular ELF files */ 117a1b5ec25Sjsg union { 118a1b5ec25Sjsg Elf32_Ehdr *e_ehdr32; 119a1b5ec25Sjsg Elf64_Ehdr *e_ehdr64; 120a1b5ec25Sjsg } e_ehdr; 121a1b5ec25Sjsg union { 122a1b5ec25Sjsg Elf32_Phdr *e_phdr32; 123a1b5ec25Sjsg Elf64_Phdr *e_phdr64; 124a1b5ec25Sjsg } e_phdr; 125a1b5ec25Sjsg STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ 126a1b5ec25Sjsg size_t e_nphdr; /* number of Phdr entries */ 127a1b5ec25Sjsg size_t e_nscn; /* number of sections */ 128a1b5ec25Sjsg size_t e_strndx; /* string table section index */ 129a1b5ec25Sjsg } e_elf; 130a1b5ec25Sjsg } e_u; 131a1b5ec25Sjsg }; 132a1b5ec25Sjsg 133a1b5ec25Sjsg /* 134a1b5ec25Sjsg * The internal descriptor wrapping the "Elf_Data" type. 135a1b5ec25Sjsg */ 136a1b5ec25Sjsg struct _Libelf_Data { 137a1b5ec25Sjsg Elf_Data d_data; /* The exported descriptor. */ 138a1b5ec25Sjsg Elf_Scn *d_scn; /* The containing section */ 139a1b5ec25Sjsg unsigned int d_flags; 140a1b5ec25Sjsg STAILQ_ENTRY(_Libelf_Data) d_next; 141a1b5ec25Sjsg }; 142a1b5ec25Sjsg 143a1b5ec25Sjsg struct _Elf_Scn { 144a1b5ec25Sjsg union { 145a1b5ec25Sjsg Elf32_Shdr s_shdr32; 146a1b5ec25Sjsg Elf64_Shdr s_shdr64; 147a1b5ec25Sjsg } s_shdr; 148a1b5ec25Sjsg STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ 149a1b5ec25Sjsg STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ 150a1b5ec25Sjsg STAILQ_ENTRY(_Elf_Scn) s_next; 151a1b5ec25Sjsg struct _Elf *s_elf; /* parent ELF descriptor */ 152a1b5ec25Sjsg unsigned int s_flags; /* flags for the section as a whole */ 153a1b5ec25Sjsg size_t s_ndx; /* index# for this section */ 154a1b5ec25Sjsg uint64_t s_offset; /* managed by elf_update() */ 155a1b5ec25Sjsg uint64_t s_rawoff; /* original offset in the file */ 156a1b5ec25Sjsg uint64_t s_size; /* managed by elf_update() */ 157a1b5ec25Sjsg }; 158a1b5ec25Sjsg 159a1b5ec25Sjsg 160a1b5ec25Sjsg enum { 161a1b5ec25Sjsg ELF_TOFILE, 162a1b5ec25Sjsg ELF_TOMEMORY 163a1b5ec25Sjsg }; 164a1b5ec25Sjsg 165a1b5ec25Sjsg 166a1b5ec25Sjsg /* 167a1b5ec25Sjsg * The LIBELF_COPY macros are used to copy fields from a GElf_* 168a1b5ec25Sjsg * structure to their 32-bit counterparts, while checking for out of 169a1b5ec25Sjsg * range values. 170a1b5ec25Sjsg * 171a1b5ec25Sjsg * - LIBELF_COPY_U32 :: copy an unsigned 32 bit field. 172a1b5ec25Sjsg * - LIBELF_COPY_S32 :: copy a signed 32 bit field. 173a1b5ec25Sjsg */ 174a1b5ec25Sjsg 175a1b5ec25Sjsg #define LIBELF_COPY_U32(DST, SRC, NAME) do { \ 176a1b5ec25Sjsg if ((SRC)->NAME > UINT32_MAX) { \ 177a1b5ec25Sjsg LIBELF_SET_ERROR(RANGE, 0); \ 178a1b5ec25Sjsg return (0); \ 179a1b5ec25Sjsg } \ 180a1b5ec25Sjsg (DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \ 181a1b5ec25Sjsg } while (0) 182a1b5ec25Sjsg 183a1b5ec25Sjsg #define LIBELF_COPY_S32(DST, SRC, NAME) do { \ 184a1b5ec25Sjsg if ((SRC)->NAME > INT32_MAX || \ 185a1b5ec25Sjsg (SRC)->NAME < INT32_MIN) { \ 186a1b5ec25Sjsg LIBELF_SET_ERROR(RANGE, 0); \ 187a1b5ec25Sjsg return (0); \ 188a1b5ec25Sjsg } \ 189a1b5ec25Sjsg (DST)->NAME = (int32_t) (SRC)->NAME; \ 190a1b5ec25Sjsg } while (0) 191a1b5ec25Sjsg 192a1b5ec25Sjsg 193a1b5ec25Sjsg /* 194a1b5ec25Sjsg * Function Prototypes. 195a1b5ec25Sjsg */ 196a1b5ec25Sjsg 197a1b5ec25Sjsg typedef int _libelf_translator_function(unsigned char *_dst, size_t dsz, 198a1b5ec25Sjsg unsigned char *_src, size_t _cnt, int _byteswap); 199a1b5ec25Sjsg 200a1b5ec25Sjsg #ifdef __cplusplus 201a1b5ec25Sjsg extern "C" { 202a1b5ec25Sjsg #endif 203a1b5ec25Sjsg struct _Libelf_Data *_libelf_allocate_data(Elf_Scn *_s); 204a1b5ec25Sjsg Elf *_libelf_allocate_elf(void); 205a1b5ec25Sjsg Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); 206a1b5ec25Sjsg Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); 207a1b5ec25Sjsg Elf *_libelf_ar_open(Elf *_e, int _reporterror); 208a1b5ec25Sjsg Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); 209a1b5ec25Sjsg Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); 210a1b5ec25Sjsg Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); 211a1b5ec25Sjsg long _libelf_checksum(Elf *_e, int _elfclass); 212a1b5ec25Sjsg void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); 213a1b5ec25Sjsg int _libelf_elfmachine(Elf *_e); 214a1b5ec25Sjsg unsigned int _libelf_falign(Elf_Type _t, int _elfclass); 215a1b5ec25Sjsg size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, 216a1b5ec25Sjsg size_t count); 217a1b5ec25Sjsg _libelf_translator_function *_libelf_get_translator(Elf_Type _t, 218a1b5ec25Sjsg int _direction, int _elfclass, int _elfmachine); 219a1b5ec25Sjsg void *_libelf_getphdr(Elf *_e, int _elfclass); 220a1b5ec25Sjsg void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); 221a1b5ec25Sjsg void _libelf_init_elf(Elf *_e, Elf_Kind _kind); 222a1b5ec25Sjsg int _libelf_load_section_headers(Elf *e, void *ehdr); 223a1b5ec25Sjsg unsigned int _libelf_malign(Elf_Type _t, int _elfclass); 224a1b5ec25Sjsg Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror); 225a1b5ec25Sjsg size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); 226a1b5ec25Sjsg void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); 227a1b5ec25Sjsg Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); 228a1b5ec25Sjsg struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); 229*63b93652Sjsg void _libelf_release_elf(Elf *_e); 230a1b5ec25Sjsg Elf_Scn *_libelf_release_scn(Elf_Scn *_s); 231a1b5ec25Sjsg int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); 232a1b5ec25Sjsg int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); 233a1b5ec25Sjsg int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, 234a1b5ec25Sjsg size_t _shstrndx); 235a1b5ec25Sjsg Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, 236a1b5ec25Sjsg unsigned int _encoding, int _elfclass, int _elfmachine, int _direction); 237a1b5ec25Sjsg int _libelf_xlate_shtype(uint32_t _sht); 238a1b5ec25Sjsg #ifdef __cplusplus 239a1b5ec25Sjsg } 240a1b5ec25Sjsg #endif 241a1b5ec25Sjsg 242a1b5ec25Sjsg #endif /* __LIBELF_H_ */ 243