195043Ssuz/*- 266776Skris * Copyright (c) 2006 Joseph Koshy 355163Sshin * All rights reserved. 455163Sshin * 555163Sshin * Redistribution and use in source and binary forms, with or without 662632Skris * modification, are permitted provided that the following conditions 755163Sshin * are met: 855163Sshin * 1. Redistributions of source code must retain the above copyright 955163Sshin * notice, this list of conditions and the following disclaimer. 1055163Sshin * 2. Redistributions in binary form must reproduce the above copyright 1155163Sshin * notice, this list of conditions and the following disclaimer in the 1255163Sshin * documentation and/or other materials provided with the distribution. 1355163Sshin * 1455163Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1555163Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1655163Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1755163Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1862632Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1955163Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2055163Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2155163Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2255163Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2355163Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2455163Sshin * SUCH DAMAGE. 2555163Sshin * 2655163Sshin * $FreeBSD$ 2755163Sshin */ 2855163Sshin 2955163Sshin#ifndef __LIBELF_H_ 3055163Sshin#define __LIBELF_H_ 3155163Sshin 3255163Sshin#include <sys/queue.h> 3355163Sshin 3455163Sshin#ifndef NULL 3555163Sshin#define NULL ((void *) 0) 3655163Sshin#endif 3755163Sshin 38118661Sume/* 3966776Skris * Library-private data structures. 40118661Sume */ 41118661Sume 4255163Sshin#define LIBELF_MSG_SIZE 256 4355163Sshin 4455163Sshinstruct _libelf_globals { 4555163Sshin int libelf_arch; 4655163Sshin unsigned int libelf_byteorder; 4755163Sshin int libelf_class; 4855163Sshin int libelf_error; 4955163Sshin int libelf_fillchar; 5055163Sshin unsigned int libelf_version; 5155163Sshin char libelf_msg[LIBELF_MSG_SIZE]; 5255163Sshin}; 5355163Sshin 5455163Sshinextern struct _libelf_globals _libelf; 5555163Sshin 5655163Sshin#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) 5755163Sshin 5855163Sshin#define LIBELF_ELF_ERROR_MASK 0xFF 5955163Sshin#define LIBELF_OS_ERROR_SHIFT 8 6055163Sshin 6155163Sshin#define LIBELF_SET_ERROR(E, O) do { \ 6255163Sshin LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \ 6355163Sshin ((O) << LIBELF_OS_ERROR_SHIFT)); \ 6462632Skris } while (0) 6555163Sshin 6655163Sshin#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) 6755163Sshin 6855163Sshin/* 6955163Sshin * Flags for library internal use. These use the upper 16 bits of a 7055163Sshin * flags field. 7155163Sshin */ 7262632Skris#define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ 7355163Sshin#define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ 74118664Sume#define LIBELF_F_SHDRS_LOADED 0x040000 /* whether all shdrs were read in */ 75118664Sume 7655163Sshinstruct _Elf { 77118661Sume int e_activations; /* activation count */ 78118661Sume Elf_Arhdr *e_arhdr; /* header for archive members */ 79118661Sume unsigned int e_byteorder; /* ELFDATA* */ 8055163Sshin int e_class; /* ELFCLASS* */ 8155163Sshin Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ 8255163Sshin int e_fd; /* associated file descriptor */ 8355163Sshin unsigned int e_flags; /* ELF_F_*, LIBELF_F_* flags */ 8455163Sshin Elf_Kind e_kind; /* ELF_K_* */ 8555163Sshin Elf *e_parent; /* non-NULL for archive members */ 8662632Skris char *e_rawfile; /* uninterpreted bytes */ 8762632Skris size_t e_rawsize; /* size of uninterpreted bytes */ 8855163Sshin unsigned int e_version; /* file version */ 8962632Skris 90118664Sume union { 9162632Skris struct { /* ar(1) archives */ 92118660Sume off_t e_next; /* set by elf_rand()/elf_next() */ 93118664Sume int e_nchildren; 9462632Skris char *e_rawstrtab; /* file name strings */ 9562632Skris size_t e_rawstrtabsz; 96118664Sume char *e_rawsymtab; /* symbol table */ 97118660Sume size_t e_rawsymtabsz; 98118664Sume Elf_Arsym *e_symtab; 9962632Skris size_t e_symtabsz; 10062632Skris } e_ar; 10155163Sshin struct { /* regular ELF files */ 10295043Ssuz union { 10395043Ssuz Elf32_Ehdr *e_ehdr32; 10455163Sshin Elf64_Ehdr *e_ehdr64; 105118664Sume } e_ehdr; 106118660Sume union { 107118664Sume Elf32_Phdr *e_phdr32; 10855163Sshin Elf64_Phdr *e_phdr64; 10955163Sshin } e_phdr; 11055163Sshin STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ 11155163Sshin size_t e_nphdr; /* number of Phdr entries */ 112118660Sume size_t e_nscn; /* number of sections */ 11355163Sshin size_t e_strndx; /* string table section index */ 11455163Sshin } e_elf; 11555163Sshin } e_u; 11655163Sshin}; 11755163Sshin 11862632Skrisstruct _Elf_Scn { 11962632Skris union { 120118664Sume Elf32_Shdr s_shdr32; 121118660Sume Elf64_Shdr s_shdr64; 122118664Sume } s_shdr; 12362632Skris STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ 12462632Skris STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ 12562632Skris STAILQ_ENTRY(_Elf_Scn) s_next; 12655163Sshin struct _Elf *s_elf; /* parent ELF descriptor */ 127118664Sume unsigned int s_flags; /* flags for the section as a whole */ 128118660Sume size_t s_ndx; /* index# for this section */ 129118664Sume uint64_t s_offset; /* managed by elf_update() */ 13055163Sshin uint64_t s_rawoff; /* original offset in the file */ 13155163Sshin uint64_t s_size; /* managed by elf_update() */ 132118664Sume}; 13355163Sshin 13455163Sshin 13555163Sshinenum { 13662632Skris ELF_TOFILE, 13762632Skris ELF_TOMEMORY 138118664Sume}; 139118660Sume 140118664Sume#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ 14162632Skris if ((SRC)->NAME > UINT_MAX) { \ 14262632Skris LIBELF_SET_ERROR(RANGE, 0); \ 14362632Skris return (0); \ 14455163Sshin } \ 145118664Sume (DST)->NAME = (SRC)->NAME; \ 146118660Sume } while (0) 147118664Sume 14855163Sshin#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ 14955163Sshin if ((SRC)->NAME > INT_MAX || \ 150118664Sume (SRC)->NAME < INT_MIN) { \ 15155163Sshin LIBELF_SET_ERROR(RANGE, 0); \ 15255163Sshin return (0); \ 15355163Sshin } \ 15455163Sshin (DST)->NAME = (SRC)->NAME; \ 15555163Sshin } while (0) 156118664Sume 157118660Sume 158118664Sume/* 15955163Sshin * Prototypes 16055163Sshin */ 16155163Sshin 16255163SshinElf_Data *_libelf_allocate_data(Elf_Scn *_s); 16355163SshinElf *_libelf_allocate_elf(void); 16455163SshinElf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); 16555163SshinElf_Arhdr *_libelf_ar_gethdr(Elf *_e); 16655163SshinElf *_libelf_ar_open(Elf *_e); 16755163SshinElf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); 16855163Sshinint _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); 16955163Sshinchar *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname); 17062632Skrischar *_libelf_ar_get_name(char *_buf, size_t _sz, Elf *_e); 17155163Sshinint _libelf_ar_get_number(char *_buf, size_t _sz, int _base, size_t *_ret); 17255163SshinElf_Arsym *_libelf_ar_process_symtab(Elf *_ar, size_t *_dst); 17355163Sshinunsigned long _libelf_checksum(Elf *_e, int _elfclass); 17455163Sshinvoid *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); 17555163Sshinint _libelf_falign(Elf_Type _t, int _elfclass); 17655163Sshinsize_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, 17762632Skris size_t count); 17855163Sshinint (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) 17955163Sshin (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); 18055163Sshinvoid *_libelf_getphdr(Elf *_e, int _elfclass); 18155163Sshinvoid *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); 18255163Sshinvoid _libelf_init_elf(Elf *_e, Elf_Kind _kind); 18355163Sshinint _libelf_load_scn(Elf *e, void *ehdr); 18455163Sshinint _libelf_malign(Elf_Type _t, int _elfclass); 185118664Sumesize_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); 186118664Sumevoid *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); 187118664SumeElf_Data *_libelf_release_data(Elf_Data *_d); 18855163SshinElf *_libelf_release_elf(Elf *_e); 18955163SshinElf_Scn *_libelf_release_scn(Elf_Scn *_s); 19055163Sshinint _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); 19155163Sshinint _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); 19255163Sshinint _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, 19355163Sshin size_t _shstrndx); 19455163SshinElf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, 19555163Sshin unsigned int _encoding, int _elfclass, int _direction); 19655163Sshinint _libelf_xlate_shtype(uint32_t _sht); 19755163Sshin 19855163Sshin#endif /* __LIBELF_H_ */ 19955163Sshin