1164190Sjkoshy/*- 2164190Sjkoshy * Copyright (c) 2006 Joseph Koshy 3164190Sjkoshy * All rights reserved. 4164190Sjkoshy * 5164190Sjkoshy * Redistribution and use in source and binary forms, with or without 6164190Sjkoshy * modification, are permitted provided that the following conditions 7164190Sjkoshy * are met: 8164190Sjkoshy * 1. Redistributions of source code must retain the above copyright 9164190Sjkoshy * notice, this list of conditions and the following disclaimer. 10164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright 11164190Sjkoshy * notice, this list of conditions and the following disclaimer in the 12164190Sjkoshy * documentation and/or other materials provided with the distribution. 13164190Sjkoshy * 14164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15164190Sjkoshy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16164190Sjkoshy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17164190Sjkoshy * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18164190Sjkoshy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19164190Sjkoshy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20164190Sjkoshy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21164190Sjkoshy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22164190Sjkoshy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23164190Sjkoshy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24164190Sjkoshy * SUCH DAMAGE. 25164190Sjkoshy * 26164190Sjkoshy * $FreeBSD$ 27164190Sjkoshy */ 28164190Sjkoshy 29164190Sjkoshy#ifndef __LIBELF_H_ 30164190Sjkoshy#define __LIBELF_H_ 31164190Sjkoshy 32164190Sjkoshy#include <sys/queue.h> 33164190Sjkoshy 34164190Sjkoshy#ifndef NULL 35164190Sjkoshy#define NULL ((void *) 0) 36164190Sjkoshy#endif 37164190Sjkoshy 38164190Sjkoshy/* 39164190Sjkoshy * Library-private data structures. 40164190Sjkoshy */ 41164190Sjkoshy 42164190Sjkoshy#define LIBELF_MSG_SIZE 256 43164190Sjkoshy 44164190Sjkoshystruct _libelf_globals { 45164190Sjkoshy int libelf_arch; 46164190Sjkoshy unsigned int libelf_byteorder; 47164190Sjkoshy int libelf_class; 48164190Sjkoshy int libelf_error; 49164190Sjkoshy int libelf_fillchar; 50164190Sjkoshy unsigned int libelf_version; 51164190Sjkoshy char libelf_msg[LIBELF_MSG_SIZE]; 52164190Sjkoshy}; 53164190Sjkoshy 54164190Sjkoshyextern struct _libelf_globals _libelf; 55164190Sjkoshy 56164190Sjkoshy#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) 57164190Sjkoshy 58164190Sjkoshy#define LIBELF_ELF_ERROR_MASK 0xFF 59164190Sjkoshy#define LIBELF_OS_ERROR_SHIFT 8 60164190Sjkoshy 61164190Sjkoshy#define LIBELF_SET_ERROR(E, O) do { \ 62164190Sjkoshy LIBELF_PRIVATE(error) = ((ELF_E_##E & LIBELF_ELF_ERROR_MASK)| \ 63164190Sjkoshy ((O) << LIBELF_OS_ERROR_SHIFT)); \ 64164190Sjkoshy } while (0) 65164190Sjkoshy 66164190Sjkoshy#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) 67164190Sjkoshy 68164190Sjkoshy/* 69164190Sjkoshy * Flags for library internal use. These use the upper 16 bits of a 70164190Sjkoshy * flags field. 71164190Sjkoshy */ 72164190Sjkoshy#define LIBELF_F_MALLOCED 0x010000 /* whether data was malloc'ed */ 73164190Sjkoshy#define LIBELF_F_MMAP 0x020000 /* whether e_rawfile was mmap'ed */ 74165535Sjkoshy#define LIBELF_F_SHDRS_LOADED 0x040000 /* whether all shdrs were read in */ 75164190Sjkoshy 76164190Sjkoshystruct _Elf { 77164190Sjkoshy int e_activations; /* activation count */ 78164190Sjkoshy Elf_Arhdr *e_arhdr; /* header for archive members */ 79164190Sjkoshy unsigned int e_byteorder; /* ELFDATA* */ 80164190Sjkoshy int e_class; /* ELFCLASS* */ 81164190Sjkoshy Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ 82164190Sjkoshy int e_fd; /* associated file descriptor */ 83164190Sjkoshy unsigned int e_flags; /* ELF_F_*, LIBELF_F_* flags */ 84164190Sjkoshy Elf_Kind e_kind; /* ELF_K_* */ 85164190Sjkoshy Elf *e_parent; /* non-NULL for archive members */ 86164190Sjkoshy char *e_rawfile; /* uninterpreted bytes */ 87164190Sjkoshy size_t e_rawsize; /* size of uninterpreted bytes */ 88164190Sjkoshy unsigned int e_version; /* file version */ 89164190Sjkoshy 90164190Sjkoshy union { 91164190Sjkoshy struct { /* ar(1) archives */ 92164190Sjkoshy off_t e_next; /* set by elf_rand()/elf_next() */ 93164190Sjkoshy int e_nchildren; 94164190Sjkoshy char *e_rawstrtab; /* file name strings */ 95164190Sjkoshy size_t e_rawstrtabsz; 96164190Sjkoshy char *e_rawsymtab; /* symbol table */ 97164190Sjkoshy size_t e_rawsymtabsz; 98164190Sjkoshy Elf_Arsym *e_symtab; 99164190Sjkoshy size_t e_symtabsz; 100164190Sjkoshy } e_ar; 101164190Sjkoshy struct { /* regular ELF files */ 102164190Sjkoshy union { 103164190Sjkoshy Elf32_Ehdr *e_ehdr32; 104164190Sjkoshy Elf64_Ehdr *e_ehdr64; 105164190Sjkoshy } e_ehdr; 106164190Sjkoshy union { 107164190Sjkoshy Elf32_Phdr *e_phdr32; 108164190Sjkoshy Elf64_Phdr *e_phdr64; 109164190Sjkoshy } e_phdr; 110164190Sjkoshy STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ 111165535Sjkoshy size_t e_nphdr; /* number of Phdr entries */ 112165535Sjkoshy size_t e_nscn; /* number of sections */ 113165535Sjkoshy size_t e_strndx; /* string table section index */ 114164190Sjkoshy } e_elf; 115164190Sjkoshy } e_u; 116164190Sjkoshy}; 117164190Sjkoshy 118164190Sjkoshystruct _Elf_Scn { 119164190Sjkoshy union { 120164190Sjkoshy Elf32_Shdr s_shdr32; 121164190Sjkoshy Elf64_Shdr s_shdr64; 122164190Sjkoshy } s_shdr; 123164190Sjkoshy STAILQ_HEAD(, _Elf_Data) s_data; /* list of Elf_Data descriptors */ 124164190Sjkoshy STAILQ_HEAD(, _Elf_Data) s_rawdata; /* raw data for this section */ 125164190Sjkoshy STAILQ_ENTRY(_Elf_Scn) s_next; 126164190Sjkoshy struct _Elf *s_elf; /* parent ELF descriptor */ 127164190Sjkoshy unsigned int s_flags; /* flags for the section as a whole */ 128164190Sjkoshy size_t s_ndx; /* index# for this section */ 129164190Sjkoshy uint64_t s_offset; /* managed by elf_update() */ 130164190Sjkoshy uint64_t s_rawoff; /* original offset in the file */ 131164190Sjkoshy uint64_t s_size; /* managed by elf_update() */ 132164190Sjkoshy}; 133164190Sjkoshy 134164190Sjkoshy 135164190Sjkoshyenum { 136164190Sjkoshy ELF_TOFILE, 137164190Sjkoshy ELF_TOMEMORY 138164190Sjkoshy}; 139164190Sjkoshy 140164190Sjkoshy#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ 141164190Sjkoshy if ((SRC)->NAME > UINT_MAX) { \ 142164190Sjkoshy LIBELF_SET_ERROR(RANGE, 0); \ 143164190Sjkoshy return (0); \ 144164190Sjkoshy } \ 145164190Sjkoshy (DST)->NAME = (SRC)->NAME; \ 146164190Sjkoshy } while (0) 147164190Sjkoshy 148164190Sjkoshy#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ 149164190Sjkoshy if ((SRC)->NAME > INT_MAX || \ 150164190Sjkoshy (SRC)->NAME < INT_MIN) { \ 151164190Sjkoshy LIBELF_SET_ERROR(RANGE, 0); \ 152164190Sjkoshy return (0); \ 153164190Sjkoshy } \ 154164190Sjkoshy (DST)->NAME = (SRC)->NAME; \ 155164190Sjkoshy } while (0) 156164190Sjkoshy 157164190Sjkoshy 158164190Sjkoshy/* 159164190Sjkoshy * Prototypes 160164190Sjkoshy */ 161164190Sjkoshy 162164190SjkoshyElf_Data *_libelf_allocate_data(Elf_Scn *_s); 163164190SjkoshyElf *_libelf_allocate_elf(void); 164164190SjkoshyElf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); 165164190SjkoshyElf_Arhdr *_libelf_ar_gethdr(Elf *_e); 166164190SjkoshyElf *_libelf_ar_open(Elf *_e); 167164190SjkoshyElf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); 168210348Skaiwint _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); 169210348Skaiwchar *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname); 170210348Skaiwchar *_libelf_ar_get_name(char *_buf, size_t _sz, Elf *_e); 171210348Skaiwint _libelf_ar_get_number(char *_buf, size_t _sz, int _base, size_t *_ret); 172164190SjkoshyElf_Arsym *_libelf_ar_process_symtab(Elf *_ar, size_t *_dst); 173164190Sjkoshyunsigned long _libelf_checksum(Elf *_e, int _elfclass); 174164190Sjkoshyvoid *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); 175164190Sjkoshyint _libelf_falign(Elf_Type _t, int _elfclass); 176164190Sjkoshysize_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, 177164190Sjkoshy size_t count); 178210338Skaiwint (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) 179210338Skaiw (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); 180164190Sjkoshyvoid *_libelf_getphdr(Elf *_e, int _elfclass); 181164190Sjkoshyvoid *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); 182164190Sjkoshyvoid _libelf_init_elf(Elf *_e, Elf_Kind _kind); 183210330Skaiwint _libelf_load_scn(Elf *e, void *ehdr); 184164190Sjkoshyint _libelf_malign(Elf_Type _t, int _elfclass); 185164190Sjkoshysize_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); 186164190Sjkoshyvoid *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); 187164190SjkoshyElf_Data *_libelf_release_data(Elf_Data *_d); 188164190SjkoshyElf *_libelf_release_elf(Elf *_e); 189164190SjkoshyElf_Scn *_libelf_release_scn(Elf_Scn *_s); 190165535Sjkoshyint _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); 191164190Sjkoshyint _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); 192164190Sjkoshyint _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, 193164190Sjkoshy size_t _shstrndx); 194164190SjkoshyElf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, 195164190Sjkoshy unsigned int _encoding, int _elfclass, int _direction); 196164190Sjkoshyint _libelf_xlate_shtype(uint32_t _sht); 197164190Sjkoshy 198164190Sjkoshy#endif /* __LIBELF_H_ */ 199