diff options
author | kaiw <kaiw@FreeBSD.org> | 2014-01-15 22:30:48 +0000 |
---|---|---|
committer | kaiw <kaiw@FreeBSD.org> | 2014-01-15 22:30:48 +0000 |
commit | 7f3a50b3b9f8ecdf4619d21ed128f0277902f34f (patch) | |
tree | 6978b22c644e091330dae1776a1d946f0f32ad6b /contrib/elftoolchain | |
parent | 4d43158298b79cad374fafa6dbd365bb93c82ea7 (diff) | |
parent | 9ee78763690833f42af4a97b77baf30edbca5314 (diff) | |
download | FreeBSD-src-7f3a50b3b9f8ecdf4619d21ed128f0277902f34f.zip FreeBSD-src-7f3a50b3b9f8ecdf4619d21ed128f0277902f34f.tar.gz |
Copy libelf, libdwarf and common files from vendor/ to contrib/.
Diffstat (limited to 'contrib/elftoolchain')
315 files changed, 56173 insertions, 0 deletions
diff --git a/contrib/elftoolchain/common/Makefile b/contrib/elftoolchain/common/Makefile new file mode 100644 index 0000000..d3df246 --- /dev/null +++ b/contrib/elftoolchain/common/Makefile @@ -0,0 +1,15 @@ +# $Id: Makefile 2606 2012-10-02 17:52:57Z jkoshy $ + +TOP= .. + +INCS= elfdefinitions.h +INCSDIR= /usr/include + +.PHONY: all clean clobber depend obj + +all depend obj: + +clean clobber: + rm -f ${CLEANFILES} + +.include "${TOP}/mk/elftoolchain.inc.mk" diff --git a/contrib/elftoolchain/common/_elftc.h b/contrib/elftoolchain/common/_elftc.h new file mode 100644 index 0000000..0b8c77c --- /dev/null +++ b/contrib/elftoolchain/common/_elftc.h @@ -0,0 +1,458 @@ +/*- + * Copyright (c) 2009 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: _elftc.h 2922 2013-03-17 22:53:15Z kaiwang27 $ + */ + +/** + ** Miscellanous definitions needed by multiple components. + **/ + +#ifndef _ELFTC_H +#define _ELFTC_H + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +#ifndef offsetof +#define offsetof(T, M) ((int) &((T*) 0) -> M) +#endif + +/* --QUEUE-MACROS-- [[ */ + +/* + * Supply macros missing from <sys/queue.h> + */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 SLIST_FOREACH_SAFE +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef STAILQ_CONCAT +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_EMPTY +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) +#endif + +#ifndef STAILQ_ENTRY +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} +#endif + +#ifndef STAILQ_FIRST +#define STAILQ_FIRST(head) ((head)->stqh_first) +#endif + +#ifndef STAILQ_HEAD +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first; /* first element */ \ + struct type **stqh_last; /* addr of last next element */ \ +} +#endif + +#ifndef STAILQ_HEAD_INITIALIZER +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } +#endif + +#ifndef STAILQ_FOREACH +#define STAILQ_FOREACH(var, head, field) \ + for ((var) = ((head)->stqh_first); \ + (var); \ + (var) = ((var)->field.stqe_next)) +#endif + +#ifndef STAILQ_FOREACH_SAFE +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +#ifndef STAILQ_INIT +#define STAILQ_INIT(head) do { \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_HEAD +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_TAIL +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_INSERT_AFTER +#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (listelm)->field.stqe_next = (elm); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_LAST +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? \ + NULL : ((struct type *)(void *) \ + ((char *)((head)->stqh_last) - offsetof(struct type, field)))) +#endif + +#ifndef STAILQ_NEXT +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) +#endif + +#ifndef STAILQ_REMOVE +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } else { \ + struct type *curelm = (head)->stqh_first; \ + while (curelm->field.stqe_next != (elm)) \ + curelm = curelm->field.stqe_next; \ + if ((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ + } \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef STAILQ_REMOVE_HEAD +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \ + NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (/*CONSTCOND*/0) +#endif + +/* + * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n)) + * mergesort algorithm. + */ +#ifndef STAILQ_SORT +#define STAILQ_SORT(head, type, field, cmp) do { \ + STAILQ_HEAD(, type) _la, _lb; \ + struct type *_p, *_q, *_e; \ + int _i, _sz, _nmerges, _psz, _qsz; \ + \ + _sz = 1; \ + do { \ + _nmerges = 0; \ + STAILQ_INIT(&_lb); \ + while (!STAILQ_EMPTY((head))) { \ + _nmerges++; \ + STAILQ_INIT(&_la); \ + _psz = 0; \ + for (_i = 0; _i < _sz && !STAILQ_EMPTY((head)); \ + _i++) { \ + _e = STAILQ_FIRST((head)); \ + if (_e == NULL) \ + break; \ + _psz++; \ + STAILQ_REMOVE_HEAD((head), field); \ + STAILQ_INSERT_TAIL(&_la, _e, field); \ + } \ + _p = STAILQ_FIRST(&_la); \ + _qsz = _sz; \ + _q = STAILQ_FIRST((head)); \ + while (_psz > 0 || (_qsz > 0 && _q != NULL)) { \ + if (_psz == 0) { \ + _e = _q; \ + _q = STAILQ_NEXT(_q, field); \ + STAILQ_REMOVE_HEAD((head), \ + field); \ + _qsz--; \ + } else if (_qsz == 0 || _q == NULL) { \ + _e = _p; \ + _p = STAILQ_NEXT(_p, field); \ + STAILQ_REMOVE_HEAD(&_la, field);\ + _psz--; \ + } else if (cmp(_p, _q) <= 0) { \ + _e = _p; \ + _p = STAILQ_NEXT(_p, field); \ + STAILQ_REMOVE_HEAD(&_la, field);\ + _psz--; \ + } else { \ + _e = _q; \ + _q = STAILQ_NEXT(_q, field); \ + STAILQ_REMOVE_HEAD((head), \ + field); \ + _qsz--; \ + } \ + STAILQ_INSERT_TAIL(&_lb, _e, field); \ + } \ + } \ + (head)->stqh_first = _lb.stqh_first; \ + (head)->stqh_last = _lb.stqh_last; \ + _sz *= 2; \ + } while (_nmerges > 1); \ +} while (/*CONSTCOND*/0) +#endif + +#ifndef TAILQ_FOREACH_SAFE +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) +#endif + +/* ]] --QUEUE-MACROS-- */ + +/* + * VCS Ids. + */ + +#ifndef ELFTC_VCSID + +#if defined(__DragonFly__) +#define ELFTC_VCSID(ID) __RCSID(ID) +#endif + +#if defined(__FreeBSD__) +#define ELFTC_VCSID(ID) __FBSDID(ID) +#endif + +#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) +#if defined(__GNUC__) +#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") +#else +#define ELFTC_VCSID(ID) /**/ +#endif +#endif + +#if defined(__minix) +#if defined(__GNUC__) +#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") +#else +#define ELFTC_VCSID(ID) /**/ +#endif /* __GNU__ */ +#endif + +#if defined(__NetBSD__) +#define ELFTC_VCSID(ID) __RCSID(ID) +#endif + +#if defined(__OpenBSD__) +#if defined(__GNUC__) +#define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") +#else +#define ELFTC_VCSID(ID) /**/ +#endif /* __GNUC__ */ +#endif + +#endif /* ELFTC_VCSID */ + +/* + * Provide an equivalent for getprogname(3). + */ + +#ifndef ELFTC_GETPROGNAME + +#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__minix) || \ + defined(__NetBSD__) + +#include <stdlib.h> + +#define ELFTC_GETPROGNAME() getprogname() + +#endif /* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */ + + +#if defined(__GLIBC__) + +/* + * GLIBC based systems have a global 'char *' pointer referencing + * the executable's name. + */ +extern const char *program_invocation_short_name; + +#define ELFTC_GETPROGNAME() program_invocation_short_name + +#endif /* __GLIBC__ */ + + +#if defined(__OpenBSD__) + +extern const char *__progname; + +#define ELFTC_GETPROGNAME() __progname + +#endif /* __OpenBSD__ */ + +#endif /* ELFTC_GETPROGNAME */ + + +/** + ** Per-OS configuration. + **/ + +#if defined(__DragonFly__) + +#include <osreldate.h> +#include <sys/endian.h> + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 + +#endif + +#if defined(__GLIBC__) + +#include <endian.h> + +#define ELFTC_BYTE_ORDER __BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN __BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 + +/* + * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3). + */ +#define ELFTC_HAVE_STRMODE 0 + +/* Whether we need to supply {be,le}32dec. */ +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 + +#define roundup2 roundup + +#endif /* __GLIBC__ */ + + +#if defined(__FreeBSD__) + +#include <osreldate.h> +#include <sys/endian.h> + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 +#if __FreeBSD_version <= 900000 +#define ELFTC_BROKEN_YY_NO_INPUT 1 +#endif +#endif /* __FreeBSD__ */ + + +#if defined(__minix) +#define ELFTC_HAVE_MMAP 0 +#endif /* __minix */ + + +#if defined(__NetBSD__) + +#include <sys/param.h> +#include <sys/endian.h> + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 +#if __NetBSD_Version__ <= 599002100 +/* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */ +/* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */ +# define ELFTC_BROKEN_YY_NO_INPUT 1 +#endif +#endif /* __NetBSD __ */ + + +#if defined(__OpenBSD__) + +#include <sys/param.h> +#include <sys/endian.h> + +#define ELFTC_BYTE_ORDER _BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN + +#define ELFTC_HAVE_MMAP 1 +#define ELFTC_HAVE_STRMODE 1 + +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 +#define roundup2 roundup + +#endif /* __OpenBSD__ */ + +#endif /* _ELFTC_H */ diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h new file mode 100644 index 0000000..7bed9a1 --- /dev/null +++ b/contrib/elftoolchain/common/elfdefinitions.h @@ -0,0 +1,2614 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: elfdefinitions.h 2950 2013-06-15 13:36:02Z jkoshy $ + */ + +/* + * These definitions are based on: + * - The public specification of the ELF format as defined in the + * October 2009 draft of System V ABI. + * See: http://www.sco.com/developers/gabi/latest/ch4.intro.html + * - The May 1998 (version 1.5) draft of "The ELF-64 object format". + * - Processor-specific ELF ABI definitions for sparc, i386, amd64, mips, + * ia64, and powerpc processors. + * - The "Linkers and Libraries Guide", from Sun Microsystems. + */ + +#ifndef _ELFDEFINITIONS_H_ +#define _ELFDEFINITIONS_H_ + +#include <stdint.h> + +/* + * Types of capabilities. + */ + +#define _ELF_DEFINE_CAPABILITIES() \ +_ELF_DEFINE_CA(CA_SUNW_NULL, 0, "ignored") \ +_ELF_DEFINE_CA(CA_SUNW_HW_1, 1, "hardware capability") \ +_ELF_DEFINE_CA(CA_SUNW_SW_1, 2, "software capability") + +#undef _ELF_DEFINE_CA +#define _ELF_DEFINE_CA(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_CAPABILITIES() + CA__LAST__ +}; + +/* + * Flags used with dynamic linking entries. + */ + +#define _ELF_DEFINE_DYN_FLAGS() \ +_ELF_DEFINE_DF(DF_ORIGIN, 0x1, \ + "object being loaded may refer to $ORIGIN") \ +_ELF_DEFINE_DF(DF_SYMBOLIC, 0x2, \ + "search library for references before executable") \ +_ELF_DEFINE_DF(DF_TEXTREL, 0x4, \ + "relocation entries may modify text segment") \ +_ELF_DEFINE_DF(DF_BIND_NOW, 0x8, \ + "process relocation entries at load time") \ +_ELF_DEFINE_DF(DF_STATIC_TLS, 0x10, \ + "uses static thread-local storage") +#undef _ELF_DEFINE_DF +#define _ELF_DEFINE_DF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_DYN_FLAGS() + DF__LAST__ +}; + + +/* + * Dynamic linking entry types. + */ + +#define _ELF_DEFINE_DYN_TYPES() \ +_ELF_DEFINE_DT(DT_NULL, 0, "end of array") \ +_ELF_DEFINE_DT(DT_NEEDED, 1, "names a needed library") \ +_ELF_DEFINE_DT(DT_PLTRELSZ, 2, \ + "size in bytes of associated relocation entries") \ +_ELF_DEFINE_DT(DT_PLTGOT, 3, \ + "address associated with the procedure linkage table") \ +_ELF_DEFINE_DT(DT_HASH, 4, \ + "address of the symbol hash table") \ +_ELF_DEFINE_DT(DT_STRTAB, 5, \ + "address of the string table") \ +_ELF_DEFINE_DT(DT_SYMTAB, 6, \ + "address of the symbol table") \ +_ELF_DEFINE_DT(DT_RELA, 7, \ + "address of the relocation table") \ +_ELF_DEFINE_DT(DT_RELASZ, 8, "size of the DT_RELA table") \ +_ELF_DEFINE_DT(DT_RELAENT, 9, "size of each DT_RELA entry") \ +_ELF_DEFINE_DT(DT_STRSZ, 10, "size of the string table") \ +_ELF_DEFINE_DT(DT_SYMENT, 11, \ + "size of a symbol table entry") \ +_ELF_DEFINE_DT(DT_INIT, 12, \ + "address of the initialization function") \ +_ELF_DEFINE_DT(DT_FINI, 13, \ + "address of the finalization function") \ +_ELF_DEFINE_DT(DT_SONAME, 14, "names the shared object") \ +_ELF_DEFINE_DT(DT_RPATH, 15, \ + "runtime library search path") \ +_ELF_DEFINE_DT(DT_SYMBOLIC, 16, \ + "alter symbol resolution algorithm") \ +_ELF_DEFINE_DT(DT_REL, 17, \ + "address of the DT_REL table") \ +_ELF_DEFINE_DT(DT_RELSZ, 18, "size of the DT_REL table") \ +_ELF_DEFINE_DT(DT_RELENT, 19, "size of each DT_REL entry") \ +_ELF_DEFINE_DT(DT_PLTREL, 20, \ + "type of relocation entry in the procedure linkage table") \ +_ELF_DEFINE_DT(DT_DEBUG, 21, "used for debugging") \ +_ELF_DEFINE_DT(DT_TEXTREL, 22, \ + "text segment may be written to during relocation") \ +_ELF_DEFINE_DT(DT_JMPREL, 23, \ + "address of relocation entries associated with the procedure linkage table") \ +_ELF_DEFINE_DT(DT_BIND_NOW, 24, \ + "bind symbols at loading time") \ +_ELF_DEFINE_DT(DT_INIT_ARRAY, 25, \ + "pointers to initialization functions") \ +_ELF_DEFINE_DT(DT_FINI_ARRAY, 26, \ + "pointers to termination functions") \ +_ELF_DEFINE_DT(DT_INIT_ARRAYSZ, 27, "size of the DT_INIT_ARRAY") \ +_ELF_DEFINE_DT(DT_FINI_ARRAYSZ, 28, "size of the DT_FINI_ARRAY") \ +_ELF_DEFINE_DT(DT_RUNPATH, 29, \ + "index of library search path string") \ +_ELF_DEFINE_DT(DT_FLAGS, 30, \ + "flags specific to the object being loaded") \ +_ELF_DEFINE_DT(DT_ENCODING, 32, "standard semantics") \ +_ELF_DEFINE_DT(DT_PREINIT_ARRAY, 32, \ + "pointers to pre-initialization functions") \ +_ELF_DEFINE_DT(DT_PREINIT_ARRAYSZ, 33, \ + "size of pre-initialization array") \ +_ELF_DEFINE_DT(DT_MAXPOSTAGS, 34, \ + "the number of positive tags") \ +_ELF_DEFINE_DT(DT_LOOS, 0x6000000DUL, \ + "start of OS-specific types") \ +_ELF_DEFINE_DT(DT_SUNW_AUXILIARY, 0x6000000DUL, \ + "offset of string naming auxiliary filtees") \ +_ELF_DEFINE_DT(DT_SUNW_RTLDINF, 0x6000000EUL, "rtld internal use") \ +_ELF_DEFINE_DT(DT_SUNW_FILTER, 0x6000000FUL, \ + "offset of string naming standard filtees") \ +_ELF_DEFINE_DT(DT_SUNW_CAP, 0x60000010UL, \ + "address of hardware capabilities section") \ +_ELF_DEFINE_DT(DT_HIOS, 0x6FFFF000UL, \ + "end of OS-specific types") \ +_ELF_DEFINE_DT(DT_VALRNGLO, 0x6FFFFD00UL, \ + "start of range using the d_val field") \ +_ELF_DEFINE_DT(DT_GNU_PRELINKED, 0x6FFFFDF5UL, \ + "prelinking timestamp") \ +_ELF_DEFINE_DT(DT_GNU_CONFLICTSZ, 0x6FFFFDF6UL, \ + "size of conflict section") \ +_ELF_DEFINE_DT(DT_GNU_LIBLISTSZ, 0x6FFFFDF7UL, \ + "size of library list") \ +_ELF_DEFINE_DT(DT_CHECKSUM, 0x6FFFFDF8UL, \ + "checksum for the object") \ +_ELF_DEFINE_DT(DT_PLTPADSZ, 0x6FFFFDF9UL, \ + "size of PLT padding") \ +_ELF_DEFINE_DT(DT_MOVEENT, 0x6FFFFDFAUL, \ + "size of DT_MOVETAB entries") \ +_ELF_DEFINE_DT(DT_MOVESZ, 0x6FFFFDFBUL, \ + "total size of the MOVETAB table") \ +_ELF_DEFINE_DT(DT_FEATURE_1, 0x6FFFFDFCUL, "feature values") \ +_ELF_DEFINE_DT(DT_POSFLAG_1, 0x6FFFFDFDUL, \ + "dynamic position flags") \ +_ELF_DEFINE_DT(DT_SYMINSZ, 0x6FFFFDFEUL, \ + "size of the DT_SYMINFO table") \ +_ELF_DEFINE_DT(DT_SYMINENT, 0x6FFFFDFFUL, \ + "size of a DT_SYMINFO entry") \ +_ELF_DEFINE_DT(DT_VALRNGHI, 0x6FFFFDFFUL, \ + "end of range using the d_val field") \ +_ELF_DEFINE_DT(DT_ADDRRNGLO, 0x6FFFFE00UL, \ + "start of range using the d_ptr field") \ +_ELF_DEFINE_DT(DT_GNU_HASH, 0x6FFFFEF5UL, \ + "GNU style hash tables") \ +_ELF_DEFINE_DT(DT_GNU_CONFLICT, 0x6FFFFEF8UL, \ + "address of conflict section") \ +_ELF_DEFINE_DT(DT_GNU_LIBLIST, 0x6FFFFEF9UL, \ + "address of conflict section") \ +_ELF_DEFINE_DT(DT_CONFIG, 0x6FFFFEFAUL, \ + "configuration file") \ +_ELF_DEFINE_DT(DT_DEPAUDIT, 0x6FFFFEFBUL, \ + "string defining audit libraries") \ +_ELF_DEFINE_DT(DT_AUDIT, 0x6FFFFEFCUL, \ + "string defining audit libraries") \ +_ELF_DEFINE_DT(DT_PLTPAD, 0x6FFFFEFDUL, "PLT padding") \ +_ELF_DEFINE_DT(DT_MOVETAB, 0x6FFFFEFEUL, \ + "address of a move table") \ +_ELF_DEFINE_DT(DT_SYMINFO, 0x6FFFFEFFUL, \ + "address of the symbol information table") \ +_ELF_DEFINE_DT(DT_ADDRRNGHI, 0x6FFFFEFFUL, \ + "end of range using the d_ptr field") \ +_ELF_DEFINE_DT(DT_VERSYM, 0x6FFFFFF0UL, \ + "address of the version section") \ +_ELF_DEFINE_DT(DT_RELACOUNT, 0x6FFFFFF9UL, \ + "count of RELA relocations") \ +_ELF_DEFINE_DT(DT_RELCOUNT, 0x6FFFFFFAUL, \ + "count of REL relocations") \ +_ELF_DEFINE_DT(DT_FLAGS_1, 0x6FFFFFFBUL, "flag values") \ +_ELF_DEFINE_DT(DT_VERDEF, 0x6FFFFFFCUL, \ + "address of the version definition segment") \ +_ELF_DEFINE_DT(DT_VERDEFNUM, 0x6FFFFFFDUL, \ + "the number of version definition entries") \ +_ELF_DEFINE_DT(DT_VERNEED, 0x6FFFFFFEUL, \ + "address of section with needed versions") \ +_ELF_DEFINE_DT(DT_VERNEEDNUM, 0x6FFFFFFFUL, \ + "the number of version needed entries") \ +_ELF_DEFINE_DT(DT_LOPROC, 0x70000000UL, \ + "start of processor-specific types") \ +_ELF_DEFINE_DT(DT_ARM_SYMTABSZ, 0x70000001UL, \ + "number of entries in the dynamic symbol table") \ +_ELF_DEFINE_DT(DT_SPARC_REGISTER, 0x70000001UL, \ + "index of an STT_SPARC_REGISTER symbol") \ +_ELF_DEFINE_DT(DT_ARM_PREEMPTMAP, 0x70000002UL, \ + "address of the preemption map") \ +_ELF_DEFINE_DT(DT_MIPS_RLD_VERSION, 0x70000001UL, \ + "version ID for runtime linker interface") \ +_ELF_DEFINE_DT(DT_MIPS_TIME_STAMP, 0x70000002UL, \ + "timestamp") \ +_ELF_DEFINE_DT(DT_MIPS_ICHECKSUM, 0x70000003UL, \ + "checksum of all external strings and common sizes") \ +_ELF_DEFINE_DT(DT_MIPS_IVERSION, 0x70000004UL, \ + "string table index of a version string") \ +_ELF_DEFINE_DT(DT_MIPS_FLAGS, 0x70000005UL, \ + "MIPS-specific flags") \ +_ELF_DEFINE_DT(DT_MIPS_BASE_ADDRESS, 0x70000006UL, \ + "base address for the executable/DSO") \ +_ELF_DEFINE_DT(DT_MIPS_CONFLICT, 0x70000008UL, \ + "address of .conflict section") \ +_ELF_DEFINE_DT(DT_MIPS_LIBLIST, 0x70000009UL, \ + "address of .liblist section") \ +_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTNO, 0x7000000AUL, \ + "number of local GOT entries") \ +_ELF_DEFINE_DT(DT_MIPS_CONFLICTNO, 0x7000000BUL, \ + "number of entries in the .conflict section") \ +_ELF_DEFINE_DT(DT_MIPS_LIBLISTNO, 0x70000010UL, \ + "number of entries in the .liblist section") \ +_ELF_DEFINE_DT(DT_MIPS_SYMTABNO, 0x70000011UL, \ + "number of entries in the .dynsym section") \ +_ELF_DEFINE_DT(DT_MIPS_UNREFEXTNO, 0x70000012UL, \ + "index of first external dynamic symbol not ref'ed locally") \ +_ELF_DEFINE_DT(DT_MIPS_GOTSYM, 0x70000013UL, \ + "index of first dynamic symbol corresponds to a GOT entry") \ +_ELF_DEFINE_DT(DT_MIPS_HIPAGENO, 0x70000014UL, \ + "number of page table entries in GOT") \ +_ELF_DEFINE_DT(DT_MIPS_RLD_MAP, 0x70000016UL, \ + "address of runtime linker map") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS, 0x70000017UL, \ + "Delta C++ class definition") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASS_NO, 0x70000018UL, \ + "number of entries in DT_MIPS_DELTA_CLASS") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE, 0x70000019UL, \ + "Delta C++ class instances") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_INSTANCE_NO, 0x7000001AUL, \ + "number of entries in DT_MIPS_DELTA_INSTANCE") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC, 0x7000001BUL, \ + "Delta relocations") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_RELOC_NO, 0x7000001CUL, \ + "number of entries in DT_MIPS_DELTA_RELOC") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM, 0x7000001DUL, \ + "Delta symbols refered by Delta relocations") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_SYM_NO, 0x7000001EUL, \ + "number of entries in DT_MIPS_DELTA_SYM") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM, 0x70000020UL, \ + "Delta symbols for class declarations") \ +_ELF_DEFINE_DT(DT_MIPS_DELTA_CLASSSYM_NO, 0x70000021UL, \ + "number of entries in DT_MIPS_DELTA_CLASSSYM") \ +_ELF_DEFINE_DT(DT_MIPS_CXX_FLAGS, 0x70000022UL, \ + "C++ flavor flags") \ +_ELF_DEFINE_DT(DT_MIPS_PIXIE_INIT, 0x70000023UL, \ + "address of an initialization routine created by pixie") \ +_ELF_DEFINE_DT(DT_MIPS_SYMBOL_LIB, 0x70000024UL, \ + "address of .MIPS.symlib section") \ +_ELF_DEFINE_DT(DT_MIPS_LOCALPAGE_GOTIDX, 0x70000025UL, \ + "GOT index of first page table entry for a segment") \ +_ELF_DEFINE_DT(DT_MIPS_LOCAL_GOTIDX, 0x70000026UL, \ + "GOT index of first page table entry for a local symbol") \ +_ELF_DEFINE_DT(DT_MIPS_HIDDEN_GOTIDX, 0x70000027UL, \ + "GOT index of first page table entry for a hidden symbol") \ +_ELF_DEFINE_DT(DT_MIPS_PROTECTED_GOTIDX, 0x70000028UL, \ + "GOT index of first page table entry for a protected symbol") \ +_ELF_DEFINE_DT(DT_MIPS_OPTIONS, 0x70000029UL, \ + "address of .MIPS.options section") \ +_ELF_DEFINE_DT(DT_MIPS_INTERFACE, 0x7000002AUL, \ + "address of .MIPS.interface section") \ +_ELF_DEFINE_DT(DT_MIPS_DYNSTR_ALIGN, 0x7000002BUL, "???") \ +_ELF_DEFINE_DT(DT_MIPS_INTERFACE_SIZE, 0x7000002CUL, \ + "size of .MIPS.interface section") \ +_ELF_DEFINE_DT(DT_MIPS_RLD_TEXT_RESOLVE_ADDR, 0x7000002DUL, \ + "address of _rld_text_resolve in GOT") \ +_ELF_DEFINE_DT(DT_MIPS_PERF_SUFFIX, 0x7000002EUL, \ + "default suffix of DSO to be appended by dlopen") \ +_ELF_DEFINE_DT(DT_MIPS_COMPACT_SIZE, 0x7000002FUL, \ + "size of a ucode compact relocation record (o32)") \ +_ELF_DEFINE_DT(DT_MIPS_GP_VALUE, 0x70000030UL, \ + "GP value of a specified GP relative range") \ +_ELF_DEFINE_DT(DT_MIPS_AUX_DYNAMIC, 0x70000031UL, \ + "address of an auxiliary dynamic table") \ +_ELF_DEFINE_DT(DT_MIPS_PLTGOT, 0x70000032UL, \ + "address of the PLTGOT") \ +_ELF_DEFINE_DT(DT_MIPS_RLD_OBJ_UPDATE, 0x70000033UL, \ + "object list update callback") \ +_ELF_DEFINE_DT(DT_MIPS_RWPLT, 0x70000034UL, \ + "address of a writable PLT") \ +_ELF_DEFINE_DT(DT_PPC_GOT, 0x70000000UL, \ + "value of _GLOBAL_OFFSET_TABLE_") \ +_ELF_DEFINE_DT(DT_PPC_TLSOPT, 0x70000001UL, \ + "TLS descriptor should be optimized") \ +_ELF_DEFINE_DT(DT_PPC64_GLINK, 0x70000000UL, \ + "address of .glink section") \ +_ELF_DEFINE_DT(DT_PPC64_OPD, 0x70000001UL, \ + "address of .opd section") \ +_ELF_DEFINE_DT(DT_PPC64_OPDSZ, 0x70000002UL, \ + "size of .opd section") \ +_ELF_DEFINE_DT(DT_PPC64_TLSOPT, 0x70000003UL, \ + "TLS descriptor should be optimized") \ +_ELF_DEFINE_DT(DT_AUXILIARY, 0x7FFFFFFDUL, \ + "offset of string naming auxiliary filtees") \ +_ELF_DEFINE_DT(DT_USED, 0x7FFFFFFEUL, "ignored") \ +_ELF_DEFINE_DT(DT_FILTER, 0x7FFFFFFFUL, \ + "index of string naming filtees") \ +_ELF_DEFINE_DT(DT_HIPROC, 0x7FFFFFFFUL, \ + "end of processor-specific types") + +#undef _ELF_DEFINE_DT +#define _ELF_DEFINE_DT(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_DYN_TYPES() + DT__LAST__ = DT_HIPROC +}; + +#define DT_DEPRECATED_SPARC_REGISTER DT_SPARC_REGISTER + +/* + * Flags used in the executable header (field: e_flags). + */ +#define _ELF_DEFINE_EHDR_FLAGS() \ +_ELF_DEFINE_EF(EF_ARM_RELEXEC, 0x00000001UL, \ + "dynamic segment describes only how to relocate segments") \ +_ELF_DEFINE_EF(EF_ARM_HASENTRY, 0x00000002UL, \ + "e_entry contains a program entry point") \ +_ELF_DEFINE_EF(EF_ARM_SYMSARESORTED, 0x00000004UL, \ + "subsection of symbol table is sorted by symbol value") \ +_ELF_DEFINE_EF(EF_ARM_DYNSYMSUSESEGIDX, 0x00000008UL, \ + "dynamic symbol st_shndx = containing segment index + 1") \ +_ELF_DEFINE_EF(EF_ARM_MAPSYMSFIRST, 0x00000010UL, \ + "mapping symbols precede other local symbols in symtab") \ +_ELF_DEFINE_EF(EF_ARM_BE8, 0x00800000UL, \ + "file contains BE-8 code") \ +_ELF_DEFINE_EF(EF_ARM_LE8, 0x00400000UL, \ + "file contains LE-8 code") \ +_ELF_DEFINE_EF(EF_ARM_EABIMASK, 0xFF000000UL, \ + "mask for ARM EABI version number (0 denotes GNU or unknown)") \ +_ELF_DEFINE_EF(EF_ARM_EABI_UNKNOWN, 0x00000000UL, \ + "Unknown or GNU ARM EABI version number") \ +_ELF_DEFINE_EF(EF_ARM_EABI_VER1, 0x01000000UL, \ + "ARM EABI version 1") \ +_ELF_DEFINE_EF(EF_ARM_EABI_VER2, 0x02000000UL, \ + "ARM EABI version 2") \ +_ELF_DEFINE_EF(EF_ARM_EABI_VER3, 0x03000000UL, \ + "ARM EABI version 3") \ +_ELF_DEFINE_EF(EF_ARM_EABI_VER4, 0x04000000UL, \ + "ARM EABI version 4") \ +_ELF_DEFINE_EF(EF_ARM_EABI_VER5, 0x05000000UL, \ + "ARM EABI version 5") \ +_ELF_DEFINE_EF(EF_ARM_INTERWORK, 0x00000004UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_APCS_26, 0x00000008UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_APCS_FLOAT, 0x00000010UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_PIC, 0x00000020UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_ALIGN8, 0x00000040UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_NEW_ABI, 0x00000080UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_OLD_ABI, 0x00000100UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_SOFT_FLOAT, 0x00000200UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_VFP_FLOAT, 0x00000400UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_ARM_MAVERICK_FLOAT, 0x00000800UL, \ + "GNU EABI extension") \ +_ELF_DEFINE_EF(EF_MIPS_NOREORDER, 0x00000001UL, \ + "at least one .noreorder directive appeared in the source") \ +_ELF_DEFINE_EF(EF_MIPS_PIC, 0x00000002UL, \ + "file contains position independent code") \ +_ELF_DEFINE_EF(EF_MIPS_CPIC, 0x00000004UL, \ + "file's code uses standard conventions for calling PIC") \ +_ELF_DEFINE_EF(EF_MIPS_UCODE, 0x00000010UL, \ + "file contains UCODE (obsolete)") \ +_ELF_DEFINE_EF(EF_MIPS_ABI2, 0x00000020UL, \ + "file follows MIPS III 32-bit ABI") \ +_ELF_DEFINE_EF(EF_MIPS_OPTIONS_FIRST, 0x00000080UL, \ + "ld(1) should process .MIPS.options section first") \ +_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE, 0x0F000000UL, \ + "file uses application-specific architectural extensions") \ +_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_MDMX, 0x08000000UL, \ + "file uses MDMX multimedia extensions") \ +_ELF_DEFINE_EF(EF_MIPS_ARCH_ASE_M16, 0x04000000UL, \ + "file uses MIPS-16 ISA extensions") \ +_ELF_DEFINE_EF(EF_MIPS_ARCH, 0xF0000000UL, \ + "4-bit MIPS architecture field") \ +_ELF_DEFINE_EF(EF_PPC_EMB, 0x80000000UL, \ + "Embedded PowerPC flag") \ +_ELF_DEFINE_EF(EF_PPC_RELOCATABLE, 0x00010000UL, \ + "-mrelocatable flag") \ +_ELF_DEFINE_EF(EF_PPC_RELOCATABLE_LIB, 0x00008000UL, \ + "-mrelocatable-lib flag") \ +_ELF_DEFINE_EF(EF_SPARC_EXT_MASK, 0x00ffff00UL, \ + "Vendor Extension mask") \ +_ELF_DEFINE_EF(EF_SPARC_32PLUS, 0x00000100UL, \ + "Generic V8+ features") \ +_ELF_DEFINE_EF(EF_SPARC_SUN_US1, 0x00000200UL, \ + "Sun UltraSPARCTM 1 Extensions") \ +_ELF_DEFINE_EF(EF_SPARC_HAL_R1, 0x00000400UL, "HAL R1 Extensions") \ +_ELF_DEFINE_EF(EF_SPARC_SUN_US3, 0x00000800UL, \ + "Sun UltraSPARC 3 Extensions") \ +_ELF_DEFINE_EF(EF_SPARCV9_MM, 0x00000003UL, \ + "Mask for Memory Model") \ +_ELF_DEFINE_EF(EF_SPARCV9_TSO, 0x00000000UL, \ + "Total Store Ordering") \ +_ELF_DEFINE_EF(EF_SPARCV9_PSO, 0x00000001UL, \ + "Partial Store Ordering") \ +_ELF_DEFINE_EF(EF_SPARCV9_RMO, 0x00000002UL, \ + "Relaxed Memory Ordering") + +#undef _ELF_DEFINE_EF +#define _ELF_DEFINE_EF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_EHDR_FLAGS() + EF__LAST__ +}; + +/* + * Offsets in the `ei_ident[]` field of an ELF executable header. + */ +#define _ELF_DEFINE_EI_OFFSETS() \ +_ELF_DEFINE_EI(EI_MAG0, 0, "magic number") \ +_ELF_DEFINE_EI(EI_MAG1, 1, "magic number") \ +_ELF_DEFINE_EI(EI_MAG2, 2, "magic number") \ +_ELF_DEFINE_EI(EI_MAG3, 3, "magic number") \ +_ELF_DEFINE_EI(EI_CLASS, 4, "file class") \ +_ELF_DEFINE_EI(EI_DATA, 5, "data encoding") \ +_ELF_DEFINE_EI(EI_VERSION, 6, "file version") \ +_ELF_DEFINE_EI(EI_OSABI, 7, "OS ABI kind") \ +_ELF_DEFINE_EI(EI_ABIVERSION, 8, "OS ABI version") \ +_ELF_DEFINE_EI(EI_PAD, 9, "padding start") \ +_ELF_DEFINE_EI(EI_NIDENT, 16, "total size") + +#undef _ELF_DEFINE_EI +#define _ELF_DEFINE_EI(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_EI_OFFSETS() + EI__LAST__ +}; + +/* + * The ELF class of an object. + */ +#define _ELF_DEFINE_ELFCLASS() \ +_ELF_DEFINE_EC(ELFCLASSNONE, 0, "Unknown ELF class") \ +_ELF_DEFINE_EC(ELFCLASS32, 1, "32 bit objects") \ +_ELF_DEFINE_EC(ELFCLASS64, 2, "64 bit objects") + +#undef _ELF_DEFINE_EC +#define _ELF_DEFINE_EC(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ELFCLASS() + EC__LAST__ +}; + +/* + * Endianness of data in an ELF object. + */ + +#define _ELF_DEFINE_ELF_DATA_ENDIANNESS() \ +_ELF_DEFINE_ED(ELFDATANONE, 0, "Unknown data endianness") \ +_ELF_DEFINE_ED(ELFDATA2LSB, 1, "little endian") \ +_ELF_DEFINE_ED(ELFDATA2MSB, 2, "big endian") + +#undef _ELF_DEFINE_ED +#define _ELF_DEFINE_ED(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ELF_DATA_ENDIANNESS() + ED__LAST__ +}; + +/* + * Values of the magic numbers used in identification array. + */ +#define _ELF_DEFINE_ELF_MAGIC() \ +_ELF_DEFINE_EMAG(ELFMAG0, 0x7FU) \ +_ELF_DEFINE_EMAG(ELFMAG1, 'E') \ +_ELF_DEFINE_EMAG(ELFMAG2, 'L') \ +_ELF_DEFINE_EMAG(ELFMAG3, 'F') + +#undef _ELF_DEFINE_EMAG +#define _ELF_DEFINE_EMAG(N, V) N = V , +enum { + _ELF_DEFINE_ELF_MAGIC() + ELFMAG__LAST__ +}; + +/* + * ELF OS ABI field. + */ +#define _ELF_DEFINE_ELF_OSABI() \ +_ELF_DEFINE_EABI(ELFOSABI_NONE, 0, \ + "No extensions or unspecified") \ +_ELF_DEFINE_EABI(ELFOSABI_SYSV, 0, "SYSV") \ +_ELF_DEFINE_EABI(ELFOSABI_HPUX, 1, "Hewlett-Packard HP-UX") \ +_ELF_DEFINE_EABI(ELFOSABI_NETBSD, 2, "NetBSD") \ +_ELF_DEFINE_EABI(ELFOSABI_GNU, 3, "GNU") \ +_ELF_DEFINE_EABI(ELFOSABI_HURD, 4, "GNU/HURD") \ +_ELF_DEFINE_EABI(ELFOSABI_86OPEN, 5, "86Open Common ABI") \ +_ELF_DEFINE_EABI(ELFOSABI_SOLARIS, 6, "Sun Solaris") \ +_ELF_DEFINE_EABI(ELFOSABI_AIX, 7, "AIX") \ +_ELF_DEFINE_EABI(ELFOSABI_IRIX, 8, "IRIX") \ +_ELF_DEFINE_EABI(ELFOSABI_FREEBSD, 9, "FreeBSD") \ +_ELF_DEFINE_EABI(ELFOSABI_TRU64, 10, "Compaq TRU64 UNIX") \ +_ELF_DEFINE_EABI(ELFOSABI_MODESTO, 11, "Novell Modesto") \ +_ELF_DEFINE_EABI(ELFOSABI_OPENBSD, 12, "Open BSD") \ +_ELF_DEFINE_EABI(ELFOSABI_OPENVMS, 13, "Open VMS") \ +_ELF_DEFINE_EABI(ELFOSABI_NSK, 14, \ + "Hewlett-Packard Non-Stop Kernel") \ +_ELF_DEFINE_EABI(ELFOSABI_AROS, 15, "Amiga Research OS") \ +_ELF_DEFINE_EABI(ELFOSABI_FENIXOS, 16, \ + "The FenixOS highly scalable multi-core OS") \ +_ELF_DEFINE_EABI(ELFOSABI_ARM_AEABI, 64, \ + "ARM specific symbol versioning extensions") \ +_ELF_DEFINE_EABI(ELFOSABI_ARM, 97, "ARM ABI") \ +_ELF_DEFINE_EABI(ELFOSABI_STANDALONE, 255, \ + "Standalone (embedded) application") + +#undef _ELF_DEFINE_EABI +#define _ELF_DEFINE_EABI(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ELF_OSABI() + ELFOSABI__LAST__ +}; + +#define ELFOSABI_LINUX ELFOSABI_GNU + +/* + * ELF Machine types: (EM_*). + */ +#define _ELF_DEFINE_ELF_MACHINES() \ +_ELF_DEFINE_EM(EM_NONE, 0, "No machine") \ +_ELF_DEFINE_EM(EM_M32, 1, "AT&T WE 32100") \ +_ELF_DEFINE_EM(EM_SPARC, 2, "SPARC") \ +_ELF_DEFINE_EM(EM_386, 3, "Intel 80386") \ +_ELF_DEFINE_EM(EM_68K, 4, "Motorola 68000") \ +_ELF_DEFINE_EM(EM_88K, 5, "Motorola 88000") \ +_ELF_DEFINE_EM(EM_860, 7, "Intel 80860") \ +_ELF_DEFINE_EM(EM_MIPS, 8, "MIPS I Architecture") \ +_ELF_DEFINE_EM(EM_S370, 9, "IBM System/370 Processor") \ +_ELF_DEFINE_EM(EM_MIPS_RS3_LE, 10, "MIPS RS3000 Little-endian") \ +_ELF_DEFINE_EM(EM_PARISC, 15, "Hewlett-Packard PA-RISC") \ +_ELF_DEFINE_EM(EM_VPP500, 17, "Fujitsu VPP500") \ +_ELF_DEFINE_EM(EM_SPARC32PLUS, 18, \ + "Enhanced instruction set SPARC") \ +_ELF_DEFINE_EM(EM_960, 19, "Intel 80960") \ +_ELF_DEFINE_EM(EM_PPC, 20, "PowerPC") \ +_ELF_DEFINE_EM(EM_PPC64, 21, "64-bit PowerPC") \ +_ELF_DEFINE_EM(EM_S390, 22, "IBM System/390 Processor") \ +_ELF_DEFINE_EM(EM_SPU, 23, "IBM SPU/SPC") \ +_ELF_DEFINE_EM(EM_V800, 36, "NEC V800") \ +_ELF_DEFINE_EM(EM_FR20, 37, "Fujitsu FR20") \ +_ELF_DEFINE_EM(EM_RH32, 38, "TRW RH-32") \ +_ELF_DEFINE_EM(EM_RCE, 39, "Motorola RCE") \ +_ELF_DEFINE_EM(EM_ARM, 40, "Advanced RISC Machines ARM") \ +_ELF_DEFINE_EM(EM_ALPHA, 41, "Digital Alpha") \ +_ELF_DEFINE_EM(EM_SH, 42, "Hitachi SH") \ +_ELF_DEFINE_EM(EM_SPARCV9, 43, "SPARC Version 9") \ +_ELF_DEFINE_EM(EM_TRICORE, 44, \ + "Siemens TriCore embedded processor") \ +_ELF_DEFINE_EM(EM_ARC, 45, \ + "Argonaut RISC Core, Argonaut Technologies Inc.") \ +_ELF_DEFINE_EM(EM_H8_300, 46, "Hitachi H8/300") \ +_ELF_DEFINE_EM(EM_H8_300H, 47, "Hitachi H8/300H") \ +_ELF_DEFINE_EM(EM_H8S, 48, "Hitachi H8S") \ +_ELF_DEFINE_EM(EM_H8_500, 49, "Hitachi H8/500") \ +_ELF_DEFINE_EM(EM_IA_64, 50, \ + "Intel IA-64 processor architecture") \ +_ELF_DEFINE_EM(EM_MIPS_X, 51, "Stanford MIPS-X") \ +_ELF_DEFINE_EM(EM_COLDFIRE, 52, "Motorola ColdFire") \ +_ELF_DEFINE_EM(EM_68HC12, 53, "Motorola M68HC12") \ +_ELF_DEFINE_EM(EM_MMA, 54, \ + "Fujitsu MMA Multimedia Accelerator") \ +_ELF_DEFINE_EM(EM_PCP, 55, "Siemens PCP") \ +_ELF_DEFINE_EM(EM_NCPU, 56, \ + "Sony nCPU embedded RISC processor") \ +_ELF_DEFINE_EM(EM_NDR1, 57, "Denso NDR1 microprocessor") \ +_ELF_DEFINE_EM(EM_STARCORE, 58, "Motorola Star*Core processor") \ +_ELF_DEFINE_EM(EM_ME16, 59, "Toyota ME16 processor") \ +_ELF_DEFINE_EM(EM_ST100, 60, \ + "STMicroelectronics ST100 processor") \ +_ELF_DEFINE_EM(EM_TINYJ, 61, \ + "Advanced Logic Corp. TinyJ embedded processor family") \ +_ELF_DEFINE_EM(EM_X86_64, 62, "AMD x86-64 architecture") \ +_ELF_DEFINE_EM(EM_PDSP, 63, "Sony DSP Processor") \ +_ELF_DEFINE_EM(EM_PDP10, 64, \ + "Digital Equipment Corp. PDP-10") \ +_ELF_DEFINE_EM(EM_PDP11, 65, \ + "Digital Equipment Corp. PDP-11") \ +_ELF_DEFINE_EM(EM_FX66, 66, "Siemens FX66 microcontroller") \ +_ELF_DEFINE_EM(EM_ST9PLUS, 67, \ + "STMicroelectronics ST9+ 8/16 bit microcontroller") \ +_ELF_DEFINE_EM(EM_ST7, 68, \ + "STMicroelectronics ST7 8-bit microcontroller") \ +_ELF_DEFINE_EM(EM_68HC16, 69, \ + "Motorola MC68HC16 Microcontroller") \ +_ELF_DEFINE_EM(EM_68HC11, 70, \ + "Motorola MC68HC11 Microcontroller") \ +_ELF_DEFINE_EM(EM_68HC08, 71, \ + "Motorola MC68HC08 Microcontroller") \ +_ELF_DEFINE_EM(EM_68HC05, 72, \ + "Motorola MC68HC05 Microcontroller") \ +_ELF_DEFINE_EM(EM_SVX, 73, "Silicon Graphics SVx") \ +_ELF_DEFINE_EM(EM_ST19, 74, \ + "STMicroelectronics ST19 8-bit microcontroller") \ +_ELF_DEFINE_EM(EM_VAX, 75, "Digital VAX") \ +_ELF_DEFINE_EM(EM_CRIS, 76, \ + "Axis Communications 32-bit embedded processor") \ +_ELF_DEFINE_EM(EM_JAVELIN, 77, \ + "Infineon Technologies 32-bit embedded processor") \ +_ELF_DEFINE_EM(EM_FIREPATH, 78, \ + "Element 14 64-bit DSP Processor") \ +_ELF_DEFINE_EM(EM_ZSP, 79, \ + "LSI Logic 16-bit DSP Processor") \ +_ELF_DEFINE_EM(EM_MMIX, 80, \ + "Donald Knuth's educational 64-bit processor") \ +_ELF_DEFINE_EM(EM_HUANY, 81, \ + "Harvard University machine-independent object files") \ +_ELF_DEFINE_EM(EM_PRISM, 82, "SiTera Prism") \ +_ELF_DEFINE_EM(EM_AVR, 83, \ + "Atmel AVR 8-bit microcontroller") \ +_ELF_DEFINE_EM(EM_FR30, 84, "Fujitsu FR30") \ +_ELF_DEFINE_EM(EM_D10V, 85, "Mitsubishi D10V") \ +_ELF_DEFINE_EM(EM_D30V, 86, "Mitsubishi D30V") \ +_ELF_DEFINE_EM(EM_V850, 87, "NEC v850") \ +_ELF_DEFINE_EM(EM_M32R, 88, "Mitsubishi M32R") \ +_ELF_DEFINE_EM(EM_MN10300, 89, "Matsushita MN10300") \ +_ELF_DEFINE_EM(EM_MN10200, 90, "Matsushita MN10200") \ +_ELF_DEFINE_EM(EM_PJ, 91, "picoJava") \ +_ELF_DEFINE_EM(EM_OPENRISC, 92, \ + "OpenRISC 32-bit embedded processor") \ +_ELF_DEFINE_EM(EM_ARC_COMPACT, 93, \ + "ARC International ARCompact processor") \ +_ELF_DEFINE_EM(EM_XTENSA, 94, \ + "Tensilica Xtensa Architecture") \ +_ELF_DEFINE_EM(EM_VIDEOCORE, 95, \ + "Alphamosaic VideoCore processor") \ +_ELF_DEFINE_EM(EM_TMM_GPP, 96, \ + "Thompson Multimedia General Purpose Processor") \ +_ELF_DEFINE_EM(EM_NS32K, 97, \ + "National Semiconductor 32000 series") \ +_ELF_DEFINE_EM(EM_TPC, 98, "Tenor Network TPC processor") \ +_ELF_DEFINE_EM(EM_SNP1K, 99, "Trebia SNP 1000 processor") \ +_ELF_DEFINE_EM(EM_ST200, 100, \ + "STMicroelectronics (www.st.com) ST200 microcontroller") \ +_ELF_DEFINE_EM(EM_IP2K, 101, \ + "Ubicom IP2xxx microcontroller family") \ +_ELF_DEFINE_EM(EM_MAX, 102, "MAX Processor") \ +_ELF_DEFINE_EM(EM_CR, 103, \ + "National Semiconductor CompactRISC microprocessor") \ +_ELF_DEFINE_EM(EM_F2MC16, 104, "Fujitsu F2MC16") \ +_ELF_DEFINE_EM(EM_MSP430, 105, \ + "Texas Instruments embedded microcontroller msp430") \ +_ELF_DEFINE_EM(EM_BLACKFIN, 106, \ + "Analog Devices Blackfin (DSP) processor") \ +_ELF_DEFINE_EM(EM_SE_C33, 107, \ + "S1C33 Family of Seiko Epson processors") \ +_ELF_DEFINE_EM(EM_SEP, 108, \ + "Sharp embedded microprocessor") \ +_ELF_DEFINE_EM(EM_ARCA, 109, "Arca RISC Microprocessor") \ +_ELF_DEFINE_EM(EM_UNICORE, 110, \ + "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University") \ +_ELF_DEFINE_EM(EM_EXCESS, 111, \ + "eXcess: 16/32/64-bit configurable embedded CPU") \ +_ELF_DEFINE_EM(EM_DXP, 112, \ + "Icera Semiconductor Inc. Deep Execution Processor") \ +_ELF_DEFINE_EM(EM_ALTERA_NIOS2, 113, \ + "Altera Nios II soft-core processor") \ +_ELF_DEFINE_EM(EM_CRX, 114, \ + "National Semiconductor CompactRISC CRX microprocessor") \ +_ELF_DEFINE_EM(EM_XGATE, 115, \ + "Motorola XGATE embedded processor") \ +_ELF_DEFINE_EM(EM_C166, 116, \ + "Infineon C16x/XC16x processor") \ +_ELF_DEFINE_EM(EM_M16C, 117, \ + "Renesas M16C series microprocessors") \ +_ELF_DEFINE_EM(EM_DSPIC30F, 118, \ + "Microchip Technology dsPIC30F Digital Signal Controller") \ +_ELF_DEFINE_EM(EM_CE, 119, \ + "Freescale Communication Engine RISC core") \ +_ELF_DEFINE_EM(EM_M32C, 120, \ + "Renesas M32C series microprocessors") \ +_ELF_DEFINE_EM(EM_TSK3000, 131, "Altium TSK3000 core") \ +_ELF_DEFINE_EM(EM_RS08, 132, \ + "Freescale RS08 embedded processor") \ +_ELF_DEFINE_EM(EM_SHARC, 133, \ + "Analog Devices SHARC family of 32-bit DSP processors") \ +_ELF_DEFINE_EM(EM_ECOG2, 134, \ + "Cyan Technology eCOG2 microprocessor") \ +_ELF_DEFINE_EM(EM_SCORE7, 135, \ + "Sunplus S+core7 RISC processor") \ +_ELF_DEFINE_EM(EM_DSP24, 136, \ + "New Japan Radio (NJR) 24-bit DSP Processor") \ +_ELF_DEFINE_EM(EM_VIDEOCORE3, 137, \ + "Broadcom VideoCore III processor") \ +_ELF_DEFINE_EM(EM_LATTICEMICO32, 138, \ + "RISC processor for Lattice FPGA architecture") \ +_ELF_DEFINE_EM(EM_SE_C17, 139, "Seiko Epson C17 family") \ +_ELF_DEFINE_EM(EM_TI_C6000, 140, \ + "The Texas Instruments TMS320C6000 DSP family") \ +_ELF_DEFINE_EM(EM_TI_C2000, 141, \ + "The Texas Instruments TMS320C2000 DSP family") \ +_ELF_DEFINE_EM(EM_TI_C5500, 142, \ + "The Texas Instruments TMS320C55x DSP family") \ +_ELF_DEFINE_EM(EM_MMDSP_PLUS, 160, \ + "STMicroelectronics 64bit VLIW Data Signal Processor") \ +_ELF_DEFINE_EM(EM_CYPRESS_M8C, 161, "Cypress M8C microprocessor") \ +_ELF_DEFINE_EM(EM_R32C, 162, \ + "Renesas R32C series microprocessors") \ +_ELF_DEFINE_EM(EM_TRIMEDIA, 163, \ + "NXP Semiconductors TriMedia architecture family") \ +_ELF_DEFINE_EM(EM_QDSP6, 164, "QUALCOMM DSP6 Processor") \ +_ELF_DEFINE_EM(EM_8051, 165, "Intel 8051 and variants") \ +_ELF_DEFINE_EM(EM_STXP7X, 166, \ + "STMicroelectronics STxP7x family of configurable and extensible RISC processors") \ +_ELF_DEFINE_EM(EM_NDS32, 167, \ + "Andes Technology compact code size embedded RISC processor family") \ +_ELF_DEFINE_EM(EM_ECOG1, 168, \ + "Cyan Technology eCOG1X family") \ +_ELF_DEFINE_EM(EM_ECOG1X, 168, \ + "Cyan Technology eCOG1X family") \ +_ELF_DEFINE_EM(EM_MAXQ30, 169, \ + "Dallas Semiconductor MAXQ30 Core Micro-controllers") \ +_ELF_DEFINE_EM(EM_XIMO16, 170, \ + "New Japan Radio (NJR) 16-bit DSP Processor") \ +_ELF_DEFINE_EM(EM_MANIK, 171, \ + "M2000 Reconfigurable RISC Microprocessor") \ +_ELF_DEFINE_EM(EM_CRAYNV2, 172, \ + "Cray Inc. NV2 vector architecture") \ +_ELF_DEFINE_EM(EM_RX, 173, "Renesas RX family") \ +_ELF_DEFINE_EM(EM_METAG, 174, \ + "Imagination Technologies META processor architecture") \ +_ELF_DEFINE_EM(EM_MCST_ELBRUS, 175, \ + "MCST Elbrus general purpose hardware architecture") \ +_ELF_DEFINE_EM(EM_ECOG16, 176, \ + "Cyan Technology eCOG16 family") \ +_ELF_DEFINE_EM(EM_CR16, 177, \ + "National Semiconductor CompactRISC CR16 16-bit microprocessor") \ +_ELF_DEFINE_EM(EM_ETPU, 178, \ + "Freescale Extended Time Processing Unit") \ +_ELF_DEFINE_EM(EM_SLE9X, 179, \ + "Infineon Technologies SLE9X core") \ +_ELF_DEFINE_EM(EM_AVR32, 185, \ + "Atmel Corporation 32-bit microprocessor family") \ +_ELF_DEFINE_EM(EM_STM8, 186, \ + "STMicroeletronics STM8 8-bit microcontroller") \ +_ELF_DEFINE_EM(EM_TILE64, 187, \ + "Tilera TILE64 multicore architecture family") \ +_ELF_DEFINE_EM(EM_TILEPRO, 188, \ + "Tilera TILEPro multicore architecture family") \ +_ELF_DEFINE_EM(EM_MICROBLAZE, 189, \ + "Xilinx MicroBlaze 32-bit RISC soft processor core") \ +_ELF_DEFINE_EM(EM_CUDA, 190, "NVIDIA CUDA architecture") \ +_ELF_DEFINE_EM(EM_TILEGX, 191, \ + "Tilera TILE-Gx multicore architecture family") \ +_ELF_DEFINE_EM(EM_CLOUDSHIELD, 192, \ + "CloudShield architecture family") \ +_ELF_DEFINE_EM(EM_COREA_1ST, 193, \ + "KIPO-KAIST Core-A 1st generation processor family") \ +_ELF_DEFINE_EM(EM_COREA_2ND, 194, \ + "KIPO-KAIST Core-A 2nd generation processor family") \ +_ELF_DEFINE_EM(EM_ARC_COMPACT2, 195, "Synopsys ARCompact V2") \ +_ELF_DEFINE_EM(EM_OPEN8, 196, \ + "Open8 8-bit RISC soft processor core") \ +_ELF_DEFINE_EM(EM_RL78, 197, "Renesas RL78 family") \ +_ELF_DEFINE_EM(EM_VIDEOCORE5, 198, "Broadcom VideoCore V processor") \ +_ELF_DEFINE_EM(EM_78KOR, 199, "Renesas 78KOR family") \ +_ELF_DEFINE_EM(EM_56800EX, 200, \ + "Freescale 56800EX Digital Signal Controller") \ +_ELF_DEFINE_EM(EM_BA1, 201, "Beyond BA1 CPU architecture") \ +_ELF_DEFINE_EM(EM_BA2, 202, "Beyond BA2 CPU architecture") \ +_ELF_DEFINE_EM(EM_XCORE, 203, "XMOS xCORE processor family") \ +_ELF_DEFINE_EM(EM_MCHP_PIC, 204, "Microchip 8-bit PIC(r) family") \ +_ELF_DEFINE_EM(EM_INTEL205, 205, "Reserved by Intel") \ +_ELF_DEFINE_EM(EM_INTEL206, 206, "Reserved by Intel") \ +_ELF_DEFINE_EM(EM_INTEL207, 207, "Reserved by Intel") \ +_ELF_DEFINE_EM(EM_INTEL208, 208, "Reserved by Intel") \ +_ELF_DEFINE_EM(EM_INTEL209, 209, "Reserved by Intel") \ +_ELF_DEFINE_EM(EM_KM32, 210, "KM211 KM32 32-bit processor") \ +_ELF_DEFINE_EM(EM_KMX32, 211, "KM211 KMX32 32-bit processor") \ +_ELF_DEFINE_EM(EM_KMX16, 212, "KM211 KMX16 16-bit processor") \ +_ELF_DEFINE_EM(EM_KMX8, 213, "KM211 KMX8 8-bit processor") \ +_ELF_DEFINE_EM(EM_KVARC, 214, "KM211 KMX32 KVARC processor") + +#undef _ELF_DEFINE_EM +#define _ELF_DEFINE_EM(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ELF_MACHINES() + EM__LAST__ +}; + +/* Older synonyms. */ +#define EM_ARC_A5 EM_ARC_COMPACT + +/* + * ELF file types: (ET_*). + */ +#define _ELF_DEFINE_ELF_TYPES() \ +_ELF_DEFINE_ET(ET_NONE, 0, "No file type") \ +_ELF_DEFINE_ET(ET_REL, 1, "Relocatable object") \ +_ELF_DEFINE_ET(ET_EXEC, 2, "Executable") \ +_ELF_DEFINE_ET(ET_DYN, 3, "Shared object") \ +_ELF_DEFINE_ET(ET_CORE, 4, "Core file") \ +_ELF_DEFINE_ET(ET_LOOS, 0xFE00U, "Begin OS-specific range") \ +_ELF_DEFINE_ET(ET_HIOS, 0xFEFFU, "End OS-specific range") \ +_ELF_DEFINE_ET(ET_LOPROC, 0xFF00U, "Begin processor-specific range") \ +_ELF_DEFINE_ET(ET_HIPROC, 0xFFFFU, "End processor-specific range") + +#undef _ELF_DEFINE_ET +#define _ELF_DEFINE_ET(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ELF_TYPES() + ET__LAST__ +}; + +/* ELF file format version numbers. */ +#define EV_NONE 0 +#define EV_CURRENT 1 + +/* + * Flags for section groups. + */ +#define GRP_COMDAT 0x1 /* COMDAT semantics */ +#define GRP_MASKOS 0x0ff00000 /* OS-specific flags */ +#define GRP_MASKPROC 0xf0000000 /* processor-specific flags */ + +/* + * Flags used by program header table entries. + */ + +#define _ELF_DEFINE_PHDR_FLAGS() \ +_ELF_DEFINE_PF(PF_X, 0x1, "Execute") \ +_ELF_DEFINE_PF(PF_W, 0x2, "Write") \ +_ELF_DEFINE_PF(PF_R, 0x4, "Read") \ +_ELF_DEFINE_PF(PF_MASKOS, 0x0ff00000, "OS-specific flags") \ +_ELF_DEFINE_PF(PF_MASKPROC, 0xf0000000, "Processor-specific flags") \ +_ELF_DEFINE_PF(PF_ARM_SB, 0x10000000, \ + "segment contains the location addressed by the static base") \ +_ELF_DEFINE_PF(PF_ARM_PI, 0x20000000, \ + "segment is position-independent") \ +_ELF_DEFINE_PF(PF_ARM_ABS, 0x40000000, \ + "segment must be loaded at its base address") + +#undef _ELF_DEFINE_PF +#define _ELF_DEFINE_PF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_PHDR_FLAGS() + PF__LAST__ +}; + +/* + * Types of program header table entries. + */ + +#define _ELF_DEFINE_PHDR_TYPES() \ +_ELF_DEFINE_PT(PT_NULL, 0, "ignored entry") \ +_ELF_DEFINE_PT(PT_LOAD, 1, "loadable segment") \ +_ELF_DEFINE_PT(PT_DYNAMIC, 2, \ + "contains dynamic linking information") \ +_ELF_DEFINE_PT(PT_INTERP, 3, "names an interpreter") \ +_ELF_DEFINE_PT(PT_NOTE, 4, "auxiliary information") \ +_ELF_DEFINE_PT(PT_SHLIB, 5, "reserved") \ +_ELF_DEFINE_PT(PT_PHDR, 6, \ + "describes the program header itself") \ +_ELF_DEFINE_PT(PT_TLS, 7, "thread local storage") \ +_ELF_DEFINE_PT(PT_LOOS, 0x60000000UL, \ + "start of OS-specific range") \ +_ELF_DEFINE_PT(PT_SUNW_UNWIND, 0x6464E550UL, \ + "Solaris/amd64 stack unwind tables") \ +_ELF_DEFINE_PT(PT_GNU_EH_FRAME, 0x6474E550UL, \ + "GCC generated .eh_frame_hdr segment") \ +_ELF_DEFINE_PT(PT_GNU_STACK, 0x6474E551UL, \ + "Stack flags") \ +_ELF_DEFINE_PT(PT_GNU_RELRO, 0x6474E552UL, \ + "Segment becomes read-only after relocation") \ +_ELF_DEFINE_PT(PT_SUNWBSS, 0x6FFFFFFAUL, \ + "A Solaris .SUNW_bss section") \ +_ELF_DEFINE_PT(PT_SUNWSTACK, 0x6FFFFFFBUL, \ + "A Solaris process stack") \ +_ELF_DEFINE_PT(PT_SUNWDTRACE, 0x6FFFFFFCUL, \ + "Used by dtrace(1)") \ +_ELF_DEFINE_PT(PT_SUNWCAP, 0x6FFFFFFDUL, \ + "Special hardware capability requirements") \ +_ELF_DEFINE_PT(PT_HIOS, 0x6FFFFFFFUL, \ + "end of OS-specific range") \ +_ELF_DEFINE_PT(PT_LOPROC, 0x70000000UL, \ + "start of processor-specific range") \ +_ELF_DEFINE_PT(PT_ARM_ARCHEXT, 0x70000000UL, \ + "platform architecture compatibility information") \ +_ELF_DEFINE_PT(PT_ARM_EXIDX, 0x70000001UL, \ + "exception unwind tables") \ +_ELF_DEFINE_PT(PT_MIPS_REGINFO, 0x70000000UL, \ + "register usage information") \ +_ELF_DEFINE_PT(PT_MIPS_RTPROC, 0x70000001UL, \ + "runtime procedure table") \ +_ELF_DEFINE_PT(PT_MIPS_OPTIONS, 0x70000002UL, \ + "options segment") \ +_ELF_DEFINE_PT(PT_HIPROC, 0x7FFFFFFFUL, \ + "end of processor-specific range") + +#undef _ELF_DEFINE_PT +#define _ELF_DEFINE_PT(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_PHDR_TYPES() + PT__LAST__ = PT_HIPROC +}; + +/* synonyms. */ +#define PT_ARM_UNWIND PT_ARM_EXIDX +#define PT_HISUNW PT_HIOS +#define PT_LOSUNW PT_SUNWBSS + +/* + * Section flags. + */ + +#define _ELF_DEFINE_SECTION_FLAGS() \ +_ELF_DEFINE_SHF(SHF_WRITE, 0x1, \ + "writable during program execution") \ +_ELF_DEFINE_SHF(SHF_ALLOC, 0x2, \ + "occupies memory during program execution") \ +_ELF_DEFINE_SHF(SHF_EXECINSTR, 0x4, "executable instructions") \ +_ELF_DEFINE_SHF(SHF_MERGE, 0x10, \ + "may be merged to prevent duplication") \ +_ELF_DEFINE_SHF(SHF_STRINGS, 0x20, \ + "NUL-terminated character strings") \ +_ELF_DEFINE_SHF(SHF_INFO_LINK, 0x40, \ + "the sh_info field holds a link") \ +_ELF_DEFINE_SHF(SHF_LINK_ORDER, 0x80, \ + "special ordering requirements during linking") \ +_ELF_DEFINE_SHF(SHF_OS_NONCONFORMING, 0x100, \ + "requires OS-specific processing during linking") \ +_ELF_DEFINE_SHF(SHF_GROUP, 0x200, \ + "member of a section group") \ +_ELF_DEFINE_SHF(SHF_TLS, 0x400, \ + "holds thread-local storage") \ +_ELF_DEFINE_SHF(SHF_COMPRESSED, 0x800, \ + "holds compressed data") \ +_ELF_DEFINE_SHF(SHF_MASKOS, 0x0FF00000UL, \ + "bits reserved for OS-specific semantics") \ +_ELF_DEFINE_SHF(SHF_AMD64_LARGE, 0x10000000UL, \ + "section uses large code model") \ +_ELF_DEFINE_SHF(SHF_ENTRYSECT, 0x10000000UL, \ + "section contains an entry point (ARM)") \ +_ELF_DEFINE_SHF(SHF_COMDEF, 0x80000000UL, \ + "section may be multiply defined in input to link step (ARM)") \ +_ELF_DEFINE_SHF(SHF_MIPS_GPREL, 0x10000000UL, \ + "section must be part of global data area") \ +_ELF_DEFINE_SHF(SHF_MIPS_MERGE, 0x20000000UL, \ + "section data should be merged to eliminate duplication") \ +_ELF_DEFINE_SHF(SHF_MIPS_ADDR, 0x40000000UL, \ + "section data is addressed by default") \ +_ELF_DEFINE_SHF(SHF_MIPS_STRING, 0x80000000UL, \ + "section data is string data by default") \ +_ELF_DEFINE_SHF(SHF_MIPS_NOSTRIP, 0x08000000UL, \ + "section data may not be stripped") \ +_ELF_DEFINE_SHF(SHF_MIPS_LOCAL, 0x04000000UL, \ + "section data local to process") \ +_ELF_DEFINE_SHF(SHF_MIPS_NAMES, 0x02000000UL, \ + "linker must generate implicit hidden weak names") \ +_ELF_DEFINE_SHF(SHF_MIPS_NODUPE, 0x01000000UL, \ + "linker must retain only one copy") \ +_ELF_DEFINE_SHF(SHF_ORDERED, 0x40000000UL, \ + "section is ordered with respect to other sections") \ +_ELF_DEFINE_SHF(SHF_EXCLUDE, 0x80000000UL, \ + "section is excluded from executables and shared objects") \ +_ELF_DEFINE_SHF(SHF_MASKPROC, 0xF0000000UL, \ + "bits reserved for processor-specific semantics") + +#undef _ELF_DEFINE_SHF +#define _ELF_DEFINE_SHF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SECTION_FLAGS() + SHF__LAST__ +}; + +/* + * Special section indices. + */ +#define _ELF_DEFINE_SECTION_INDICES() \ +_ELF_DEFINE_SHN(SHN_UNDEF, 0, "undefined section") \ +_ELF_DEFINE_SHN(SHN_LORESERVE, 0xFF00U, "start of reserved area") \ +_ELF_DEFINE_SHN(SHN_LOPROC, 0xFF00U, \ + "start of processor-specific range") \ +_ELF_DEFINE_SHN(SHN_BEFORE, 0xFF00U, "used for section ordering") \ +_ELF_DEFINE_SHN(SHN_AFTER, 0xFF01U, "used for section ordering") \ +_ELF_DEFINE_SHN(SHN_AMD64_LCOMMON, 0xFF02U, "large common block label") \ +_ELF_DEFINE_SHN(SHN_MIPS_ACOMMON, 0xFF00U, \ + "allocated common symbols in a DSO") \ +_ELF_DEFINE_SHN(SHN_MIPS_TEXT, 0xFF01U, "Reserved (obsolete)") \ +_ELF_DEFINE_SHN(SHN_MIPS_DATA, 0xFF02U, "Reserved (obsolete)") \ +_ELF_DEFINE_SHN(SHN_MIPS_SCOMMON, 0xFF03U, \ + "gp-addressable common symbols") \ +_ELF_DEFINE_SHN(SHN_MIPS_SUNDEFINED, 0xFF04U, \ + "gp-addressable undefined symbols") \ +_ELF_DEFINE_SHN(SHN_MIPS_LCOMMON, 0xFF05U, "local common symbols") \ +_ELF_DEFINE_SHN(SHN_MIPS_LUNDEFINED, 0xFF06U, \ + "local undefined symbols") \ +_ELF_DEFINE_SHN(SHN_HIPROC, 0xFF1FU, \ + "end of processor-specific range") \ +_ELF_DEFINE_SHN(SHN_LOOS, 0xFF20U, \ + "start of OS-specific range") \ +_ELF_DEFINE_SHN(SHN_SUNW_IGNORE, 0xFF3FU, "used by dtrace") \ +_ELF_DEFINE_SHN(SHN_HIOS, 0xFF3FU, \ + "end of OS-specific range") \ +_ELF_DEFINE_SHN(SHN_ABS, 0xFFF1U, "absolute references") \ +_ELF_DEFINE_SHN(SHN_COMMON, 0xFFF2U, "references to COMMON areas") \ +_ELF_DEFINE_SHN(SHN_XINDEX, 0xFFFFU, "extended index") \ +_ELF_DEFINE_SHN(SHN_HIRESERVE, 0xFFFFU, "end of reserved area") + +#undef _ELF_DEFINE_SHN +#define _ELF_DEFINE_SHN(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SECTION_INDICES() + SHN__LAST__ +}; + +/* + * Section types. + */ + +#define _ELF_DEFINE_SECTION_TYPES() \ +_ELF_DEFINE_SHT(SHT_NULL, 0, "inactive header") \ +_ELF_DEFINE_SHT(SHT_PROGBITS, 1, "program defined information") \ +_ELF_DEFINE_SHT(SHT_SYMTAB, 2, "symbol table") \ +_ELF_DEFINE_SHT(SHT_STRTAB, 3, "string table") \ +_ELF_DEFINE_SHT(SHT_RELA, 4, \ + "relocation entries with addends") \ +_ELF_DEFINE_SHT(SHT_HASH, 5, "symbol hash table") \ +_ELF_DEFINE_SHT(SHT_DYNAMIC, 6, \ + "information for dynamic linking") \ +_ELF_DEFINE_SHT(SHT_NOTE, 7, "additional notes") \ +_ELF_DEFINE_SHT(SHT_NOBITS, 8, "section occupying no space") \ +_ELF_DEFINE_SHT(SHT_REL, 9, \ + "relocation entries without addends") \ +_ELF_DEFINE_SHT(SHT_SHLIB, 10, "reserved") \ +_ELF_DEFINE_SHT(SHT_DYNSYM, 11, "symbol table") \ +_ELF_DEFINE_SHT(SHT_INIT_ARRAY, 14, \ + "pointers to initialization functions") \ +_ELF_DEFINE_SHT(SHT_FINI_ARRAY, 15, \ + "pointers to termination functions") \ +_ELF_DEFINE_SHT(SHT_PREINIT_ARRAY, 16, \ + "pointers to functions called before initialization") \ +_ELF_DEFINE_SHT(SHT_GROUP, 17, "defines a section group") \ +_ELF_DEFINE_SHT(SHT_SYMTAB_SHNDX, 18, \ + "used for extended section numbering") \ +_ELF_DEFINE_SHT(SHT_LOOS, 0x60000000UL, \ + "start of OS-specific range") \ +_ELF_DEFINE_SHT(SHT_SUNW_dof, 0x6FFFFFF4UL, \ + "used by dtrace") \ +_ELF_DEFINE_SHT(SHT_SUNW_cap, 0x6FFFFFF5UL, \ + "capability requirements") \ +_ELF_DEFINE_SHT(SHT_GNU_ATTRIBUTES, 0x6FFFFFF5UL, \ + "object attributes") \ +_ELF_DEFINE_SHT(SHT_SUNW_SIGNATURE, 0x6FFFFFF6UL, \ + "module verification signature") \ +_ELF_DEFINE_SHT(SHT_GNU_HASH, 0x6FFFFFF6UL, \ + "GNU Hash sections") \ +_ELF_DEFINE_SHT(SHT_GNU_LIBLIST, 0x6FFFFFF7UL, \ + "List of libraries to be prelinked") \ +_ELF_DEFINE_SHT(SHT_SUNW_ANNOTATE, 0x6FFFFFF7UL, \ + "special section where unresolved references are allowed") \ +_ELF_DEFINE_SHT(SHT_SUNW_DEBUGSTR, 0x6FFFFFF8UL, \ + "debugging information") \ +_ELF_DEFINE_SHT(SHT_CHECKSUM, 0x6FFFFFF8UL, \ + "checksum for dynamic shared objects") \ +_ELF_DEFINE_SHT(SHT_SUNW_DEBUG, 0x6FFFFFF9UL, \ + "debugging information") \ +_ELF_DEFINE_SHT(SHT_SUNW_move, 0x6FFFFFFAUL, \ + "information to handle partially initialized symbols") \ +_ELF_DEFINE_SHT(SHT_SUNW_COMDAT, 0x6FFFFFFBUL, \ + "section supporting merging of multiple copies of data") \ +_ELF_DEFINE_SHT(SHT_SUNW_syminfo, 0x6FFFFFFCUL, \ + "additional symbol information") \ +_ELF_DEFINE_SHT(SHT_SUNW_verdef, 0x6FFFFFFDUL, \ + "symbol versioning information") \ +_ELF_DEFINE_SHT(SHT_SUNW_verneed, 0x6FFFFFFEUL, \ + "symbol versioning requirements") \ +_ELF_DEFINE_SHT(SHT_SUNW_versym, 0x6FFFFFFFUL, \ + "symbol versioning table") \ +_ELF_DEFINE_SHT(SHT_HIOS, 0x6FFFFFFFUL, \ + "end of OS-specific range") \ +_ELF_DEFINE_SHT(SHT_LOPROC, 0x70000000UL, \ + "start of processor-specific range") \ +_ELF_DEFINE_SHT(SHT_ARM_EXIDX, 0x70000001UL, \ + "exception index table") \ +_ELF_DEFINE_SHT(SHT_ARM_PREEMPTMAP, 0x70000002UL, \ + "BPABI DLL dynamic linking preemption map") \ +_ELF_DEFINE_SHT(SHT_ARM_ATTRIBUTES, 0x70000003UL, \ + "object file compatibility attributes") \ +_ELF_DEFINE_SHT(SHT_ARM_DEBUGOVERLAY, 0x70000004UL, \ + "overlay debug information") \ +_ELF_DEFINE_SHT(SHT_ARM_OVERLAYSECTION, 0x70000005UL, \ + "overlay debug information") \ +_ELF_DEFINE_SHT(SHT_MIPS_LIBLIST, 0x70000000UL, \ + "DSO library information used in link") \ +_ELF_DEFINE_SHT(SHT_MIPS_MSYM, 0x70000001UL, \ + "MIPS symbol table extension") \ +_ELF_DEFINE_SHT(SHT_MIPS_CONFLICT, 0x70000002UL, \ + "symbol conflicting with DSO-defined symbols ") \ +_ELF_DEFINE_SHT(SHT_MIPS_GPTAB, 0x70000003UL, \ + "global pointer table") \ +_ELF_DEFINE_SHT(SHT_MIPS_UCODE, 0x70000004UL, \ + "reserved") \ +_ELF_DEFINE_SHT(SHT_MIPS_DEBUG, 0x70000005UL, \ + "reserved (obsolete debug information)") \ +_ELF_DEFINE_SHT(SHT_MIPS_REGINFO, 0x70000006UL, \ + "register usage information") \ +_ELF_DEFINE_SHT(SHT_MIPS_PACKAGE, 0x70000007UL, \ + "OSF reserved") \ +_ELF_DEFINE_SHT(SHT_MIPS_PACKSYM, 0x70000008UL, \ + "OSF reserved") \ +_ELF_DEFINE_SHT(SHT_MIPS_RELD, 0x70000009UL, \ + "dynamic relocation") \ +_ELF_DEFINE_SHT(SHT_MIPS_IFACE, 0x7000000BUL, \ + "subprogram interface information") \ +_ELF_DEFINE_SHT(SHT_MIPS_CONTENT, 0x7000000CUL, \ + "section content classification") \ +_ELF_DEFINE_SHT(SHT_MIPS_OPTIONS, 0x7000000DUL, \ + "general options") \ +_ELF_DEFINE_SHT(SHT_MIPS_DELTASYM, 0x7000001BUL, \ + "Delta C++: symbol table") \ +_ELF_DEFINE_SHT(SHT_MIPS_DELTAINST, 0x7000001CUL, \ + "Delta C++: instance table") \ +_ELF_DEFINE_SHT(SHT_MIPS_DELTACLASS, 0x7000001DUL, \ + "Delta C++: class table") \ +_ELF_DEFINE_SHT(SHT_MIPS_DWARF, 0x7000001EUL, \ + "DWARF debug information") \ +_ELF_DEFINE_SHT(SHT_MIPS_DELTADECL, 0x7000001FUL, \ + "Delta C++: declarations") \ +_ELF_DEFINE_SHT(SHT_MIPS_SYMBOL_LIB, 0x70000020UL, \ + "symbol-to-library mapping") \ +_ELF_DEFINE_SHT(SHT_MIPS_EVENTS, 0x70000021UL, \ + "event locations") \ +_ELF_DEFINE_SHT(SHT_MIPS_TRANSLATE, 0x70000022UL, \ + "???") \ +_ELF_DEFINE_SHT(SHT_MIPS_PIXIE, 0x70000023UL, \ + "special pixie sections") \ +_ELF_DEFINE_SHT(SHT_MIPS_XLATE, 0x70000024UL, \ + "address translation table") \ +_ELF_DEFINE_SHT(SHT_MIPS_XLATE_DEBUG, 0x70000025UL, \ + "SGI internal address translation table") \ +_ELF_DEFINE_SHT(SHT_MIPS_WHIRL, 0x70000026UL, \ + "intermediate code") \ +_ELF_DEFINE_SHT(SHT_MIPS_EH_REGION, 0x70000027UL, \ + "C++ exception handling region info") \ +_ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD, 0x70000028UL, \ + "obsolete") \ +_ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, \ + "runtime procedure descriptor table exception information") \ +_ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ + "SPARC-specific data") \ +_ELF_DEFINE_SHT(SHT_AMD64_UNWIND, 0x70000001UL, \ + "unwind tables for the AMD64") \ +_ELF_DEFINE_SHT(SHT_ORDERED, 0x7FFFFFFFUL, \ + "sort entries in the section") \ +_ELF_DEFINE_SHT(SHT_HIPROC, 0x7FFFFFFFUL, \ + "end of processor-specific range") \ +_ELF_DEFINE_SHT(SHT_LOUSER, 0x80000000UL, \ + "start of application-specific range") \ +_ELF_DEFINE_SHT(SHT_HIUSER, 0xFFFFFFFFUL, \ + "end of application-specific range") + +#undef _ELF_DEFINE_SHT +#define _ELF_DEFINE_SHT(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SECTION_TYPES() + SHT__LAST__ = SHT_HIUSER +}; + +/* Aliases for section types. */ +#define SHT_GNU_verdef SHT_SUNW_verdef +#define SHT_GNU_verneed SHT_SUNW_verneed +#define SHT_GNU_versym SHT_SUNW_versym + +/* + * Symbol binding information. + */ + +#define _ELF_DEFINE_SYMBOL_BINDING() \ +_ELF_DEFINE_STB(STB_LOCAL, 0, \ + "not visible outside defining object file") \ +_ELF_DEFINE_STB(STB_GLOBAL, 1, \ + "visible across all object files being combined") \ +_ELF_DEFINE_STB(STB_WEAK, 2, \ + "visible across all object files but with low precedence") \ +_ELF_DEFINE_STB(STB_LOOS, 10, "start of OS-specific range") \ +_ELF_DEFINE_STB(STB_HIOS, 12, "end of OS-specific range") \ +_ELF_DEFINE_STB(STB_LOPROC, 13, \ + "start of processor-specific range") \ +_ELF_DEFINE_STB(STB_HIPROC, 15, \ + "end of processor-specific range") + +#undef _ELF_DEFINE_STB +#define _ELF_DEFINE_STB(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SYMBOL_BINDING() + STB__LAST__ +}; + +/* + * Symbol types + */ + +#define _ELF_DEFINE_SYMBOL_TYPES() \ +_ELF_DEFINE_STT(STT_NOTYPE, 0, "unspecified type") \ +_ELF_DEFINE_STT(STT_OBJECT, 1, "data object") \ +_ELF_DEFINE_STT(STT_FUNC, 2, "executable code") \ +_ELF_DEFINE_STT(STT_SECTION, 3, "section") \ +_ELF_DEFINE_STT(STT_FILE, 4, "source file") \ +_ELF_DEFINE_STT(STT_COMMON, 5, "uninitialized common block") \ +_ELF_DEFINE_STT(STT_TLS, 6, "thread local storage") \ +_ELF_DEFINE_STT(STT_LOOS, 10, "start of OS-specific types") \ +_ELF_DEFINE_STT(STT_HIOS, 12, "end of OS-specific types") \ +_ELF_DEFINE_STT(STT_LOPROC, 13, \ + "start of processor-specific types") \ +_ELF_DEFINE_STT(STT_ARM_TFUNC, 13, "Thumb function (GNU)") \ +_ELF_DEFINE_STT(STT_ARM_16BIT, 15, "Thumb label (GNU)") \ +_ELF_DEFINE_STT(STT_HIPROC, 15, \ + "end of processor-specific types") + +#undef _ELF_DEFINE_STT +#define _ELF_DEFINE_STT(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SYMBOL_TYPES() + STT__LAST__ +}; + +/* + * Symbol binding. + */ + +#define _ELF_DEFINE_SYMBOL_BINDING_KINDS() \ +_ELF_DEFINE_SYB(SYMINFO_BT_SELF, 0xFFFFU, \ + "bound to self") \ +_ELF_DEFINE_SYB(SYMINFO_BT_PARENT, 0xFFFEU, \ + "bound to parent") \ +_ELF_DEFINE_SYB(SYMINFO_BT_NONE, 0xFFFDU, \ + "no special binding") + +#undef _ELF_DEFINE_SYB +#define _ELF_DEFINE_SYB(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SYMBOL_BINDING_KINDS() + SYMINFO__LAST__ +}; + +/* + * Symbol visibility. + */ + +#define _ELF_DEFINE_SYMBOL_VISIBILITY() \ +_ELF_DEFINE_STV(STV_DEFAULT, 0, \ + "as specified by symbol type") \ +_ELF_DEFINE_STV(STV_INTERNAL, 1, \ + "as defined by processor semantics") \ +_ELF_DEFINE_STV(STV_HIDDEN, 2, \ + "hidden from other components") \ +_ELF_DEFINE_STV(STV_PROTECTED, 3, \ + "local references are not preemptable") + +#undef _ELF_DEFINE_STV +#define _ELF_DEFINE_STV(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SYMBOL_VISIBILITY() + STV__LAST__ +}; + +/* + * Symbol flags. + */ +#define _ELF_DEFINE_SYMBOL_FLAGS() \ +_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECT, 0x01, \ + "directly assocated reference") \ +_ELF_DEFINE_SYF(SYMINFO_FLG_COPY, 0x04, \ + "definition by copy-relocation") \ +_ELF_DEFINE_SYF(SYMINFO_FLG_LAZYLOAD, 0x08, \ + "object should be lazily loaded") \ +_ELF_DEFINE_SYF(SYMINFO_FLG_DIRECTBIND, 0x10, \ + "reference should be directly bound") \ +_ELF_DEFINE_SYF(SYMINFO_FLG_NOEXTDIRECT, 0x20, \ + "external references not allowed to bind to definition") + +#undef _ELF_DEFINE_SYF +#define _ELF_DEFINE_SYF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_SYMBOL_FLAGS() + SYMINFO_FLG__LAST__ +}; + +/* + * Version dependencies. + */ +#define _ELF_DEFINE_VERSIONING_DEPENDENCIES() \ +_ELF_DEFINE_VERD(VER_NDX_LOCAL, 0, "local scope") \ +_ELF_DEFINE_VERD(VER_NDX_GLOBAL, 1, "global scope") +#undef _ELF_DEFINE_VERD +#define _ELF_DEFINE_VERD(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_VERSIONING_DEPENDENCIES() + VER_NDX__LAST__ +}; + +/* + * Version flags. + */ +#define _ELF_DEFINE_VERSIONING_FLAGS() \ +_ELF_DEFINE_VERF(VER_FLG_BASE, 0x1, "file version") \ +_ELF_DEFINE_VERF(VER_FLG_WEAK, 0x2, "weak version") +#undef _ELF_DEFINE_VERF +#define _ELF_DEFINE_VERF(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_VERSIONING_FLAGS() + VER_FLG__LAST__ +}; + +/* + * Version needs + */ +#define _ELF_DEFINE_VERSIONING_NEEDS() \ +_ELF_DEFINE_VRN(VER_NEED_NONE, 0, "invalid version") \ +_ELF_DEFINE_VRN(VER_NEED_CURRENT, 1, "current version") +#undef _ELF_DEFINE_VRN +#define _ELF_DEFINE_VRN(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_VERSIONING_NEEDS() + VER_NEED__LAST__ +}; + +/* + * Version numbers. + */ +#define _ELF_DEFINE_VERSIONING_NUMBERS() \ +_ELF_DEFINE_VRNU(VER_DEF_NONE, 0, "invalid version") \ +_ELF_DEFINE_VRNU(VER_DEF_CURRENT, 1, "current version") +#undef _ELF_DEFINE_VRNU +#define _ELF_DEFINE_VRNU(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_VERSIONING_NUMBERS() + VER_DEF__LAST__ +}; + +/** + ** Relocation types. + **/ + +#define _ELF_DEFINE_386_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_386_NONE, 0) \ +_ELF_DEFINE_RELOC(R_386_32, 1) \ +_ELF_DEFINE_RELOC(R_386_PC32, 2) \ +_ELF_DEFINE_RELOC(R_386_GOT32, 3) \ +_ELF_DEFINE_RELOC(R_386_PLT32, 4) \ +_ELF_DEFINE_RELOC(R_386_COPY, 5) \ +_ELF_DEFINE_RELOC(R_386_GLOB_DAT, 6) \ +_ELF_DEFINE_RELOC(R_386_JMP_SLOT, 7) \ +_ELF_DEFINE_RELOC(R_386_RELATIVE, 8) \ +_ELF_DEFINE_RELOC(R_386_GOTOFF, 9) \ +_ELF_DEFINE_RELOC(R_386_GOTPC, 10) \ +_ELF_DEFINE_RELOC(R_386_32PLT, 11) \ +_ELF_DEFINE_RELOC(R_386_16, 20) \ +_ELF_DEFINE_RELOC(R_386_PC16, 21) \ +_ELF_DEFINE_RELOC(R_386_8, 22) \ +_ELF_DEFINE_RELOC(R_386_PC8, 23) + +/* + * These are the symbols used in the Sun ``Linkers and Loaders + * Guide'', Document No: 817-1984-17. See the X86_64 relocations list + * below for the spellings used in the ELF specification. + */ +#define _ELF_DEFINE_AMD64_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_AMD64_NONE, 0) \ +_ELF_DEFINE_RELOC(R_AMD64_64, 1) \ +_ELF_DEFINE_RELOC(R_AMD64_PC32, 2) \ +_ELF_DEFINE_RELOC(R_AMD64_GOT32, 3) \ +_ELF_DEFINE_RELOC(R_AMD64_PLT32, 4) \ +_ELF_DEFINE_RELOC(R_AMD64_COPY, 5) \ +_ELF_DEFINE_RELOC(R_AMD64_GLOB_DAT, 6) \ +_ELF_DEFINE_RELOC(R_AMD64_JUMP_SLOT, 7) \ +_ELF_DEFINE_RELOC(R_AMD64_RELATIVE, 8) \ +_ELF_DEFINE_RELOC(R_AMD64_GOTPCREL, 9) \ +_ELF_DEFINE_RELOC(R_AMD64_32, 10) \ +_ELF_DEFINE_RELOC(R_AMD64_32S, 11) \ +_ELF_DEFINE_RELOC(R_AMD64_16, 12) \ +_ELF_DEFINE_RELOC(R_AMD64_PC16, 13) \ +_ELF_DEFINE_RELOC(R_AMD64_8, 14) \ +_ELF_DEFINE_RELOC(R_AMD64_PC8, 15) \ +_ELF_DEFINE_RELOC(R_AMD64_PC64, 24) \ +_ELF_DEFINE_RELOC(R_AMD64_GOTOFF64, 25) \ +_ELF_DEFINE_RELOC(R_AMD64_GOTPC32, 26) + +/* + * Relocation definitions from the ARM ELF ABI, version "ARM IHI + * 0044E" released on 30th November 2012. + */ +#define _ELF_DEFINE_ARM_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_ARM_NONE, 0) \ +_ELF_DEFINE_RELOC(R_ARM_PC24, 1) \ +_ELF_DEFINE_RELOC(R_ARM_ABS32, 2) \ +_ELF_DEFINE_RELOC(R_ARM_REL32, 3) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G0, 4) \ +_ELF_DEFINE_RELOC(R_ARM_ABS16, 5) \ +_ELF_DEFINE_RELOC(R_ARM_ABS12, 6) \ +_ELF_DEFINE_RELOC(R_ARM_THM_ABS5, 7) \ +_ELF_DEFINE_RELOC(R_ARM_ABS8, 8) \ +_ELF_DEFINE_RELOC(R_ARM_SBREL32, 9) \ +_ELF_DEFINE_RELOC(R_ARM_THM_CALL, 10) \ +_ELF_DEFINE_RELOC(R_ARM_THM_PC8, 11) \ +_ELF_DEFINE_RELOC(R_ARM_BREL_ADJ, 12) \ +_ELF_DEFINE_RELOC(R_ARM_SWI24, 13) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_DESC, 13) \ +_ELF_DEFINE_RELOC(R_ARM_THM_SWI8, 14) \ +_ELF_DEFINE_RELOC(R_ARM_XPC25, 15) \ +_ELF_DEFINE_RELOC(R_ARM_THM_XPC22, 16) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_DTPMOD32, 17) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_DTPOFF32, 18) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_TPOFF32, 19) \ +_ELF_DEFINE_RELOC(R_ARM_COPY, 20) \ +_ELF_DEFINE_RELOC(R_ARM_GLOB_DAT, 21) \ +_ELF_DEFINE_RELOC(R_ARM_JUMP_SLOT, 22) \ +_ELF_DEFINE_RELOC(R_ARM_RELATIVE, 23) \ +_ELF_DEFINE_RELOC(R_ARM_GOTOFF32, 24) \ +_ELF_DEFINE_RELOC(R_ARM_BASE_PREL, 25) \ +_ELF_DEFINE_RELOC(R_ARM_GOT_BREL, 26) \ +_ELF_DEFINE_RELOC(R_ARM_PLT32, 27) \ +_ELF_DEFINE_RELOC(R_ARM_CALL, 28) \ +_ELF_DEFINE_RELOC(R_ARM_JUMP24, 29) \ +_ELF_DEFINE_RELOC(R_ARM_THM_JUMP24, 30) \ +_ELF_DEFINE_RELOC(R_ARM_BASE_ABS, 31) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL_7_0, 32) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL_15_8, 33) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PCREL_23_15, 34) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_SBREL_11_0_NC, 35) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_19_12_NC, 36) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_27_20_CK, 37) \ +_ELF_DEFINE_RELOC(R_ARM_TARGET1, 38) \ +_ELF_DEFINE_RELOC(R_ARM_SBREL31, 39) \ +_ELF_DEFINE_RELOC(R_ARM_V4BX, 40) \ +_ELF_DEFINE_RELOC(R_ARM_TARGET2, 41) \ +_ELF_DEFINE_RELOC(R_ARM_PREL31, 42) \ +_ELF_DEFINE_RELOC(R_ARM_MOVW_ABS_NC, 43) \ +_ELF_DEFINE_RELOC(R_ARM_MOVT_ABS, 44) \ +_ELF_DEFINE_RELOC(R_ARM_MOVW_PREL_NC, 45) \ +_ELF_DEFINE_RELOC(R_ARM_MOVT_PREL, 46) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_ABS_NC, 47) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_ABS, 48) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_PREL_NC, 49) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_PREL, 50) \ +_ELF_DEFINE_RELOC(R_ARM_THM_JUMP19, 51) \ +_ELF_DEFINE_RELOC(R_ARM_THM_JUMP6, 52) \ +_ELF_DEFINE_RELOC(R_ARM_THM_ALU_PREL_11_0, 53) \ +_ELF_DEFINE_RELOC(R_ARM_THM_PC12, 54) \ +_ELF_DEFINE_RELOC(R_ARM_ABS32_NOI, 55) \ +_ELF_DEFINE_RELOC(R_ARM_REL32_NOI, 56) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0_NC, 57) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G0, 58) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1_NC, 59) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G1, 60) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_PC_G2, 61) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G1, 62) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_PC_G2, 63) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G0, 64) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G1, 65) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_PC_G2, 66) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G0, 67) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G1, 68) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_PC_G2, 69) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0_NC, 70) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G0, 71) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1_NC, 72) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G1, 73) \ +_ELF_DEFINE_RELOC(R_ARM_ALU_SB_G2, 74) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G0, 75) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G1, 76) \ +_ELF_DEFINE_RELOC(R_ARM_LDR_SB_G2, 77) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G0, 78) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G1, 79) \ +_ELF_DEFINE_RELOC(R_ARM_LDRS_SB_G2, 80) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G0, 81) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G1, 82) \ +_ELF_DEFINE_RELOC(R_ARM_LDC_SB_G2, 83) \ +_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL_NC, 84) \ +_ELF_DEFINE_RELOC(R_ARM_MOVT_BREL, 85) \ +_ELF_DEFINE_RELOC(R_ARM_MOVW_BREL, 86) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL_NC, 87) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVT_BREL, 88) \ +_ELF_DEFINE_RELOC(R_ARM_THM_MOVW_BREL, 89) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_GOTDESC, 90) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_CALL, 91) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_DESCSEQ, 92) \ +_ELF_DEFINE_RELOC(R_ARM_THM_TLS_CALL, 93) \ +_ELF_DEFINE_RELOC(R_ARM_PLT32_ABS, 94) \ +_ELF_DEFINE_RELOC(R_ARM_GOT_ABS, 95) \ +_ELF_DEFINE_RELOC(R_ARM_GOT_PREL, 96) \ +_ELF_DEFINE_RELOC(R_ARM_GOT_BREL12, 97) \ +_ELF_DEFINE_RELOC(R_ARM_GOTOFF12, 98) \ +_ELF_DEFINE_RELOC(R_ARM_GOTRELAX, 99) \ +_ELF_DEFINE_RELOC(R_ARM_GNU_VTENTRY, 100) \ +_ELF_DEFINE_RELOC(R_ARM_GNU_VTINHERIT, 101) \ +_ELF_DEFINE_RELOC(R_ARM_THM_JUMP11, 102) \ +_ELF_DEFINE_RELOC(R_ARM_THM_JUMP8, 103) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_GD32, 104) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_LDM32, 105) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_LDO32, 106) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_IE32, 107) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_LE32, 108) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_LDO12, 109) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_LE12, 110) \ +_ELF_DEFINE_RELOC(R_ARM_TLS_IE12GP, 111) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_0, 112) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_1, 113) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_2, 114) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_3, 115) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_4, 116) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_5, 117) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_6, 118) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_7, 119) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_8, 120) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_9, 121) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_10, 122) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_11, 123) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_12, 124) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_13, 125) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_14, 126) \ +_ELF_DEFINE_RELOC(R_ARM_PRIVATE_15, 127) \ +_ELF_DEFINE_RELOC(R_ARM_ME_TOO, 128) \ +_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ16, 129) \ +_ELF_DEFINE_RELOC(R_ARM_THM_TLS_DESCSEQ32, 130) \ +_ELF_DEFINE_RELOC(R_ARM_THM_GOT_BREL12, 131) \ +_ELF_DEFINE_RELOC(R_ARM_IRELATIVE, 140) + +#define _ELF_DEFINE_IA64_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_IA_64_NONE, 0) \ +_ELF_DEFINE_RELOC(R_IA_64_IMM14, 0x21) \ +_ELF_DEFINE_RELOC(R_IA_64_IMM22, 0x22) \ +_ELF_DEFINE_RELOC(R_IA_64_IMM64, 0x23) \ +_ELF_DEFINE_RELOC(R_IA_64_DIR32MSB, 0x24) \ +_ELF_DEFINE_RELOC(R_IA_64_DIR32LSB, 0x25) \ +_ELF_DEFINE_RELOC(R_IA_64_DIR64MSB, 0x26) \ +_ELF_DEFINE_RELOC(R_IA_64_DIR64LSB, 0x27) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL22, 0x2a) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL64I, 0x2b) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL32MSB, 0x2c) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL32LSB, 0x2d) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL64MSB, 0x2e) \ +_ELF_DEFINE_RELOC(R_IA_64_GPREL64LSB, 0x2f) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF22, 0x32) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF64I, 0x33) \ +_ELF_DEFINE_RELOC(R_IA_64_PLTOFF22, 0x3a) \ +_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64I, 0x3b) \ +_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64MSB, 0x3e) \ +_ELF_DEFINE_RELOC(R_IA_64_PLTOFF64LSB, 0x3f) \ +_ELF_DEFINE_RELOC(R_IA_64_FPTR64I, 0x43) \ +_ELF_DEFINE_RELOC(R_IA_64_FPTR32MSB, 0x44) \ +_ELF_DEFINE_RELOC(R_IA_64_FPTR32LSB, 0x45) \ +_ELF_DEFINE_RELOC(R_IA_64_FPTR64MSB, 0x46) \ +_ELF_DEFINE_RELOC(R_IA_64_FPTR64LSB, 0x47) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL60B, 0x48) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL21B, 0x49) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL21M, 0x4a) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL21F, 0x4b) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL32MSB, 0x4c) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL32LSB, 0x4d) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL64MSB, 0x4e) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL64LSB, 0x4f) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR22, 0x52) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64I, 0x53) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32MSB, 0x54) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR32LSB, 0x55) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64MSB, 0x56) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_FPTR64LSB, 0x57) \ +_ELF_DEFINE_RELOC(R_IA_64_SEGREL32MSB, 0x5c) \ +_ELF_DEFINE_RELOC(R_IA_64_SEGREL32LSB, 0x5d) \ +_ELF_DEFINE_RELOC(R_IA_64_SEGREL64MSB, 0x5e) \ +_ELF_DEFINE_RELOC(R_IA_64_SEGREL64LSB, 0x5f) \ +_ELF_DEFINE_RELOC(R_IA_64_SECREL32MSB, 0x64) \ +_ELF_DEFINE_RELOC(R_IA_64_SECREL32LSB, 0x65) \ +_ELF_DEFINE_RELOC(R_IA_64_SECREL64MSB, 0x66) \ +_ELF_DEFINE_RELOC(R_IA_64_SECREL64LSB, 0x67) \ +_ELF_DEFINE_RELOC(R_IA_64_REL32MSB, 0x6c) \ +_ELF_DEFINE_RELOC(R_IA_64_REL32LSB, 0x6d) \ +_ELF_DEFINE_RELOC(R_IA_64_REL64MSB, 0x6e) \ +_ELF_DEFINE_RELOC(R_IA_64_REL64LSB, 0x6f) \ +_ELF_DEFINE_RELOC(R_IA_64_LTV32MSB, 0x74) \ +_ELF_DEFINE_RELOC(R_IA_64_LTV32LSB, 0x75) \ +_ELF_DEFINE_RELOC(R_IA_64_LTV64MSB, 0x76) \ +_ELF_DEFINE_RELOC(R_IA_64_LTV64LSB, 0x77) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL21BIa, 0x79) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL22, 0x7A) \ +_ELF_DEFINE_RELOC(R_IA_64_PCREL64I, 0x7B) \ +_ELF_DEFINE_RELOC(R_IA_64_IPLTMSB, 0x80) \ +_ELF_DEFINE_RELOC(R_IA_64_IPLTLSB, 0x81) \ +_ELF_DEFINE_RELOC(R_IA_64_SUB, 0x85) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF22X, 0x86) \ +_ELF_DEFINE_RELOC(R_IA_64_LDXMOV, 0x87) \ +_ELF_DEFINE_RELOC(R_IA_64_TPREL14, 0x91) \ +_ELF_DEFINE_RELOC(R_IA_64_TPREL22, 0x92) \ +_ELF_DEFINE_RELOC(R_IA_64_TPREL64I, 0x93) \ +_ELF_DEFINE_RELOC(R_IA_64_TPREL64MSB, 0x96) \ +_ELF_DEFINE_RELOC(R_IA_64_TPREL64LSB, 0x97) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_TPREL22, 0x9A) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64MSB, 0xA6) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPMOD64LSB, 0xA7) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPMOD22, 0xAA) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL14, 0xB1) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL22, 0xB2) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL64I, 0xB3) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL32MSB, 0xB4) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL32LSB, 0xB5) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL64MSB, 0xB6) \ +_ELF_DEFINE_RELOC(R_IA_64_DTPREL64LSB, 0xB7) \ +_ELF_DEFINE_RELOC(R_IA_64_LTOFF_DTPREL22, 0xBA) + +#define _ELF_DEFINE_MIPS_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_MIPS_NONE, 0) \ +_ELF_DEFINE_RELOC(R_MIPS_16, 1) \ +_ELF_DEFINE_RELOC(R_MIPS_32, 2) \ +_ELF_DEFINE_RELOC(R_MIPS_REL32, 3) \ +_ELF_DEFINE_RELOC(R_MIPS_26, 4) \ +_ELF_DEFINE_RELOC(R_MIPS_HI16, 5) \ +_ELF_DEFINE_RELOC(R_MIPS_LO16, 6) \ +_ELF_DEFINE_RELOC(R_MIPS_GPREL16, 7) \ +_ELF_DEFINE_RELOC(R_MIPS_LITERAL, 8) \ +_ELF_DEFINE_RELOC(R_MIPS_GOT16, 9) \ +_ELF_DEFINE_RELOC(R_MIPS_PC16, 10) \ +_ELF_DEFINE_RELOC(R_MIPS_CALL16, 11) \ +_ELF_DEFINE_RELOC(R_MIPS_GPREL32, 12) \ +_ELF_DEFINE_RELOC(R_MIPS_64, 18) \ +_ELF_DEFINE_RELOC(R_MIPS_GOTHI16, 21) \ +_ELF_DEFINE_RELOC(R_MIPS_GOTLO16, 22) \ +_ELF_DEFINE_RELOC(R_MIPS_CALLHI16, 30) \ +_ELF_DEFINE_RELOC(R_MIPS_CALLLO16, 31) + +#define _ELF_DEFINE_PPC32_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_PPC_NONE, 0) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR32, 1) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR24, 2) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR16, 3) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR16_LO, 4) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR16_HI, 5) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR16_HA, 6) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR14, 7) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRTAKEN, 8) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR14_BRNTAKEN, 9) \ +_ELF_DEFINE_RELOC(R_PPC_REL24, 10) \ +_ELF_DEFINE_RELOC(R_PPC_REL14, 11) \ +_ELF_DEFINE_RELOC(R_PPC_REL14_BRTAKEN, 12) \ +_ELF_DEFINE_RELOC(R_PPC_REL14_BRNTAKEN, 13) \ +_ELF_DEFINE_RELOC(R_PPC_GOT16, 14) \ +_ELF_DEFINE_RELOC(R_PPC_GOT16_LO, 15) \ +_ELF_DEFINE_RELOC(R_PPC_GOT16_HI, 16) \ +_ELF_DEFINE_RELOC(R_PPC_GOT16_HA, 17) \ +_ELF_DEFINE_RELOC(R_PPC_PLTREL24, 18) \ +_ELF_DEFINE_RELOC(R_PPC_COPY, 19) \ +_ELF_DEFINE_RELOC(R_PPC_GLOB_DAT, 20) \ +_ELF_DEFINE_RELOC(R_PPC_JMP_SLOT, 21) \ +_ELF_DEFINE_RELOC(R_PPC_RELATIVE, 22) \ +_ELF_DEFINE_RELOC(R_PPC_LOCAL24PC, 23) \ +_ELF_DEFINE_RELOC(R_PPC_UADDR32, 24) \ +_ELF_DEFINE_RELOC(R_PPC_UADDR16, 25) \ +_ELF_DEFINE_RELOC(R_PPC_REL32, 26) \ +_ELF_DEFINE_RELOC(R_PPC_PLT32, 27) \ +_ELF_DEFINE_RELOC(R_PPC_PLTREL32, 28) \ +_ELF_DEFINE_RELOC(R_PPC_PLT16_LO, 29) \ +_ELF_DEFINE_RELOC(R_PPL_PLT16_HI, 30) \ +_ELF_DEFINE_RELOC(R_PPC_PLT16_HA, 31) \ +_ELF_DEFINE_RELOC(R_PPC_SDAREL16, 32) \ +_ELF_DEFINE_RELOC(R_PPC_SECTOFF, 33) \ +_ELF_DEFINE_RELOC(R_PPC_SECTOFF_LO, 34) \ +_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HI, 35) \ +_ELF_DEFINE_RELOC(R_PPC_SECTOFF_HA, 36) \ +_ELF_DEFINE_RELOC(R_PPC_ADDR30, 37) \ +_ELF_DEFINE_RELOC(R_PPC_TLS, 67) \ +_ELF_DEFINE_RELOC(R_PPC_DTPMOD32, 68) \ +_ELF_DEFINE_RELOC(R_PPC_TPREL16, 69) \ +_ELF_DEFINE_RELOC(R_PPC_TPREL16_LO, 70) \ +_ELF_DEFINE_RELOC(R_PPC_TPREL16_HI, 71) \ +_ELF_DEFINE_RELOC(R_PPC_TPREL16_HA, 72) \ +_ELF_DEFINE_RELOC(R_PPC_TPREL32, 73) \ +_ELF_DEFINE_RELOC(R_PPC_DTPREL16, 74) \ +_ELF_DEFINE_RELOC(R_PPC_DTPREL16_LO, 75) \ +_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HI, 76) \ +_ELF_DEFINE_RELOC(R_PPC_DTPREL16_HA, 77) \ +_ELF_DEFINE_RELOC(R_PPC_DTPREL32, 78) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16, 79) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_LO, 80) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HI, 81) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSGD16_HA, 82) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16, 83) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_LO, 84) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HI, 85) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TLSLD16_HA, 86) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16, 87) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_LO, 88) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HI, 89) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_TPREL16_HA, 90) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16, 91) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_LO, 92) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HI, 93) \ +_ELF_DEFINE_RELOC(R_PPC_GOT_DTPREL16_HA, 94) \ +_ELF_DEFINE_RELOC(R_PPC_TLSGD, 95) \ +_ELF_DEFINE_RELOC(R_PPC_TLSLD, 96) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR32, 101) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16, 102) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_LO, 103) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HI, 104) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_NADDR16_HA, 105) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_SDAI16, 106) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2I16, 107) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_SDA2REL, 108) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_SDA21, 109) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_MRKREF, 110) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_RELSEC16, 111) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_LO, 112) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HI, 113) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_RELST_HA, 114) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_BIT_FLD, 115) \ +_ELF_DEFINE_RELOC(R_PPC_EMB_RELSDA, 116) \ + +#define _ELF_DEFINE_PPC64_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_PPC64_NONE, 0) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR32, 1) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR24, 2) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16, 3) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO, 4) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HI, 5) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HA, 6) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR14, 7) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRTAKEN, 8) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR14_BRNTAKEN, 9) \ +_ELF_DEFINE_RELOC(R_PPC64_REL24, 10) \ +_ELF_DEFINE_RELOC(R_PPC64_REL14, 11) \ +_ELF_DEFINE_RELOC(R_PPC64_REL14_BRTAKEN, 12) \ +_ELF_DEFINE_RELOC(R_PPC64_REL14_BRNTAKEN, 13) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16, 14) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO, 15) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16_HI, 16) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16_HA, 17) \ +_ELF_DEFINE_RELOC(R_PPC64_COPY, 19) \ +_ELF_DEFINE_RELOC(R_PPC64_GLOB_DAT, 20) \ +_ELF_DEFINE_RELOC(R_PPC64_JMP_SLOT, 21) \ +_ELF_DEFINE_RELOC(R_PPC64_RELATIVE, 22) \ +_ELF_DEFINE_RELOC(R_PPC64_UADDR32, 24) \ +_ELF_DEFINE_RELOC(R_PPC64_UADDR16, 25) \ +_ELF_DEFINE_RELOC(R_PPC64_REL32, 26) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT32, 27) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTREL32, 28) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO, 29) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT16_HI, 30) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT16_HA, 31) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF, 33) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO, 34) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HI, 35) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_HA, 36) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR30, 37) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR64, 38) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHER, 39) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHERA, 40) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHEST, 41) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_HIGHESTA, 42) \ +_ELF_DEFINE_RELOC(R_PPC64_UADDR64, 43) \ +_ELF_DEFINE_RELOC(R_PPC64_REL64, 44) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT64, 45) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTREL64, 46) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16, 47) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO, 48) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16_HI, 49) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16_HA, 50) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC, 51) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16, 52) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO, 53) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HI, 54) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_HA, 55) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_DS, 56) \ +_ELF_DEFINE_RELOC(R_PPC64_ADDR16_LO_DS, 57) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16_DS, 58) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT16_LO_DS, 59) \ +_ELF_DEFINE_RELOC(R_PPC64_PLT16_LO_DS, 60) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_DS, 61) \ +_ELF_DEFINE_RELOC(R_PPC64_SECTOFF_LO_DS, 62) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16_DS, 63) \ +_ELF_DEFINE_RELOC(R_PPC64_TOC16_LO_DS, 64) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_DS, 65) \ +_ELF_DEFINE_RELOC(R_PPC64_PLTGOT16_LO_DS, 66) \ +_ELF_DEFINE_RELOC(R_PPC64_TLS, 67) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPMOD64, 68) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16, 69) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO, 60) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HI, 71) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HA, 72) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL64, 73) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16, 74) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO, 75) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HI, 76) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HA, 77) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL64, 78) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16, 79) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_LO, 80) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HI, 81) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSGD16_HA, 82) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16, 83) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_LO, 84) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HI, 85) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TLSLD16_HA, 86) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_DS, 87) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_LO_DS, 88) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HI, 89) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_TPREL16_HA, 90) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_DS, 91) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_LO_DS, 92) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HI, 93) \ +_ELF_DEFINE_RELOC(R_PPC64_GOT_DTPREL16_HA, 94) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_DS, 95) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_LO_DS, 96) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHER, 97) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHERA, 98) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHEST, 99) \ +_ELF_DEFINE_RELOC(R_PPC64_TPREL16_HIGHESTA, 100) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_DS, 101) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_LO_DS, 102) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHER, 103) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHERA, 104) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHEST, 105) \ +_ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) \ +_ELF_DEFINE_RELOC(R_PPC64_TLSGD, 107) \ +_ELF_DEFINE_RELOC(R_PPC64_TLSLD, 108) + +#define _ELF_DEFINE_SPARC_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_SPARC_NONE, 0) \ +_ELF_DEFINE_RELOC(R_SPARC_8, 1) \ +_ELF_DEFINE_RELOC(R_SPARC_16, 2) \ +_ELF_DEFINE_RELOC(R_SPARC_32, 3) \ +_ELF_DEFINE_RELOC(R_SPARC_DISP8, 4) \ +_ELF_DEFINE_RELOC(R_SPARC_DISP16, 5) \ +_ELF_DEFINE_RELOC(R_SPARC_DISP32, 6) \ +_ELF_DEFINE_RELOC(R_SPARC_WDISP30, 7) \ +_ELF_DEFINE_RELOC(R_SPARC_WDISP22, 8) \ +_ELF_DEFINE_RELOC(R_SPARC_HI22, 9) \ +_ELF_DEFINE_RELOC(R_SPARC_22, 10) \ +_ELF_DEFINE_RELOC(R_SPARC_13, 11) \ +_ELF_DEFINE_RELOC(R_SPARC_LO10, 12) \ +_ELF_DEFINE_RELOC(R_SPARC_GOT10, 13) \ +_ELF_DEFINE_RELOC(R_SPARC_GOT13, 14) \ +_ELF_DEFINE_RELOC(R_SPARC_GOT22, 15) \ +_ELF_DEFINE_RELOC(R_SPARC_PC10, 16) \ +_ELF_DEFINE_RELOC(R_SPARC_PC22, 17) \ +_ELF_DEFINE_RELOC(R_SPARC_WPLT30, 18) \ +_ELF_DEFINE_RELOC(R_SPARC_COPY, 19) \ +_ELF_DEFINE_RELOC(R_SPARC_GLOB_DAT, 20) \ +_ELF_DEFINE_RELOC(R_SPARC_JMP_SLOT, 21) \ +_ELF_DEFINE_RELOC(R_SPARC_RELATIVE, 22) \ +_ELF_DEFINE_RELOC(R_SPARC_UA32, 23) \ +_ELF_DEFINE_RELOC(R_SPARC_PLT32, 24) \ +_ELF_DEFINE_RELOC(R_SPARC_HIPLT22, 25) \ +_ELF_DEFINE_RELOC(R_SPARC_LOPLT10, 26) \ +_ELF_DEFINE_RELOC(R_SPARC_PCPLT32, 27) \ +_ELF_DEFINE_RELOC(R_SPARC_PCPLT22, 28) \ +_ELF_DEFINE_RELOC(R_SPARC_PCPLT10, 29) \ +_ELF_DEFINE_RELOC(R_SPARC_10, 30) \ +_ELF_DEFINE_RELOC(R_SPARC_11, 31) \ +_ELF_DEFINE_RELOC(R_SPARC_64, 32) \ +_ELF_DEFINE_RELOC(R_SPARC_OLO10, 33) \ +_ELF_DEFINE_RELOC(R_SPARC_HH22, 34) \ +_ELF_DEFINE_RELOC(R_SPARC_HM10, 35) \ +_ELF_DEFINE_RELOC(R_SPARC_LM22, 36) \ +_ELF_DEFINE_RELOC(R_SPARC_PC_HH22, 37) \ +_ELF_DEFINE_RELOC(R_SPARC_PC_HM10, 38) \ +_ELF_DEFINE_RELOC(R_SPARC_PC_LM22, 39) \ +_ELF_DEFINE_RELOC(R_SPARC_WDISP16, 40) \ +_ELF_DEFINE_RELOC(R_SPARC_WDISP19, 41) \ +_ELF_DEFINE_RELOC(R_SPARC_7, 43) \ +_ELF_DEFINE_RELOC(R_SPARC_5, 44) \ +_ELF_DEFINE_RELOC(R_SPARC_6, 45) \ +_ELF_DEFINE_RELOC(R_SPARC_DISP64, 46) \ +_ELF_DEFINE_RELOC(R_SPARC_PLT64, 47) \ +_ELF_DEFINE_RELOC(R_SPARC_HIX22, 48) \ +_ELF_DEFINE_RELOC(R_SPARC_LOX10, 49) \ +_ELF_DEFINE_RELOC(R_SPARC_H44, 50) \ +_ELF_DEFINE_RELOC(R_SPARC_M44, 51) \ +_ELF_DEFINE_RELOC(R_SPARC_L44, 52) \ +_ELF_DEFINE_RELOC(R_SPARC_REGISTER, 53) \ +_ELF_DEFINE_RELOC(R_SPARC_UA64, 54) \ +_ELF_DEFINE_RELOC(R_SPARC_UA16, 55) \ +_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_HIX22, 80) \ +_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_LOX10, 81) \ +_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82) \ +_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83) \ +_ELF_DEFINE_RELOC(R_SPARC_GOTDATA_OP, 84) \ +_ELF_DEFINE_RELOC(R_SPARC_H34, 85) + +#define _ELF_DEFINE_X86_64_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_X86_64_NONE, 0) \ +_ELF_DEFINE_RELOC(R_X86_64_64, 1) \ +_ELF_DEFINE_RELOC(R_X86_64_PC32, 2) \ +_ELF_DEFINE_RELOC(R_X86_64_GOT32, 3) \ +_ELF_DEFINE_RELOC(R_X86_64_PLT32, 4) \ +_ELF_DEFINE_RELOC(R_X86_64_COPY, 5) \ +_ELF_DEFINE_RELOC(R_X86_64_GLOB_DAT, 6) \ +_ELF_DEFINE_RELOC(R_X86_64_JUMP_SLOT, 7) \ +_ELF_DEFINE_RELOC(R_X86_64_RELATIVE, 8) \ +_ELF_DEFINE_RELOC(R_X86_64_GOTPCREL, 9) \ +_ELF_DEFINE_RELOC(R_X86_64_32, 10) \ +_ELF_DEFINE_RELOC(R_X86_64_32S, 11) \ +_ELF_DEFINE_RELOC(R_X86_64_16, 12) \ +_ELF_DEFINE_RELOC(R_X86_64_PC16, 13) \ +_ELF_DEFINE_RELOC(R_X86_64_8, 14) \ +_ELF_DEFINE_RELOC(R_X86_64_PC8, 15) \ +_ELF_DEFINE_RELOC(R_X86_64_DTPMOD64, 16) \ +_ELF_DEFINE_RELOC(R_X86_64_DTPOFF64, 17) \ +_ELF_DEFINE_RELOC(R_X86_64_TPOFF64, 18) \ +_ELF_DEFINE_RELOC(R_X86_64_TLSGD, 19) \ +_ELF_DEFINE_RELOC(R_X86_64_TLSLD, 20) \ +_ELF_DEFINE_RELOC(R_X86_64_DTPOFF32, 21) \ +_ELF_DEFINE_RELOC(R_X86_64_GOTTPOFF, 22) \ +_ELF_DEFINE_RELOC(R_X86_64_TPOFF32, 23) \ +_ELF_DEFINE_RELOC(R_X86_64_PC64, 24) \ +_ELF_DEFINE_RELOC(R_X86_64_GOTOFF64, 25) \ +_ELF_DEFINE_RELOC(R_X86_64_GOTPC32, 26) \ +_ELF_DEFINE_RELOC(R_X86_64_SIZE32, 32) \ +_ELF_DEFINE_RELOC(R_X86_64_SIZE64, 33) \ +_ELF_DEFINE_RELOC(R_X86_64_GOTPC32_TLSDESC, 34) \ +_ELF_DEFINE_RELOC(R_X86_64_TLSDESC_CALL, 35) \ +_ELF_DEFINE_RELOC(R_X86_64_TLSDESC, 36) + +#define _ELF_DEFINE_RELOCATIONS() \ +_ELF_DEFINE_386_RELOCATIONS() \ +_ELF_DEFINE_AMD64_RELOCATIONS() \ +_ELF_DEFINE_ARM_RELOCATIONS() \ +_ELF_DEFINE_IA64_RELOCATIONS() \ +_ELF_DEFINE_MIPS_RELOCATIONS() \ +_ELF_DEFINE_PPC32_RELOCATIONS() \ +_ELF_DEFINE_PPC64_RELOCATIONS() \ +_ELF_DEFINE_SPARC_RELOCATIONS() \ +_ELF_DEFINE_X86_64_RELOCATIONS() + +#undef _ELF_DEFINE_RELOC +#define _ELF_DEFINE_RELOC(N, V) N = V , +enum { + _ELF_DEFINE_RELOCATIONS() + R__LAST__ +}; + +#define PN_XNUM 0xFFFFU /* Use extended section numbering. */ + +/** + ** ELF Types. + **/ + +typedef uint32_t Elf32_Addr; /* Program address. */ +typedef uint8_t Elf32_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer. */ +typedef uint32_t Elf32_Off; /* File offset. */ +typedef uint16_t Elf32_Section; /* Section index. */ +typedef int32_t Elf32_Sword; /* Signed integer. */ +typedef uint32_t Elf32_Word; /* Unsigned integer. */ +typedef uint64_t Elf32_Lword; /* Unsigned long integer. */ + +typedef uint64_t Elf64_Addr; /* Program address. */ +typedef uint8_t Elf64_Byte; /* Unsigned tiny integer. */ +typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ +typedef uint64_t Elf64_Off; /* File offset. */ +typedef uint16_t Elf64_Section; /* Section index. */ +typedef int32_t Elf64_Sword; /* Signed integer. */ +typedef uint32_t Elf64_Word; /* Unsigned integer. */ +typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ +typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ +typedef int64_t Elf64_Sxword; /* Signed long integer. */ + + +/* + * Capability descriptors. + */ + +/* 32-bit capability descriptor. */ +typedef struct { + Elf32_Word c_tag; /* Type of entry. */ + union { + Elf32_Word c_val; /* Integer value. */ + Elf32_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf32_Cap; + +/* 64-bit capability descriptor. */ +typedef struct { + Elf64_Xword c_tag; /* Type of entry. */ + union { + Elf64_Xword c_val; /* Integer value. */ + Elf64_Addr c_ptr; /* Pointer value. */ + } c_un; +} Elf64_Cap; + +/* + * MIPS .conflict section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Addr c_index; +} Elf32_Conflict; + +/* 64-bit entry. */ +typedef struct { + Elf64_Addr c_index; +} Elf64_Conflict; + +/* + * Dynamic section entries. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Sword d_tag; /* Type of entry. */ + union { + Elf32_Word d_val; /* Integer value. */ + Elf32_Addr d_ptr; /* Pointer value. */ + } d_un; +} Elf32_Dyn; + +/* 64-bit entry. */ +typedef struct { + Elf64_Sxword d_tag; /* Type of entry. */ + union { + Elf64_Xword d_val; /* Integer value. */ + Elf64_Addr d_ptr; /* Pointer value; */ + } d_un; +} Elf64_Dyn; + + +/* + * The executable header (EHDR). + */ + +/* 32 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf32_Half e_type; /* Object file type (ET_*). */ + Elf32_Half e_machine; /* Machine type (EM_*). */ + Elf32_Word e_version; /* File format version (EV_*). */ + Elf32_Addr e_entry; /* Start address. */ + Elf32_Off e_phoff; /* File offset to the PHDR table. */ + Elf32_Off e_shoff; /* File offset to the SHDRheader. */ + Elf32_Word e_flags; /* Flags (EF_*). */ + Elf32_Half e_ehsize; /* Elf header size in bytes. */ + Elf32_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf32_Half e_phnum; /* Number of PHDR entries. */ + Elf32_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf32_Half e_shnum; /* Number of SHDR entries. */ + Elf32_Half e_shstrndx; /* Index of section name string table. */ +} Elf32_Ehdr; + + +/* 64 bit EHDR. */ +typedef struct { + unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ + Elf64_Half e_type; /* Object file type (ET_*). */ + Elf64_Half e_machine; /* Machine type (EM_*). */ + Elf64_Word e_version; /* File format version (EV_*). */ + Elf64_Addr e_entry; /* Start address. */ + Elf64_Off e_phoff; /* File offset to the PHDR table. */ + Elf64_Off e_shoff; /* File offset to the SHDRheader. */ + Elf64_Word e_flags; /* Flags (EF_*). */ + Elf64_Half e_ehsize; /* Elf header size in bytes. */ + Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ + Elf64_Half e_phnum; /* Number of PHDR entries. */ + Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ + Elf64_Half e_shnum; /* Number of SHDR entries. */ + Elf64_Half e_shstrndx; /* Index of section name string table. */ +} Elf64_Ehdr; + + +/* + * Shared object information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Word l_name; /* The name of a shared object. */ + Elf32_Word l_time_stamp; /* 32-bit timestamp. */ + Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf32_Word l_version; /* Interface version string index. */ + Elf32_Word l_flags; /* Flags (LL_*). */ +} Elf32_Lib; + +/* 64-bit entry. */ +typedef struct { + Elf64_Word l_name; + Elf64_Word l_time_stamp; + Elf64_Word l_checksum; + Elf64_Word l_version; + Elf64_Word l_flags; +} Elf64_Lib; + +#define _ELF_DEFINE_LL_FLAGS() \ +_ELF_DEFINE_LL(LL_NONE, 0, \ + "no flags") \ +_ELF_DEFINE_LL(LL_EXACT_MATCH, 0x1, \ + "require an exact match") \ +_ELF_DEFINE_LL(LL_IGNORE_INT_VER, 0x2, \ + "ignore version incompatibilities") \ +_ELF_DEFINE_LL(LL_REQUIRE_MINOR, 0x4, \ + "") \ +_ELF_DEFINE_LL(LL_EXPORTS, 0x8, \ + "") \ +_ELF_DEFINE_LL(LL_DELAY_LOAD, 0x10, \ + "") \ +_ELF_DEFINE_LL(LL_DELTA, 0x20, \ + "") + +#undef _ELF_DEFINE_LL +#define _ELF_DEFINE_LL(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_LL_FLAGS() + LL__LAST__ +}; + +/* + * Note tags + */ + +#define _ELF_DEFINE_NOTE_ENTRY_TYPES() \ +_ELF_DEFINE_NT(NT_ABI_TAG, 1, "Tag indicating the ABI") \ +_ELF_DEFINE_NT(NT_GNU_HWCAP, 2, "Hardware capabilities") \ +_ELF_DEFINE_NT(NT_GNU_BUILD_ID, 3, "Build id, set by ld(1)") \ +_ELF_DEFINE_NT(NT_GNU_GOLD_VERSION, 4, \ + "Version number of the GNU gold linker") \ +_ELF_DEFINE_NT(NT_PRSTATUS, 1, "Process status") \ +_ELF_DEFINE_NT(NT_FPREGSET, 2, "Floating point information") \ +_ELF_DEFINE_NT(NT_PRPSINFO, 3, "Process information") \ +_ELF_DEFINE_NT(NT_AUXV, 6, "Auxiliary vector") \ +_ELF_DEFINE_NT(NT_PRXFPREG, 0x46E62B7FUL, \ + "Linux user_xfpregs structure") \ +_ELF_DEFINE_NT(NT_PSTATUS, 10, "Linux process status") \ +_ELF_DEFINE_NT(NT_FPREGS, 12, "Linux floating point regset") \ +_ELF_DEFINE_NT(NT_PSINFO, 13, "Linux process information") \ +_ELF_DEFINE_NT(NT_LWPSTATUS, 16, "Linux lwpstatus_t type") \ +_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type") + +#undef _ELF_DEFINE_NT +#define _ELF_DEFINE_NT(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_NOTE_ENTRY_TYPES() + NT__LAST__ +}; + +/* Aliases for the ABI tag. */ +#define NT_FREEBSD_ABI_TAG NT_ABI_TAG +#define NT_GNU_ABI_TAG NT_ABI_TAG +#define NT_NETBSD_IDENT NT_ABI_TAG +#define NT_OPENBSD_IDENT NT_ABI_TAG + +/* + * Note descriptors. + */ + +typedef struct { + uint32_t n_namesz; /* Length of note's name. */ + uint32_t n_descsz; /* Length of note's value. */ + uint32_t n_type; /* Type of note. */ +} Elf_Note; + +typedef Elf_Note Elf32_Nhdr; /* 32-bit note header. */ +typedef Elf_Note Elf64_Nhdr; /* 64-bit note header. */ + +/* + * MIPS ELF options descriptor header. + */ + +typedef struct { + Elf64_Byte kind; /* Type of options. */ + Elf64_Byte size; /* Size of option descriptor. */ + Elf64_Half section; /* Index of section affected. */ + Elf64_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* + * Option kinds. + */ + +#define _ELF_DEFINE_OPTION_KINDS() \ +_ELF_DEFINE_ODK(ODK_NULL, 0, "undefined") \ +_ELF_DEFINE_ODK(ODK_REGINFO, 1, "register usage info") \ +_ELF_DEFINE_ODK(ODK_EXCEPTIONS, 2, "exception processing info") \ +_ELF_DEFINE_ODK(ODK_PAD, 3, "section padding") \ +_ELF_DEFINE_ODK(ODK_HWPATCH, 4, "hardware patch applied") \ +_ELF_DEFINE_ODK(ODK_FILL, 5, "fill value used by linker") \ +_ELF_DEFINE_ODK(ODK_TAGS, 6, "reserved space for tools") \ +_ELF_DEFINE_ODK(ODK_HWAND, 7, "hardware AND patch applied") \ +_ELF_DEFINE_ODK(ODK_HWOR, 8, "hardware OR patch applied") \ +_ELF_DEFINE_ODK(ODK_GP_GROUP, 9, \ + "GP group to use for text/data sections") \ +_ELF_DEFINE_ODK(ODK_IDENT, 10, "ID information") \ +_ELF_DEFINE_ODK(ODK_PAGESIZE, 11, "page size infomation") + +#undef _ELF_DEFINE_ODK +#define _ELF_DEFINE_ODK(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_OPTION_KINDS() + ODK__LAST__ +}; + +/* + * ODK_EXCEPTIONS info field masks. + */ + +#define _ELF_DEFINE_ODK_EXCEPTIONS_MASK() \ +_ELF_DEFINE_OEX(OEX_FPU_MIN, 0x0000001FUL, \ + "minimum FPU exception which must be enabled") \ +_ELF_DEFINE_OEX(OEX_FPU_MAX, 0x00001F00UL, \ + "maximum FPU exception which can be enabled") \ +_ELF_DEFINE_OEX(OEX_PAGE0, 0x00010000UL, \ + "page zero must be mapped") \ +_ELF_DEFINE_OEX(OEX_SMM, 0x00020000UL, \ + "run in sequential memory mode") \ +_ELF_DEFINE_OEX(OEX_PRECISEFP, 0x00040000UL, \ + "run in precise FP exception mode") \ +_ELF_DEFINE_OEX(OEX_DISMISS, 0x00080000UL, \ + "dismiss invalid address traps") + +#undef _ELF_DEFINE_OEX +#define _ELF_DEFINE_OEX(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ODK_EXCEPTIONS_MASK() + OEX__LAST__ +}; + +/* + * ODK_PAD info field masks. + */ + +#define _ELF_DEFINE_ODK_PAD_MASK() \ +_ELF_DEFINE_OPAD(OPAD_PREFIX, 0x0001) \ +_ELF_DEFINE_OPAD(OPAD_POSTFIX, 0x0002) \ +_ELF_DEFINE_OPAD(OPAD_SYMBOL, 0x0004) + +#undef _ELF_DEFINE_OPAD +#define _ELF_DEFINE_OPAD(N, V) N = V , +enum { + _ELF_DEFINE_ODK_PAD_MASK() + OPAD__LAST__ +}; + +/* + * ODK_HWPATCH info field masks. + */ + +#define _ELF_DEFINE_ODK_HWPATCH_MASK() \ +_ELF_DEFINE_OHW(OHW_R4KEOP, 0x00000001UL, \ + "patch for R4000 branch at end-of-page bug") \ +_ELF_DEFINE_OHW(OHW_R8KPFETCH, 0x00000002UL, \ + "R8000 prefetch bug may occur") \ +_ELF_DEFINE_OHW(OHW_R5KEOP, 0x00000004UL, \ + "patch for R5000 branch at end-of-page bug") \ +_ELF_DEFINE_OHW(OHW_R5KCVTL, 0x00000008UL, \ + "R5000 cvt.[ds].l bug: clean == 1") \ +_ELF_DEFINE_OHW(OHW_R10KLDL, 0x00000010UL, \ + "needd patch for R10000 misaligned load") + +#undef _ELF_DEFINE_OHW +#define _ELF_DEFINE_OHW(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ODK_HWPATCH_MASK() + OHW__LAST__ +}; + +/* + * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks. + */ + +#define _ELF_DEFINE_ODK_HWP_MASK() \ +_ELF_DEFINE_HWP(OHWA0_R4KEOP_CHECKED, 0x00000001UL, \ + "object checked for R4000 end-of-page bug") \ +_ELF_DEFINE_HWP(OHWA0_R4KEOP_CLEAN, 0x00000002UL, \ + "object verified clean for R4000 end-of-page bug") \ +_ELF_DEFINE_HWP(OHWO0_FIXADE, 0x00000001UL, \ + "object requires call to fixade") + +#undef _ELF_DEFINE_HWP +#define _ELF_DEFINE_HWP(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ODK_HWP_MASK() + OHWX0__LAST__ +}; + +/* + * ODK_IDENT/ODK_GP_GROUP info field masks. + */ + +#define _ELF_DEFINE_ODK_GP_MASK() \ +_ELF_DEFINE_OGP(OGP_GROUP, 0x0000FFFFUL, "GP group number") \ +_ELF_DEFINE_OGP(OGP_SELF, 0x00010000UL, \ + "GP group is self-contained") + +#undef _ELF_DEFINE_OGP +#define _ELF_DEFINE_OGP(N, V, DESCR) N = V , +enum { + _ELF_DEFINE_ODK_GP_MASK() + OGP__LAST__ +}; + +/* + * MIPS ELF register info descriptor. + */ + +/* 32 bit RegInfo entry. */ +typedef struct { + Elf32_Word ri_gprmask; /* Mask of general register used. */ + Elf32_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf32_Addr ri_gp_value; /* GP register value. */ +} Elf32_RegInfo; + +/* 64 bit RegInfo entry. */ +typedef struct { + Elf64_Word ri_gprmask; /* Mask of general register used. */ + Elf64_Word ri_pad; /* Padding. */ + Elf64_Word ri_cprmask[4]; /* Mask of coprocessor register used. */ + Elf64_Addr ri_gp_value; /* GP register value. */ +} Elf64_RegInfo; + +/* + * Program Header Table (PHDR) entries. + */ + +/* 32 bit PHDR entry. */ +typedef struct { + Elf32_Word p_type; /* Type of segment. */ + Elf32_Off p_offset; /* File offset to segment. */ + Elf32_Addr p_vaddr; /* Virtual address in memory. */ + Elf32_Addr p_paddr; /* Physical address (if relevant). */ + Elf32_Word p_filesz; /* Size of segment in file. */ + Elf32_Word p_memsz; /* Size of segment in memory. */ + Elf32_Word p_flags; /* Segment flags. */ + Elf32_Word p_align; /* Alignment constraints. */ +} Elf32_Phdr; + +/* 64 bit PHDR entry. */ +typedef struct { + Elf64_Word p_type; /* Type of segment. */ + Elf64_Word p_flags; /* File offset to segment. */ + Elf64_Off p_offset; /* Virtual address in memory. */ + Elf64_Addr p_vaddr; /* Physical address (if relevant). */ + Elf64_Addr p_paddr; /* Size of segment in file. */ + Elf64_Xword p_filesz; /* Size of segment in memory. */ + Elf64_Xword p_memsz; /* Segment flags. */ + Elf64_Xword p_align; /* Alignment constraints. */ +} Elf64_Phdr; + + +/* + * Move entries, for describing data in COMMON blocks in a compact + * manner. + */ + +/* 32-bit move entry. */ +typedef struct { + Elf32_Lword m_value; /* Initialization value. */ + Elf32_Word m_info; /* Encoded size and index. */ + Elf32_Word m_poffset; /* Offset relative to symbol. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Number of units to skip. */ +} Elf32_Move; + +/* 64-bit move entry. */ +typedef struct { + Elf64_Lword m_value; /* Initialization value. */ + Elf64_Xword m_info; /* Encoded size and index. */ + Elf64_Xword m_poffset; /* Offset relative to symbol. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Number of units to skip. */ +} Elf64_Move; + +#define ELF32_M_SYM(I) ((I) >> 8) +#define ELF32_M_SIZE(I) ((unsigned char) (I)) +#define ELF32_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +#define ELF64_M_SYM(I) ((I) >> 8) +#define ELF64_M_SIZE(I) ((unsigned char) (I)) +#define ELF64_M_INFO(M, S) (((M) << 8) + (unsigned char) (S)) + +/* + * Section Header Table (SHDR) entries. + */ + +/* 32 bit SHDR */ +typedef struct { + Elf32_Word sh_name; /* index of section name */ + Elf32_Word sh_type; /* section type */ + Elf32_Word sh_flags; /* section flags */ + Elf32_Addr sh_addr; /* in-memory address of section */ + Elf32_Off sh_offset; /* file offset of section */ + Elf32_Word sh_size; /* section size in bytes */ + Elf32_Word sh_link; /* section header table link */ + Elf32_Word sh_info; /* extra information */ + Elf32_Word sh_addralign; /* alignment constraint */ + Elf32_Word sh_entsize; /* size for fixed-size entries */ +} Elf32_Shdr; + +/* 64 bit SHDR */ +typedef struct { + Elf64_Word sh_name; /* index of section name */ + Elf64_Word sh_type; /* section type */ + Elf64_Xword sh_flags; /* section flags */ + Elf64_Addr sh_addr; /* in-memory address of section */ + Elf64_Off sh_offset; /* file offset of section */ + Elf64_Xword sh_size; /* section size in bytes */ + Elf64_Word sh_link; /* section header table link */ + Elf64_Word sh_info; /* extra information */ + Elf64_Xword sh_addralign; /* alignment constraint */ + Elf64_Xword sh_entsize; /* size for fixed-size entries */ +} Elf64_Shdr; + + +/* + * Symbol table entries. + */ + +typedef struct { + Elf32_Word st_name; /* index of symbol's name */ + Elf32_Addr st_value; /* value for the symbol */ + Elf32_Word st_size; /* size of associated data */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf32_Half st_shndx; /* index of related section */ +} Elf32_Sym; + +typedef struct { + Elf64_Word st_name; /* index of symbol's name */ + unsigned char st_info; /* value for the symbol */ + unsigned char st_other; /* size of associated data */ + Elf64_Half st_shndx; /* type and binding attributes */ + Elf64_Addr st_value; /* visibility */ + Elf64_Xword st_size; /* index of related section */ +} Elf64_Sym; + +#define ELF32_ST_BIND(I) ((I) >> 4) +#define ELF32_ST_TYPE(I) ((I) & 0xFU) +#define ELF32_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF64_ST_BIND(I) ((I) >> 4) +#define ELF64_ST_TYPE(I) ((I) & 0xFU) +#define ELF64_ST_INFO(B,T) (((B) << 4) + ((T) & 0xF)) + +#define ELF32_ST_VISIBILITY(O) ((O) & 0x3) +#define ELF64_ST_VISIBILITY(O) ((O) & 0x3) + +/* + * Syminfo descriptors, containing additional symbol information. + */ + +/* 32-bit entry. */ +typedef struct { + Elf32_Half si_boundto; /* Entry index with additional flags. */ + Elf32_Half si_flags; /* Flags. */ +} Elf32_Syminfo; + +/* 64-bit entry. */ +typedef struct { + Elf64_Half si_boundto; /* Entry index with additional flags. */ + Elf64_Half si_flags; /* Flags. */ +} Elf64_Syminfo; + +/* + * Relocation descriptors. + */ + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ +} Elf32_Rel; + +typedef struct { + Elf32_Addr r_offset; /* location to apply relocation to */ + Elf32_Word r_info; /* type+section for relocation */ + Elf32_Sword r_addend; /* constant addend */ +} Elf32_Rela; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ +} Elf64_Rel; + +typedef struct { + Elf64_Addr r_offset; /* location to apply relocation to */ + Elf64_Xword r_info; /* type+section for relocation */ + Elf64_Sxword r_addend; /* constant addend */ +} Elf64_Rela; + + +#define ELF32_R_SYM(I) ((I) >> 8) +#define ELF32_R_TYPE(I) ((unsigned char) (I)) +#define ELF32_R_INFO(S,T) (((S) << 8) + (unsigned char) (T)) + +#define ELF64_R_SYM(I) ((I) >> 32) +#define ELF64_R_TYPE(I) ((I) & 0xFFFFFFFFUL) +#define ELF64_R_INFO(S,T) (((S) << 32) + ((T) & 0xFFFFFFFFUL)) + +/* + * Symbol versioning structures. + */ + +/* 32-bit structures. */ +typedef struct +{ + Elf32_Word vda_name; /* Index to name. */ + Elf32_Word vda_next; /* Offset to next entry. */ +} Elf32_Verdaux; + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name. */ + Elf32_Half vna_flags; /* Flags. */ + Elf32_Half vna_other; /* Unused. */ + Elf32_Word vna_name; /* Offset to dependency name. */ + Elf32_Word vna_next; /* Offset to next vernaux entry. */ +} Elf32_Vernaux; + +typedef struct +{ + Elf32_Half vd_version; /* Version information. */ + Elf32_Half vd_flags; /* Flags. */ + Elf32_Half vd_ndx; /* Index into the versym section. */ + Elf32_Half vd_cnt; /* Number of aux entries. */ + Elf32_Word vd_hash; /* Hash value of name. */ + Elf32_Word vd_aux; /* Offset to aux entries. */ + Elf32_Word vd_next; /* Offset to next version definition. */ +} Elf32_Verdef; + +typedef struct +{ + Elf32_Half vn_version; /* Version number. */ + Elf32_Half vn_cnt; /* Number of aux entries. */ + Elf32_Word vn_file; /* Offset of associated file name. */ + Elf32_Word vn_aux; /* Offset of vernaux array. */ + Elf32_Word vn_next; /* Offset of next verneed entry. */ +} Elf32_Verneed; + +typedef Elf32_Half Elf32_Versym; + +/* 64-bit structures. */ + +typedef struct { + Elf64_Word vda_name; /* Index to name. */ + Elf64_Word vda_next; /* Offset to next entry. */ +} Elf64_Verdaux; + +typedef struct { + Elf64_Word vna_hash; /* Hash value of dependency name. */ + Elf64_Half vna_flags; /* Flags. */ + Elf64_Half vna_other; /* Unused. */ + Elf64_Word vna_name; /* Offset to dependency name. */ + Elf64_Word vna_next; /* Offset to next vernaux entry. */ +} Elf64_Vernaux; + +typedef struct { + Elf64_Half vd_version; /* Version information. */ + Elf64_Half vd_flags; /* Flags. */ + Elf64_Half vd_ndx; /* Index into the versym section. */ + Elf64_Half vd_cnt; /* Number of aux entries. */ + Elf64_Word vd_hash; /* Hash value of name. */ + Elf64_Word vd_aux; /* Offset to aux entries. */ + Elf64_Word vd_next; /* Offset to next version definition. */ +} Elf64_Verdef; + +typedef struct { + Elf64_Half vn_version; /* Version number. */ + Elf64_Half vn_cnt; /* Number of aux entries. */ + Elf64_Word vn_file; /* Offset of associated file name. */ + Elf64_Word vn_aux; /* Offset of vernaux array. */ + Elf64_Word vn_next; /* Offset of next verneed entry. */ +} Elf64_Verneed; + +typedef Elf64_Half Elf64_Versym; + + +/* + * The header for GNU-style hash sections. + */ + +typedef struct { + uint32_t gh_nbuckets; /* Number of hash buckets. */ + uint32_t gh_symndx; /* First visible symbol in .dynsym. */ + uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ + uint32_t gh_shift2; /* Bloom filter shift count. */ +} Elf_GNU_Hash_Header; + +#endif /* _ELFDEFINITIONS_H_ */ diff --git a/contrib/elftoolchain/common/native-elf-format b/contrib/elftoolchain/common/native-elf-format new file mode 100755 index 0000000..af70759 --- /dev/null +++ b/contrib/elftoolchain/common/native-elf-format @@ -0,0 +1,47 @@ +#!/bin/sh +# +# $Id: native-elf-format 2064 2011-10-26 15:12:32Z jkoshy $ +# +# Find the native ELF format for a host platform by compiling a +# test object and examining the resulting object. +# +# This script is used if there is no easy way to determine this +# information statically at compile time. + +program=`basename $0` +tmp_c=`mktemp -u nefXXXXXX`.c +tmp_o=`echo ${tmp_c} | sed -e 's/.c$/.o/'` + +trap "rm -f ${tmp_c} ${tmp_o}" 0 1 2 3 15 + +touch ${tmp_c} + +echo "/* Generated by ${program} on `date` */" + +cc -c ${tmp_c} -o ${tmp_o} +readelf -h ${tmp_o} | awk ' +$1 ~ "Class:" { + sub("ELF","",$2); elfclass = $2; + } +$1 ~ "Data:" { + if (match($0, "little")) { + elfdata = "LSB"; + } else { + elfdata = "MSB"; + } + } +$1 ~ "Machine:" { + if (match($0, "Intel.*386")) { + elfarch = "EM_386"; + } else if (match($0, ".*X86-64")) { + elfarch = "EM_X86_64"; + } else { + elfarch = "unknown"; + } + } +END { + printf("#define ELFTC_CLASS ELFCLASS%s\n", elfclass); + printf("#define ELFTC_ARCH %s\n", elfarch); + printf("#define ELFTC_BYTEORDER ELFDATA2%s\n", elfdata); +}' + diff --git a/contrib/elftoolchain/common/os.Linux.mk b/contrib/elftoolchain/common/os.Linux.mk new file mode 100644 index 0000000..2339e2a --- /dev/null +++ b/contrib/elftoolchain/common/os.Linux.mk @@ -0,0 +1,13 @@ +# +# Build recipes for Linux based operating systems. +# +# $Id: os.Linux.mk 2064 2011-10-26 15:12:32Z jkoshy $ + +_NATIVE_ELF_FORMAT = native-elf-format + +.BEGIN: ${_NATIVE_ELF_FORMAT}.h + +${_NATIVE_ELF_FORMAT}.h: + ${.CURDIR}/${_NATIVE_ELF_FORMAT} > ${.TARGET} || rm ${.TARGET} + +CLEANFILES += ${_NATIVE_ELF_FORMAT}.h diff --git a/contrib/elftoolchain/common/utarray.h b/contrib/elftoolchain/common/utarray.h new file mode 100644 index 0000000..090e354 --- /dev/null +++ b/contrib/elftoolchain/common/utarray.h @@ -0,0 +1,237 @@ +/* +Copyright (c) 2008-2013, Troy D. Hanson http://uthash.sourceforge.net +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. + +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 OWNER +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. +*/ + +/* $Id: utarray.h 2694 2012-11-24 17:11:58Z kaiwang27 $ */ + +/* a dynamic array implementation using macros + * see http://uthash.sourceforge.net/utarray + */ +#ifndef UTARRAY_H +#define UTARRAY_H + +#define UTARRAY_VERSION 1.9.7 + +#ifdef __GNUC__ +#define _UNUSED_ __attribute__ ((__unused__)) +#else +#define _UNUSED_ +#endif + +#include <stddef.h> /* size_t */ +#include <string.h> /* memset, etc */ +#include <stdlib.h> /* exit */ + +#ifndef oom +#define oom() exit(-1) +#endif + +typedef void (ctor_f)(void *dst, const void *src); +typedef void (dtor_f)(void *elt); +typedef void (init_f)(void *elt); +typedef struct { + size_t sz; + init_f *init; + ctor_f *copy; + dtor_f *dtor; +} UT_icd; + +typedef struct { + unsigned i,n;/* i: index of next available slot, n: num slots */ + UT_icd icd; /* initializer, copy and destructor functions */ + char *d; /* n slots of size icd->sz*/ +} UT_array; + +#define utarray_init(a,_icd) do { \ + memset(a,0,sizeof(UT_array)); \ + (a)->icd=*_icd; \ +} while(0) + +#define utarray_done(a) do { \ + if ((a)->n) { \ + if ((a)->icd.dtor) { \ + size_t _ut_i; \ + for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ + } \ + } \ + free((a)->d); \ + } \ + (a)->n=0; \ +} while(0) + +#define utarray_new(a,_icd) do { \ + a=(UT_array*)malloc(sizeof(UT_array)); \ + utarray_init(a,_icd); \ +} while(0) + +#define utarray_free(a) do { \ + utarray_done(a); \ + free(a); \ +} while(0) + +#define utarray_reserve(a,by) do { \ + if (((a)->i+by) > ((a)->n)) { \ + while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ + if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd.sz)) == NULL) oom(); \ + } \ +} while(0) + +#define utarray_push_back(a,p) do { \ + utarray_reserve(a,1); \ + if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); } \ + else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); }; \ +} while(0) + +#define utarray_pop_back(a) do { \ + if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); } \ + else { (a)->i--; } \ +} while(0) + +#define utarray_extend_back(a) do { \ + utarray_reserve(a,1); \ + if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); } \ + else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); } \ + (a)->i++; \ +} while(0) + +#define utarray_len(a) ((a)->i) + +#define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) +#define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd.sz*(j) ))) + +#define utarray_insert(a,p,j) do { \ + utarray_reserve(a,1); \ + if (j > (a)->i) break; \ + if ((j) < (a)->i) { \ + memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ + ((a)->i - (j))*((a)->icd.sz)); \ + } \ + if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); } \ + else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); }; \ + (a)->i++; \ +} while(0) + +#define utarray_inserta(a,w,j) do { \ + if (utarray_len(w) == 0) break; \ + if (j > (a)->i) break; \ + utarray_reserve(a,utarray_len(w)); \ + if ((j) < (a)->i) { \ + memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ + _utarray_eltptr(a,j), \ + ((a)->i - (j))*((a)->icd.sz)); \ + } \ + if ((a)->icd.copy) { \ + size_t _ut_i; \ + for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ + (a)->icd.copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i)); \ + } \ + } else { \ + memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ + utarray_len(w)*((a)->icd.sz)); \ + } \ + (a)->i += utarray_len(w); \ +} while(0) + +#define utarray_resize(dst,num) do { \ + size_t _ut_i; \ + if (dst->i > (size_t)(num)) { \ + if ((dst)->icd.dtor) { \ + for(_ut_i=num; _ut_i < dst->i; _ut_i++) { \ + (dst)->icd.dtor(utarray_eltptr(dst,_ut_i)); \ + } \ + } \ + } else if (dst->i < (size_t)(num)) { \ + utarray_reserve(dst,num-dst->i); \ + if ((dst)->icd.init) { \ + for(_ut_i=dst->i; _ut_i < num; _ut_i++) { \ + (dst)->icd.init(utarray_eltptr(dst,_ut_i)); \ + } \ + } else { \ + memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd.sz*(num-dst->i)); \ + } \ + } \ + dst->i = num; \ +} while(0) + +#define utarray_concat(dst,src) do { \ + utarray_inserta((dst),(src),utarray_len(dst)); \ +} while(0) + +#define utarray_erase(a,pos,len) do { \ + if ((a)->icd.dtor) { \ + size_t _ut_i; \ + for(_ut_i=0; _ut_i < len; _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr((a),pos+_ut_i)); \ + } \ + } \ + if ((a)->i > (pos+len)) { \ + memmove( _utarray_eltptr((a),pos), _utarray_eltptr((a),pos+len), \ + (((a)->i)-(pos+len))*((a)->icd.sz)); \ + } \ + (a)->i -= (len); \ +} while(0) + +#define utarray_renew(a,u) do { \ + if (a) utarray_clear(a); \ + else utarray_new((a),(u)); \ +} while(0) + +#define utarray_clear(a) do { \ + if ((a)->i > 0) { \ + if ((a)->icd.dtor) { \ + size_t _ut_i; \ + for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ + (a)->icd.dtor(utarray_eltptr(a,_ut_i)); \ + } \ + } \ + (a)->i = 0; \ + } \ +} while(0) + +#define utarray_sort(a,cmp) do { \ + qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \ +} while(0) + +#define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp) + +#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) +#define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : (((int)((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) +#define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL)) +#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) +#define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (int)(((char*)(e) - (char*)((a)->d))/(a)->icd.sz) : -1) + +/* last we pre-define a few icd for common utarrays of ints and strings */ +static void utarray_str_cpy(void *dst, const void *src) { + char *const*_src = (char*const*)src, **_dst = (char**)dst; + *_dst = (*_src == NULL) ? NULL : strdup(*_src); +} +static void utarray_str_dtor(void *elt) { + char **eltc = (char**)elt; + if (*eltc) free(*eltc); +} +static const UT_icd ut_str_icd _UNUSED_ = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; +static const UT_icd ut_int_icd _UNUSED_ = {sizeof(int),NULL,NULL,NULL}; +static const UT_icd ut_ptr_icd _UNUSED_ = {sizeof(void*),NULL,NULL,NULL}; + + +#endif /* UTARRAY_H */ diff --git a/contrib/elftoolchain/common/uthash.h b/contrib/elftoolchain/common/uthash.h new file mode 100644 index 0000000..79e1e71 --- /dev/null +++ b/contrib/elftoolchain/common/uthash.h @@ -0,0 +1,919 @@ +/* +Copyright (c) 2003-2013, Troy D. Hanson http://uthash.sourceforge.net +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. + +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 OWNER +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. +*/ + +/* $Id: uthash.h 2682 2012-11-23 22:04:22Z kaiwang27 $ */ + +#ifndef UTHASH_H +#define UTHASH_H + +#include <string.h> /* memcmp,strlen */ +#include <stddef.h> /* ptrdiff_t */ +#include <stdlib.h> /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on win32 */ +#ifdef _MSC_VER +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#else +#include <inttypes.h> /* uint32_t */ +#endif + +#define UTHASH_VERSION 1.9.7 + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_bkt,_hf_hashv; \ + out=NULL; \ + if (head) { \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)keyptr; \ + (add)->hh.keylen = (unsigned)keylen_in; \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + unsigned _hd_bkt; \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield,strlen(add->strfield),add) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + unsigned _bkt_i; \ + unsigned _count, _bkt_count; \ + char *_prev; \ + struct UT_hash_handle *_thh; \ + if (head) { \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %d, actual %d\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include <unistd.h> to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6 */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) + +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) \ + hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + char *_hj_key=(char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = (unsigned)keylen; \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + char *_sfh_key=(char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if ((out)->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + _hs_tail->next = NULL; \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/contrib/elftoolchain/libdwarf/Makefile b/contrib/elftoolchain/libdwarf/Makefile new file mode 100644 index 0000000..81b5657 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/Makefile @@ -0,0 +1,324 @@ +# $Id: Makefile 2937 2013-04-27 04:48:23Z jkoshy $ + +TOP= ${.CURDIR}/.. + +LIB= dwarf + +SRCS= \ + dwarf_abbrev.c \ + dwarf_arange.c \ + dwarf_attr.c \ + dwarf_attrval.c \ + dwarf_cu.c \ + dwarf_dealloc.c \ + dwarf_die.c \ + dwarf_dump.c \ + dwarf_errmsg.c \ + dwarf_finish.c \ + dwarf_form.c \ + dwarf_frame.c \ + dwarf_funcs.c \ + dwarf_init.c \ + dwarf_lineno.c \ + dwarf_loclist.c \ + dwarf_macinfo.c \ + dwarf_pro_arange.c \ + dwarf_pro_attr.c \ + dwarf_pro_die.c \ + dwarf_pro_expr.c \ + dwarf_pro_finish.c \ + dwarf_pro_frame.c \ + dwarf_pro_funcs.c \ + dwarf_pro_init.c \ + dwarf_pro_lineno.c \ + dwarf_pro_macinfo.c \ + dwarf_pro_pubnames.c \ + dwarf_pro_reloc.c \ + dwarf_pro_sections.c \ + dwarf_pro_types.c \ + dwarf_pro_vars.c \ + dwarf_pro_weaks.c \ + dwarf_pubnames.c \ + dwarf_pubtypes.c \ + dwarf_ranges.c \ + dwarf_reloc.c \ + dwarf_seterror.c \ + dwarf_str.c \ + dwarf_types.c \ + dwarf_vars.c \ + dwarf_weaks.c \ + libdwarf.c \ + libdwarf_abbrev.c \ + libdwarf_arange.c \ + libdwarf_attr.c \ + libdwarf_die.c \ + libdwarf_error.c \ + libdwarf_elf_access.c \ + libdwarf_elf_init.c \ + libdwarf_frame.c \ + libdwarf_info.c \ + libdwarf_init.c \ + libdwarf_lineno.c \ + libdwarf_loc.c \ + libdwarf_loclist.c \ + libdwarf_macinfo.c \ + libdwarf_nametbl.c \ + libdwarf_ranges.c \ + libdwarf_reloc.c \ + libdwarf_rw.c \ + libdwarf_sections.c \ + libdwarf_str.c + +INCS= dwarf.h libdwarf.h +INCSDIR= /usr/include + +GENSRCS= dwarf_pubnames.c dwarf_pubtypes.c dwarf_weaks.c \ + dwarf_funcs.c dwarf_vars.c dwarf_types.c \ + dwarf_pro_pubnames.c dwarf_pro_weaks.c \ + dwarf_pro_funcs.c dwarf_pro_types.c \ + dwarf_pro_vars.c +CLEANFILES= ${GENSRCS} + +SHLIB_MAJOR= 3 + +WARNS?= 6 + +LDADD+= -lelf + +MAN= dwarf.3 \ + dwarf_add_arange.3 \ + dwarf_add_AT_comp_dir.3 \ + dwarf_add_AT_const_value_string.3 \ + dwarf_add_AT_dataref.3 \ + dwarf_add_AT_flag.3 \ + dwarf_add_AT_location_expr.3 \ + dwarf_add_AT_name.3 \ + dwarf_add_AT_producer.3 \ + dwarf_add_AT_ref_address.3 \ + dwarf_add_AT_reference.3 \ + dwarf_add_AT_signed_const.3 \ + dwarf_add_AT_string.3 \ + dwarf_add_AT_targ_address.3 \ + dwarf_add_die_to_debug.3 \ + dwarf_add_directory_decl.3 \ + dwarf_add_expr_addr.3 \ + dwarf_add_expr_gen.3 \ + dwarf_add_fde_inst.3 \ + dwarf_add_file_decl.3 \ + dwarf_add_frame_cie.3 \ + dwarf_add_frame_fde.3 \ + dwarf_add_funcname.3 \ + dwarf_add_line_entry.3 \ + dwarf_add_pubname.3 \ + dwarf_add_typename.3 \ + dwarf_add_varname.3 \ + dwarf_add_weakname.3 \ + dwarf_attr.3 \ + dwarf_attrlist.3 \ + dwarf_attrval_signed.3 \ + dwarf_child.3 \ + dwarf_dealloc.3 \ + dwarf_def_macro.3 \ + dwarf_die_abbrev_code.3 \ + dwarf_die_link.3 \ + dwarf_diename.3 \ + dwarf_dieoffset.3 \ + dwarf_end_macro_file.3 \ + dwarf_errmsg.3 \ + dwarf_errno.3 \ + dwarf_expand_frame_instructions.3 \ + dwarf_expr_current_offset.3 \ + dwarf_expr_into_block.3 \ + dwarf_fde_cfa_offset.3 \ + dwarf_find_macro_value_start.3 \ + dwarf_finish.3 \ + dwarf_formaddr.3 \ + dwarf_formblock.3 \ + dwarf_formexprloc.3 \ + dwarf_formflag.3 \ + dwarf_formref.3 \ + dwarf_formsig8.3 \ + dwarf_formstring.3 \ + dwarf_formudata.3 \ + dwarf_get_abbrev.3 \ + dwarf_get_abbrev_children_flag.3 \ + dwarf_get_abbrev_code.3 \ + dwarf_get_abbrev_entry.3 \ + dwarf_get_abbrev_tag.3 \ + dwarf_get_address_size.3 \ + dwarf_get_arange.3 \ + dwarf_get_arange_info.3 \ + dwarf_get_aranges.3 \ + dwarf_get_AT_name.3 \ + dwarf_get_cie_index.3 \ + dwarf_get_cie_info.3 \ + dwarf_get_cie_of_fde.3 \ + dwarf_get_cu_die_offset.3 \ + dwarf_get_elf.3 \ + dwarf_get_fde_at_pc.3 \ + dwarf_get_fde_info_for_all_regs.3 \ + dwarf_get_fde_info_for_all_regs3.3 \ + dwarf_get_fde_info_for_cfa_reg3.3 \ + dwarf_get_fde_info_for_reg.3 \ + dwarf_get_fde_info_for_reg3.3 \ + dwarf_get_fde_instr_bytes.3 \ + dwarf_get_fde_list.3 \ + dwarf_get_fde_n.3 \ + dwarf_get_fde_range.3 \ + dwarf_get_form_class.3 \ + dwarf_get_funcs.3 \ + dwarf_get_globals.3 \ + dwarf_get_loclist_entry.3 \ + dwarf_get_macro_details.3 \ + dwarf_get_pubtypes.3 \ + dwarf_get_ranges.3 \ + dwarf_get_relocation_info.3 \ + dwarf_get_relocation_info_count.3 \ + dwarf_get_section_bytes.3 \ + dwarf_get_str.3 \ + dwarf_get_types.3 \ + dwarf_get_vars.3 \ + dwarf_get_weaks.3 \ + dwarf_hasattr.3 \ + dwarf_hasform.3 \ + dwarf_highpc.3 \ + dwarf_init.3 \ + dwarf_lineno.3 \ + dwarf_lne_end_sequence.3 \ + dwarf_lne_set_address.3 \ + dwarf_loclist.3 \ + dwarf_loclist_from_expr.3 \ + dwarf_new_die.3 \ + dwarf_new_expr.3 \ + dwarf_new_fde.3 \ + dwarf_next_cu_header.3 \ + dwarf_object_init.3 \ + dwarf_producer_init.3 \ + dwarf_producer_set_isa.3 \ + dwarf_reset_section_bytes.3 \ + dwarf_seterrarg.3 \ + dwarf_set_frame_cfa_value.3 \ + dwarf_set_reloc_application.3 \ + dwarf_srcfiles.3 \ + dwarf_srclines.3 \ + dwarf_start_macro_file.3 \ + dwarf_tag.3 \ + dwarf_transform_to_disk_form.3 \ + dwarf_undef_macro.3 \ + dwarf_vendor_ext.3 \ + dwarf_whatattr.3 + +MLINKS+= \ + dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_signedint.3 \ + dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_unsignedint.3 \ + dwarf_add_AT_signed_const.3 dwarf_add_AT_unsigned_const.3 \ + dwarf_add_AT_targ_address.3 dwarf_add_AT_targ_address_b.3 \ + dwarf_add_arange.3 dwarf_add_arange_b.3 \ + dwarf_add_expr_addr.3 dwarf_add_expr_addr_b.3 \ + dwarf_add_frame_fde.3 dwarf_add_frame_fde_b.3 \ + dwarf_attrval_signed.3 dwarf_attrval_flag.3 \ + dwarf_attrval_signed.3 dwarf_attrval_string.3 \ + dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \ + dwarf_child.3 dwarf_offdie.3 \ + dwarf_child.3 dwarf_siblingof.3 \ + dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \ + dwarf_dealloc.3 dwarf_funcs_dealloc.3 \ + dwarf_dealloc.3 dwarf_globals_dealloc.3 \ + dwarf_dealloc.3 dwarf_pubtypes_dealloc.3 \ + dwarf_dealloc.3 dwarf_types_dealloc.3 \ + dwarf_dealloc.3 dwarf_vars_dealloc.3 \ + dwarf_dealloc.3 dwarf_weaks_dealloc.3 \ + dwarf_dealloc.3 dwarf_ranges_dealloc.3 \ + dwarf_dealloc.3 dwarf_srclines_dealloc.3 \ + dwarf_init.3 dwarf_elf_init.3 \ + dwarf_dieoffset.3 dwarf_die_CU_offset.3 \ + dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \ + dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \ + dwarf_finish.3 dwarf_object_finish.3 \ + dwarf_formref.3 dwarf_global_formref.3 \ + dwarf_formudata.3 dwarf_formsdata.3 \ + dwarf_get_AT_name.3 dwarf_get_ACCESS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ATE_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CC_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CFA_name.3 \ + dwarf_get_AT_name.3 dwarf_get_CHILDREN_name.3 \ + dwarf_get_AT_name.3 dwarf_get_DS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_DSC_name.3 \ + dwarf_get_AT_name.3 dwarf_get_EH_name.3 \ + dwarf_get_AT_name.3 dwarf_get_END_name.3 \ + dwarf_get_AT_name.3 dwarf_get_FORM_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ID_name.3 \ + dwarf_get_AT_name.3 dwarf_get_INL_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LANG_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LNE_name.3 \ + dwarf_get_AT_name.3 dwarf_get_LNS_name.3 \ + dwarf_get_AT_name.3 dwarf_get_MACINFO_name.3 \ + dwarf_get_AT_name.3 dwarf_get_OP_name.3 \ + dwarf_get_AT_name.3 dwarf_get_ORD_name.3 \ + dwarf_get_AT_name.3 dwarf_get_TAG_name.3 \ + dwarf_get_AT_name.3 dwarf_get_VIRTUALITY_name.3 \ + dwarf_get_AT_name.3 dwarf_get_VIS_name.3 \ + dwarf_get_cu_die_offset.3 dwarf_get_arange_cu_header_offset.3 \ + dwarf_get_fde_list.3 dwarf_get_fde_list_eh.3 \ + dwarf_get_funcs.3 dwarf_func_die_offset.3 \ + dwarf_get_funcs.3 dwarf_func_cu_offset.3 \ + dwarf_get_funcs.3 dwarf_func_name_offsets.3 \ + dwarf_get_funcs.3 dwarf_funcname.3 \ + dwarf_get_globals.3 dwarf_global_die_offset.3 \ + dwarf_get_globals.3 dwarf_global_cu_offset.3 \ + dwarf_get_globals.3 dwarf_global_name_offsets.3 \ + dwarf_get_globals.3 dwarf_globname.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_die_offset.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_cu_offset.3 \ + dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \ + dwarf_get_pubtypes.3 dwarf_pubtypename.3 \ + dwarf_get_ranges.3 dwarf_get_ranges_a.3 \ + dwarf_get_types.3 dwarf_type_die_offset.3 \ + dwarf_get_types.3 dwarf_type_cu_offset.3 \ + dwarf_get_types.3 dwarf_type_name_offsets.3 \ + dwarf_get_types.3 dwarf_typename.3 \ + dwarf_get_vars.3 dwarf_var_die_offset.3 \ + dwarf_get_vars.3 dwarf_var_cu_offset.3 \ + dwarf_get_vars.3 dwarf_var_name_offsets.3 \ + dwarf_get_vars.3 dwarf_varname.3 \ + dwarf_get_weaks.3 dwarf_weak_die_offset.3 \ + dwarf_get_weaks.3 dwarf_weak_cu_offset.3 \ + dwarf_get_weaks.3 dwarf_weak_name_offsets.3 \ + dwarf_get_weaks.3 dwarf_weakname.3 \ + dwarf_hasform.3 dwarf_whatform.3 \ + dwarf_hasform.3 dwarf_whatform_direct.3 \ + dwarf_highpc.3 dwarf_arrayorder.3 \ + dwarf_highpc.3 dwarf_bitoffset.3 \ + dwarf_highpc.3 dwarf_bitsize.3 \ + dwarf_highpc.3 dwarf_bytesize.3 \ + dwarf_highpc.3 dwarf_lowpc.3 \ + dwarf_highpc.3 dwarf_srclang.3 \ + dwarf_lineno.3 dwarf_lineaddr.3 \ + dwarf_lineno.3 dwarf_linebeginstatement.3 \ + dwarf_lineno.3 dwarf_lineblock.3 \ + dwarf_lineno.3 dwarf_lineendsequence.3 \ + dwarf_lineno.3 dwarf_lineoff.3 \ + dwarf_lineno.3 dwarf_linesrc.3 \ + dwarf_lineno.3 dwarf_line_srcfileno.3 \ + dwarf_loclist.3 dwarf_loclist_n.3 \ + dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \ + dwarf_producer_init.3 dwarf_producer_init_b.3 \ + dwarf_seterrarg.3 dwarf_seterrhand.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_table_size.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_same_value.3 \ + dwarf_set_frame_cfa_value.3 dwarf_set_frame_undefined_value.3 + +dwarf_pubnames.c: dwarf_nametbl.m4 dwarf_pubnames.m4 +dwarf_pubtypes.c: dwarf_nametbl.m4 dwarf_pubtypes.m4 +dwarf_weaks.c: dwarf_nametbl.m4 dwarf_weaks.m4 +dwarf_funcs.c: dwarf_nametbl.m4 dwarf_funcs.m4 +dwarf_vars.c: dwarf_nametbl.m4 dwarf_vars.m4 +dwarf_types.c: dwarf_nametbl.m4 dwarf_types.m4 +dwarf_pro_pubnames.c: dwarf_pro_nametbl.m4 dwarf_pro_pubnames.m4 +dwarf_pro_weaks.c: dwarf_pro_nametbl.m4 dwarf_pro_weaks.m4 +dwarf_pro_funcs.c: dwarf_pro_nametbl.m4 dwarf_pro_funcs.m4 +dwarf_pro_types.c: dwarf_pro_nametbl.m4 dwarf_pro_types.m4 +dwarf_pro_vars.c: dwarf_pro_nametbl.m4 dwarf_pro_vars.m4 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libdwarf/Version.map b/contrib/elftoolchain/libdwarf/Version.map new file mode 100644 index 0000000..6e6548b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/Version.map @@ -0,0 +1,228 @@ +/* $Id: Version.map 2576 2012-09-13 09:16:11Z jkoshy $ */ + +R1.0 { +global: + dwarf_add_AT_comp_dir; + dwarf_add_AT_const_value_signedint; + dwarf_add_AT_const_value_string; + dwarf_add_AT_const_value_unsignedint; + dwarf_add_AT_dataref; + dwarf_add_AT_flag; + dwarf_add_AT_location_expr; + dwarf_add_AT_name; + dwarf_add_AT_producer; + dwarf_add_AT_ref_address; + dwarf_add_AT_reference; + dwarf_add_AT_signed_const; + dwarf_add_AT_string; + dwarf_add_AT_targ_address; + dwarf_add_AT_targ_address_b; + dwarf_add_AT_unsigned_const; + dwarf_add_arange; + dwarf_add_arange_b; + dwarf_add_die_to_debug; + dwarf_add_directory_decl; + dwarf_add_expr_addr; + dwarf_add_expr_addr_b; + dwarf_add_expr_gen; + dwarf_add_fde_inst; + dwarf_add_file_decl; + dwarf_add_frame_cie; + dwarf_add_frame_fde; + dwarf_add_frame_fde_b; + dwarf_add_funcname; + dwarf_add_line_entry; + dwarf_add_pubname; + dwarf_add_typename; + dwarf_add_varname; + dwarf_add_weakname; + dwarf_arrayorder; + dwarf_attr; + dwarf_attrlist; + dwarf_attrval_flag; + dwarf_attrval_signed; + dwarf_attrval_string; + dwarf_attrval_unsigned; + dwarf_bitoffset; + dwarf_bitsize; + dwarf_bytesize; + dwarf_child; + dwarf_dealloc; + dwarf_def_macro; + dwarf_die_CU_offset; + dwarf_die_CU_offset_range; + dwarf_die_abbrev_code; + dwarf_die_link; + dwarf_diename; + dwarf_dieoffset; + dwarf_elf_init; + dwarf_end_macro_file; + dwarf_errmsg_; + dwarf_expand_frame_instructions; + dwarf_expr_current_offset; + dwarf_expr_into_block; + dwarf_fde_cfa_offset; + dwarf_fde_cie_list_dealloc; + dwarf_find_macro_value_start; + dwarf_finish; + dwarf_formaddr; + dwarf_formblock; + dwarf_formexprloc; + dwarf_formflag; + dwarf_formref; + dwarf_formsdata; + dwarf_formsig8; + dwarf_formstring; + dwarf_formudata; + dwarf_func_cu_offset; + dwarf_func_die_offset; + dwarf_func_name_offsets; + dwarf_funcname; + dwarf_funcs_dealloc; + dwarf_get_ACCESS_name; + dwarf_get_ATE_name; + dwarf_get_AT_name; + dwarf_get_CC_name; + dwarf_get_CFA_name; + dwarf_get_CHILDREN_name; + dwarf_get_DSC_name; + dwarf_get_DS_name; + dwarf_get_EH_name; + dwarf_get_END_name; + dwarf_get_FORM_name; + dwarf_get_ID_name; + dwarf_get_INL_name; + dwarf_get_LANG_name; + dwarf_get_LNE_name; + dwarf_get_LNS_name; + dwarf_get_MACINFO_name; + dwarf_get_OP_name; + dwarf_get_ORD_name; + dwarf_get_TAG_name; + dwarf_get_VIRTUALITY_name; + dwarf_get_VIS_name; + dwarf_get_abbrev; + dwarf_get_abbrev_children_flag; + dwarf_get_abbrev_code; + dwarf_get_abbrev_entry; + dwarf_get_abbrev_tag; + dwarf_get_address_size; + dwarf_get_arange; + dwarf_get_arange_cu_header_offset; + dwarf_get_arange_info; + dwarf_get_aranges; + dwarf_get_cie_index; + dwarf_get_cie_info; + dwarf_get_cie_of_fde; + dwarf_get_cu_die_offset; + dwarf_get_cu_die_offset_given_cu_header_offset; + dwarf_get_elf; + dwarf_get_fde_at_pc; + dwarf_get_fde_info_for_all_regs3; + dwarf_get_fde_info_for_all_regs; + dwarf_get_fde_info_for_cfa_reg3; + dwarf_get_fde_info_for_reg3; + dwarf_get_fde_info_for_reg; + dwarf_get_fde_instr_bytes; + dwarf_get_fde_list; + dwarf_get_fde_list_eh; + dwarf_get_fde_n; + dwarf_get_fde_range; + dwarf_get_form_class; + dwarf_get_funcs; + dwarf_get_globals; + dwarf_get_loclist_entry; + dwarf_get_macro_details; + dwarf_get_pubtypes; + dwarf_get_ranges; + dwarf_get_ranges_a; + dwarf_get_relocation_info; + dwarf_get_relocation_info_count; + dwarf_get_section_bytes; + dwarf_get_str; + dwarf_get_types; + dwarf_get_vars; + dwarf_get_weaks; + dwarf_global_cu_offset; + dwarf_global_die_offset; + dwarf_global_formref; + dwarf_global_name_offsets; + dwarf_globals_dealloc; + dwarf_globname; + dwarf_hasattr; + dwarf_hasform; + dwarf_highpc; + dwarf_init; + dwarf_line_srcfileno; + dwarf_lineaddr; + dwarf_linebeginstatement; + dwarf_lineblock; + dwarf_lineendsequence; + dwarf_lineno; + dwarf_lineoff; + dwarf_linesrc; + dwarf_lne_end_sequence; + dwarf_lne_set_address; + dwarf_loclist; + dwarf_loclist_from_expr; + dwarf_loclist_from_expr_a; + dwarf_loclist_n; + dwarf_lowpc; + dwarf_new_die; + dwarf_new_expr; + dwarf_new_fde; + dwarf_next_cu_header; + dwarf_next_cu_header_b; + dwarf_object_finish; + dwarf_object_init; + dwarf_offdie; + dwarf_producer_finish; + dwarf_producer_init; + dwarf_producer_init_b; + dwarf_producer_set_isa; + dwarf_pubtype_cu_offset; + dwarf_pubtype_die_offset; + dwarf_pubtype_name_offsets; + dwarf_pubtypename; + dwarf_pubtypes_dealloc; + dwarf_ranges_dealloc; + dwarf_reset_section_bytes; + dwarf_set_frame_cfa_value; + dwarf_set_frame_rule_initial_value; + dwarf_set_frame_rule_table_size; + dwarf_set_frame_same_value; + dwarf_set_frame_undefined_value; + dwarf_set_reloc_application; + dwarf_seterrarg; + dwarf_seterrhand; + dwarf_siblingof; + dwarf_srcfiles; + dwarf_srclang; + dwarf_srclines; + dwarf_srclines_dealloc; + dwarf_start_macro_file; + dwarf_tag; + dwarf_transform_to_disk_form; + dwarf_type_cu_offset; + dwarf_type_die_offset; + dwarf_type_name_offsets; + dwarf_typename; + dwarf_types_dealloc; + dwarf_undef_macro; + dwarf_var_cu_offset; + dwarf_var_die_offset; + dwarf_var_name_offsets; + dwarf_varname; + dwarf_vars_dealloc; + dwarf_vendor_ext; + dwarf_weak_cu_offset; + dwarf_weak_die_offset; + dwarf_weak_name_offsets; + dwarf_weakname; + dwarf_weaks_dealloc; + dwarf_whatattr; + dwarf_whatform; + dwarf_whatform_direct; +local: + *; +}; diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h new file mode 100644 index 0000000..23f60e8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/_libdwarf.h @@ -0,0 +1,658 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: _libdwarf.h 2075 2011-10-27 03:47:28Z jkoshy $ + */ + +#ifndef __LIBDWARF_H_ +#define __LIBDWARF_H_ + +#include <sys/param.h> +#include <sys/queue.h> +#include <assert.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <gelf.h> +#include "dwarf.h" +#include "libdwarf.h" +#include "uthash.h" + +#include "_elftc.h" + +#define DWARF_DIE_HASH_SIZE 8191 + +struct _libdwarf_globals { + Dwarf_Handler errhand; + Dwarf_Ptr errarg; + int applyrela; +}; + +extern struct _libdwarf_globals _libdwarf; + +#define _DWARF_SET_ERROR(_d, _e, _err, _elf_err) \ + _dwarf_set_error(_d, _e, _err, _elf_err, __func__, __LINE__) +#define DWARF_SET_ERROR(_d, _e, _err) \ + _DWARF_SET_ERROR(_d, _e, _err, 0) +#define DWARF_SET_ELF_ERROR(_d, _e) \ + _DWARF_SET_ERROR(_d, _e, DW_DLE_ELF, elf_errno()) + +/* + * Convenient macros for producer bytes stream generation. + */ +#define WRITE_VALUE(value, bytes) \ + dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, \ + (value), (bytes), error) +#define WRITE_ULEB128(value) \ + _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (value), error) +#define WRITE_SLEB128(value) \ + _dwarf_write_sleb128_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (value), error) +#define WRITE_STRING(string) \ + _dwarf_write_string_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (string), error) +#define WRITE_BLOCK(blk, size) \ + _dwarf_write_block_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (blk), (size), error) +#define WRITE_PADDING(byte, cnt) \ + _dwarf_write_padding_alloc(&ds->ds_data, &ds->ds_cap, \ + &ds->ds_size, (byte), (cnt), error) +#define RCHECK(expr) \ + do { \ + ret = expr; \ + if (ret != DW_DLE_NONE) \ + goto gen_fail; \ + } while(0) + + +struct _Dwarf_AttrDef { + uint64_t ad_attrib; /* DW_AT_XXX */ + uint64_t ad_form; /* DW_FORM_XXX */ + uint64_t ad_offset; /* Offset in abbrev section. */ + STAILQ_ENTRY(_Dwarf_AttrDef) ad_next; /* Next attribute define. */ +}; + +struct _Dwarf_Attribute { + Dwarf_Die at_die; /* Ptr to containing DIE. */ + Dwarf_Die at_refdie; /* Ptr to reference DIE. */ + uint64_t at_offset; /* Offset in info section. */ + uint64_t at_attrib; /* DW_AT_XXX */ + uint64_t at_form; /* DW_FORM_XXX */ + int at_indirect; /* Has indirect form. */ + union { + uint64_t u64; /* Unsigned value. */ + int64_t s64; /* Signed value. */ + char *s; /* String. */ + uint8_t *u8p; /* Block data. */ + } u[2]; /* Value. */ + Dwarf_Block at_block; /* Block. */ + Dwarf_Locdesc *at_ld; /* at value is locdesc. */ + Dwarf_P_Expr at_expr; /* at value is expr. */ + uint64_t at_relsym; /* Relocation symbol index. */ + const char *at_relsec; /* Rel. to dwarf section. */ + STAILQ_ENTRY(_Dwarf_Attribute) at_next; /* Next attribute. */ +}; + +struct _Dwarf_Abbrev { + uint64_t ab_entry; /* Abbrev entry. */ + uint64_t ab_tag; /* Tag: DW_TAG_ */ + uint8_t ab_children; /* DW_CHILDREN_no or DW_CHILDREN_yes */ + uint64_t ab_offset; /* Offset in abbrev section. */ + uint64_t ab_length; /* Length of this abbrev entry. */ + uint64_t ab_atnum; /* Number of attribute defines. */ + UT_hash_handle ab_hh; /* Uthash handle. */ + STAILQ_HEAD(, _Dwarf_AttrDef) ab_attrdef; /* List of attribute defs. */ +}; + +struct _Dwarf_Die { + Dwarf_Die die_parent; /* Parent DIE. */ + Dwarf_Die die_child; /* First child DIE. */ + Dwarf_Die die_left; /* Left sibling DIE. */ + Dwarf_Die die_right; /* Right sibling DIE. */ + uint64_t die_offset; /* DIE offset in section. */ + uint64_t die_next_off; /* Next DIE offset in section. */ + uint64_t die_abnum; /* Abbrev number. */ + Dwarf_Abbrev die_ab; /* Abbrev pointer. */ + Dwarf_Tag die_tag; /* DW_TAG_ */ + Dwarf_Debug die_dbg; /* Dwarf_Debug pointer. */ + Dwarf_CU die_cu; /* Compilation unit pointer. */ + char *die_name; /* Ptr to the name string. */ + Dwarf_Attribute *die_attrarray; /* Array of attributes. */ + STAILQ_HEAD(, _Dwarf_Attribute) die_attr; /* List of attributes. */ + STAILQ_ENTRY(_Dwarf_Die) die_pro_next; /* Next die in pro-die list. */ +}; + +struct _Dwarf_Loclist { + Dwarf_Locdesc **ll_ldlist; /* Array of Locdesc pointer. */ + int ll_ldlen; /* Number of Locdesc. */ + Dwarf_Unsigned ll_offset; /* Offset in .debug_loc section. */ + Dwarf_Unsigned ll_length; /* Length (in bytes) of the loclist. */ + TAILQ_ENTRY(_Dwarf_Loclist) ll_next; /* Next loclist in list. */ +}; + +struct _Dwarf_P_Expr_Entry { + Dwarf_Loc ee_loc; /* Location expression. */ + Dwarf_Unsigned ee_sym; /* Optional related reloc sym index. */ + STAILQ_ENTRY(_Dwarf_P_Expr_Entry) ee_next; /* Next entry in list. */ +}; + +struct _Dwarf_P_Expr { + Dwarf_Debug pe_dbg; /* Dwarf_Debug pointer. */ + uint8_t *pe_block; /* Expression block data. */ + int pe_invalid; /* Block data is up-to-date or not. */ + Dwarf_Unsigned pe_length; /* Length of the block. */ + STAILQ_HEAD(, _Dwarf_P_Expr_Entry) pe_eelist; /* List of entries. */ + STAILQ_ENTRY(_Dwarf_P_Expr) pe_next; /* Next expr in list. */ +}; + +struct _Dwarf_Line { + Dwarf_LineInfo ln_li; /* Ptr to line info. */ + Dwarf_Addr ln_addr; /* Line address. */ + Dwarf_Unsigned ln_symndx; /* Symbol index for relocation. */ + Dwarf_Unsigned ln_fileno; /* File number. */ + Dwarf_Unsigned ln_lineno; /* Line number. */ + Dwarf_Signed ln_column; /* Column number. */ + Dwarf_Bool ln_bblock; /* Basic block flag. */ + Dwarf_Bool ln_stmt; /* Begin statement flag. */ + Dwarf_Bool ln_endseq; /* End sequence flag. */ + STAILQ_ENTRY(_Dwarf_Line) ln_next; /* Next line in list. */ +}; + +struct _Dwarf_LineFile { + char *lf_fname; /* Filename. */ + char *lf_fullpath; /* Full pathname of the file. */ + Dwarf_Unsigned lf_dirndx; /* Dir index. */ + Dwarf_Unsigned lf_mtime; /* Modification time. */ + Dwarf_Unsigned lf_size; /* File size. */ + STAILQ_ENTRY(_Dwarf_LineFile) lf_next; /* Next file in list. */ +}; + +struct _Dwarf_LineInfo { + Dwarf_Unsigned li_length; /* Length of line info data. */ + Dwarf_Half li_version; /* Version of line info. */ + Dwarf_Unsigned li_hdrlen; /* Length of line info header. */ + Dwarf_Small li_minlen; /* Minimum instrutction length. */ + Dwarf_Small li_defstmt; /* Default value of is_stmt. */ + int8_t li_lbase; /* Line base for special opcode. */ + Dwarf_Small li_lrange; /* Line range for special opcode. */ + Dwarf_Small li_opbase; /* Fisrt std opcode number. */ + Dwarf_Small *li_oplen; /* Array of std opcode len. */ + char **li_incdirs; /* Array of include dirs. */ + Dwarf_Unsigned li_inclen; /* Length of inc dir array. */ + char **li_lfnarray; /* Array of file names. */ + Dwarf_Unsigned li_lflen; /* Length of filename array. */ + STAILQ_HEAD(, _Dwarf_LineFile) li_lflist; /* List of files. */ + Dwarf_Line *li_lnarray; /* Array of lines. */ + Dwarf_Unsigned li_lnlen; /* Length of the line array. */ + STAILQ_HEAD(, _Dwarf_Line) li_lnlist; /* List of lines. */ +}; + +struct _Dwarf_NamePair { + Dwarf_NameTbl np_nt; /* Ptr to containing name table. */ + Dwarf_Die np_die; /* Ptr to Ref. Die. */ + Dwarf_Unsigned np_offset; /* Offset in CU. */ + char *np_name; /* Object/Type name. */ + STAILQ_ENTRY(_Dwarf_NamePair) np_next; /* Next pair in the list. */ +}; + +struct _Dwarf_NameTbl { + Dwarf_Unsigned nt_length; /* Name lookup table length. */ + Dwarf_Half nt_version; /* Name lookup table version. */ + Dwarf_CU nt_cu; /* Ptr to Ref. CU. */ + Dwarf_Off nt_cu_offset; /* Ref. CU offset in .debug_info */ + Dwarf_Unsigned nt_cu_length; /* Ref. CU length. */ + STAILQ_HEAD(, _Dwarf_NamePair) nt_nplist; /* List of offset+name pairs. */ + STAILQ_ENTRY(_Dwarf_NameTbl) nt_next; /* Next name table in the list. */ +}; + +struct _Dwarf_NameSec { + STAILQ_HEAD(, _Dwarf_NameTbl) ns_ntlist; /* List of name tables. */ + Dwarf_NamePair *ns_array; /* Array of pairs of all tables. */ + Dwarf_Unsigned ns_len; /* Length of the pair array. */ +}; + +struct _Dwarf_Fde { + Dwarf_Debug fde_dbg; /* Ptr to containing dbg. */ + Dwarf_Cie fde_cie; /* Ptr to associated CIE. */ + Dwarf_FrameSec fde_fs; /* Ptr to containing .debug_frame. */ + Dwarf_Ptr fde_addr; /* Ptr to start of the FDE. */ + Dwarf_Unsigned fde_offset; /* Offset of the FDE. */ + Dwarf_Unsigned fde_length; /* Length of the FDE. */ + Dwarf_Unsigned fde_cieoff; /* Offset of associated CIE. */ + Dwarf_Unsigned fde_initloc; /* Initial location. */ + Dwarf_Unsigned fde_adrange; /* Address range. */ + Dwarf_Unsigned fde_auglen; /* Augmentation length. */ + uint8_t *fde_augdata; /* Augmentation data. */ + uint8_t *fde_inst; /* Instructions. */ + Dwarf_Unsigned fde_instlen; /* Length of instructions. */ + Dwarf_Unsigned fde_instcap; /* Capacity of inst buffer. */ + Dwarf_Unsigned fde_symndx; /* Symbol index for relocation. */ + Dwarf_Unsigned fde_esymndx; /* End symbol index for relocation. */ + Dwarf_Addr fde_eoff; /* Offset from the end symbol. */ + STAILQ_ENTRY(_Dwarf_Fde) fde_next; /* Next FDE in list. */ +}; + +struct _Dwarf_Cie { + Dwarf_Debug cie_dbg; /* Ptr to containing dbg. */ + Dwarf_Unsigned cie_index; /* Index of the CIE. */ + Dwarf_Unsigned cie_offset; /* Offset of the CIE. */ + Dwarf_Unsigned cie_length; /* Length of the CIE. */ + Dwarf_Half cie_version; /* CIE version. */ + uint8_t *cie_augment; /* CIE augmentation (UTF-8). */ + Dwarf_Unsigned cie_ehdata; /* Optional EH Data. */ + Dwarf_Unsigned cie_caf; /* Code alignment factor. */ + Dwarf_Signed cie_daf; /* Data alignment factor. */ + Dwarf_Unsigned cie_ra; /* Return address register. */ + Dwarf_Unsigned cie_auglen; /* Augmentation length. */ + uint8_t *cie_augdata; /* Augmentation data; */ + uint8_t cie_fde_encode; /* FDE PC start/range encode. */ + Dwarf_Ptr cie_initinst; /* Initial instructions. */ + Dwarf_Unsigned cie_instlen; /* Length of init instructions. */ + STAILQ_ENTRY(_Dwarf_Cie) cie_next; /* Next CIE in list. */ +}; + +struct _Dwarf_FrameSec { + STAILQ_HEAD(, _Dwarf_Cie) fs_cielist; /* List of CIE. */ + STAILQ_HEAD(, _Dwarf_Fde) fs_fdelist; /* List of FDE. */ + Dwarf_Cie *fs_ciearray; /* Array of CIE. */ + Dwarf_Unsigned fs_cielen; /* Length of CIE array. */ + Dwarf_Fde *fs_fdearray; /* Array of FDE.*/ + Dwarf_Unsigned fs_fdelen; /* Length of FDE array. */ +}; + +struct _Dwarf_Arange { + Dwarf_ArangeSet ar_as; /* Ptr to the set it belongs to. */ + Dwarf_Unsigned ar_address; /* Start PC. */ + Dwarf_Unsigned ar_range; /* PC range. */ + Dwarf_Unsigned ar_symndx; /* First symbol index for reloc. */ + Dwarf_Unsigned ar_esymndx; /* Second symbol index for reloc. */ + Dwarf_Addr ar_eoff; /* Offset from second symbol. */ + STAILQ_ENTRY(_Dwarf_Arange) ar_next; /* Next arange in list. */ +}; + +struct _Dwarf_ArangeSet { + Dwarf_Unsigned as_length; /* Length of the arange set. */ + Dwarf_Half as_version; /* Version of the arange set. */ + Dwarf_Off as_cu_offset; /* Offset of associated CU. */ + Dwarf_CU as_cu; /* Ptr to associated CU. */ + Dwarf_Small as_addrsz; /* Target address size. */ + Dwarf_Small as_segsz; /* Target segment size. */ + STAILQ_HEAD (, _Dwarf_Arange) as_arlist; /* List of ae entries. */ + STAILQ_ENTRY(_Dwarf_ArangeSet) as_next; /* Next set in list. */ +}; + +struct _Dwarf_MacroSet { + Dwarf_Macro_Details *ms_mdlist; /* Array of macinfo entries. */ + Dwarf_Unsigned ms_cnt; /* Length of the array. */ + STAILQ_ENTRY(_Dwarf_MacroSet) ms_next; /* Next set in list. */ +}; + +struct _Dwarf_Rangelist { + Dwarf_CU rl_cu; /* Ptr to associated CU. */ + Dwarf_Unsigned rl_offset; /* Offset of the rangelist. */ + Dwarf_Ranges *rl_rgarray; /* Array of ranges. */ + Dwarf_Unsigned rl_rglen; /* Length of the ranges array. */ + STAILQ_ENTRY(_Dwarf_Rangelist) rl_next; /* Next rangelist in list. */ +}; + +struct _Dwarf_CU { + Dwarf_Debug cu_dbg; /* Ptr to containing dbg. */ + Dwarf_Off cu_offset; /* Offset to the this CU. */ + uint32_t cu_length; /* Length of CU data. */ + uint16_t cu_length_size; /* Size in bytes of the length field. */ + uint16_t cu_version; /* DWARF version. */ + uint64_t cu_abbrev_offset; /* Offset into .debug_abbrev. */ + uint64_t cu_abbrev_offset_cur; /* Current abbrev offset. */ + int cu_abbrev_loaded; /* Abbrev table parsed. */ + uint64_t cu_abbrev_cnt; /* Abbrev entry count. */ + uint64_t cu_lineno_offset; /* Offset into .debug_lineno. */ + uint8_t cu_pointer_size;/* Number of bytes in pointer. */ + uint8_t cu_dwarf_size; /* CU section dwarf size. */ + Dwarf_Off cu_next_offset; /* Offset to the next CU. */ + uint64_t cu_1st_offset; /* First DIE offset. */ + int cu_pass2; /* Two pass DIE traverse. */ + Dwarf_LineInfo cu_lineinfo; /* Ptr to Dwarf_LineInfo. */ + Dwarf_Abbrev cu_abbrev_hash; /* Abbrev hash table. */ + STAILQ_ENTRY(_Dwarf_CU) cu_next; /* Next compilation unit. */ +}; + +typedef struct _Dwarf_Section { + const char *ds_name; /* Section name. */ + Dwarf_Small *ds_data; /* Section data. */ + Dwarf_Unsigned ds_addr; /* Section virtual addr. */ + Dwarf_Unsigned ds_size; /* Section size. */ +} Dwarf_Section; + +typedef struct _Dwarf_P_Section { + char *ds_name; /* Section name. */ + Dwarf_Small *ds_data; /* Section data. */ + Dwarf_Unsigned ds_size; /* Section size. */ + Dwarf_Unsigned ds_cap; /* Section capacity. */ + Dwarf_Unsigned ds_ndx; /* ELF section index. */ + Dwarf_Unsigned ds_symndx; /* Section symbol index. (for reloc) */ + STAILQ_ENTRY(_Dwarf_P_Section) ds_next; /* Next section in the list. */ +} *Dwarf_P_Section; + +typedef struct _Dwarf_Rel_Entry { + unsigned char dre_type; /* Reloc type. */ + unsigned char dre_length; /* Reloc storage unit length. */ + Dwarf_Unsigned dre_offset; /* Reloc storage unit offset. */ + Dwarf_Unsigned dre_addend; /* Reloc addend. */ + Dwarf_Unsigned dre_symndx; /* Reloc symbol index. */ + const char *dre_secname; /* Refer to some debug section. */ + STAILQ_ENTRY(_Dwarf_Rel_Entry) dre_next; /* Next reloc entry. */ +} *Dwarf_Rel_Entry; + +typedef struct _Dwarf_Rel_Section { + struct _Dwarf_P_Section *drs_ds; /* Ptr to actual reloc ELF section. */ + struct _Dwarf_P_Section *drs_ref; /* Which debug section it refers. */ + struct Dwarf_Relocation_Data_s *drs_drd; /* Reloc data array. */ + STAILQ_HEAD(, _Dwarf_Rel_Entry) drs_dre; /* Reloc entry list. */ + Dwarf_Unsigned drs_drecnt; /* Count of entries. */ + Dwarf_Unsigned drs_size; /* Size of ELF section in bytes. */ + int drs_addend; /* Elf_Rel or Elf_Rela */ + STAILQ_ENTRY(_Dwarf_Rel_Section) drs_next; /* Next reloc section. */ +} *Dwarf_Rel_Section; + +typedef struct { + Elf_Data *ed_data; + void *ed_alloc; +} Dwarf_Elf_Data; + +typedef struct { + Elf *eo_elf; + GElf_Ehdr eo_ehdr; + GElf_Shdr *eo_shdr; + Dwarf_Elf_Data *eo_data; + Dwarf_Unsigned eo_seccnt; + size_t eo_strndx; + Dwarf_Obj_Access_Methods eo_methods; +} Dwarf_Elf_Object; + +struct _Dwarf_Debug { + Dwarf_Obj_Access_Interface *dbg_iface; + Dwarf_Section *dbg_section; /* Dwarf section list. */ + Dwarf_Section *dbg_info_sec; /* Pointer to info section. */ + Dwarf_Off dbg_info_off; /* Current info section offset. */ + Dwarf_Unsigned dbg_seccnt; /* Total number of dwarf sections. */ + int dbg_mode; /* Access mode. */ + int dbg_pointer_size; /* Object address size. */ + int dbg_offset_size; /* DWARF offset size. */ + int dbg_info_loaded; /* Flag indicating all CU loaded. */ + Dwarf_Half dbg_machine; /* ELF machine architecture. */ + Dwarf_Handler dbg_errhand; /* Error handler. */ + Dwarf_Ptr dbg_errarg; /* Argument to the error handler. */ + STAILQ_HEAD(, _Dwarf_CU) dbg_cu;/* List of compilation units. */ + Dwarf_CU dbg_cu_current; /* Ptr to the current CU. */ + TAILQ_HEAD(, _Dwarf_Loclist) dbg_loclist; /* List of location list. */ + Dwarf_NameSec dbg_globals; /* Ptr to pubnames lookup section. */ + Dwarf_NameSec dbg_pubtypes; /* Ptr to pubtypes lookup section. */ + Dwarf_NameSec dbg_weaks; /* Ptr to weaknames lookup section. */ + Dwarf_NameSec dbg_funcs; /* Ptr to static funcs lookup sect. */ + Dwarf_NameSec dbg_vars; /* Ptr to static vars lookup sect. */ + Dwarf_NameSec dbg_types; /* Ptr to types lookup section. */ + Dwarf_FrameSec dbg_frame; /* Ptr to .debug_frame section. */ + Dwarf_FrameSec dbg_eh_frame; /* Ptr to .eh_frame section. */ + STAILQ_HEAD(, _Dwarf_ArangeSet) dbg_aslist; /* List of arange set. */ + Dwarf_Arange *dbg_arange_array; /* Array of arange. */ + Dwarf_Unsigned dbg_arange_cnt; /* Length of the arange array. */ + char *dbg_strtab; /* Dwarf string table. */ + Dwarf_Unsigned dbg_strtab_cap; /* Dwarf string table capacity. */ + Dwarf_Unsigned dbg_strtab_size; /* Dwarf string table size. */ + STAILQ_HEAD(, _Dwarf_MacroSet) dbg_mslist; /* List of macro set. */ + STAILQ_HEAD(, _Dwarf_Rangelist) dbg_rllist; /* List of rangelist. */ + uint64_t (*read)(uint8_t *, uint64_t *, int); + void (*write)(uint8_t *, uint64_t *, uint64_t, int); + int (*write_alloc)(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); + uint64_t (*decode)(uint8_t **, int); + + Dwarf_Half dbg_frame_rule_table_size; + Dwarf_Half dbg_frame_rule_initial_value; + Dwarf_Half dbg_frame_cfa_value; + Dwarf_Half dbg_frame_same_value; + Dwarf_Half dbg_frame_undefined_value; + + Dwarf_Regtable3 *dbg_internal_reg_table; + + /* + * Fields used by libdwarf producer. + */ + + Dwarf_Unsigned dbgp_flags; + Dwarf_Unsigned dbgp_isa; + Dwarf_Callback_Func dbgp_func; + Dwarf_Callback_Func_b dbgp_func_b; + Dwarf_Die dbgp_root_die; + STAILQ_HEAD(, _Dwarf_Die) dbgp_dielist; + STAILQ_HEAD(, _Dwarf_P_Expr) dbgp_pelist; + Dwarf_LineInfo dbgp_lineinfo; + Dwarf_ArangeSet dbgp_as; + Dwarf_Macro_Details *dbgp_mdlist; + Dwarf_Unsigned dbgp_mdcnt; + STAILQ_HEAD(, _Dwarf_Cie) dbgp_cielist; + STAILQ_HEAD(, _Dwarf_Fde) dbgp_fdelist; + Dwarf_Unsigned dbgp_cielen; + Dwarf_Unsigned dbgp_fdelen; + Dwarf_NameTbl dbgp_pubs; + Dwarf_NameTbl dbgp_weaks; + Dwarf_NameTbl dbgp_funcs; + Dwarf_NameTbl dbgp_types; + Dwarf_NameTbl dbgp_vars; + STAILQ_HEAD(, _Dwarf_P_Section) dbgp_seclist; + Dwarf_Unsigned dbgp_seccnt; + Dwarf_P_Section dbgp_secpos; + Dwarf_P_Section dbgp_info; + STAILQ_HEAD(, _Dwarf_Rel_Section) dbgp_drslist; + Dwarf_Unsigned dbgp_drscnt; + Dwarf_Rel_Section dbgp_drspos; +}; + +/* + * Internal function prototypes. + */ + +int _dwarf_abbrev_add(Dwarf_CU, uint64_t, uint64_t, uint8_t, + uint64_t, Dwarf_Abbrev *, Dwarf_Error *); +void _dwarf_abbrev_cleanup(Dwarf_CU); +int _dwarf_abbrev_find(Dwarf_CU, uint64_t, Dwarf_Abbrev *, + Dwarf_Error *); +int _dwarf_abbrev_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_abbrev_parse(Dwarf_Debug, Dwarf_CU, Dwarf_Unsigned *, + Dwarf_Abbrev *, Dwarf_Error *); +int _dwarf_add_AT_dataref(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Unsigned, Dwarf_Unsigned, const char *, + Dwarf_P_Attribute *, Dwarf_Error *); +int _dwarf_add_string_attr(Dwarf_P_Die, Dwarf_P_Attribute *, + Dwarf_Half, char *, Dwarf_Error *); +int _dwarf_alloc(Dwarf_Debug *, int, Dwarf_Error *); +void _dwarf_arange_cleanup(Dwarf_Debug); +int _dwarf_arange_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_arange_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_arange_pro_cleanup(Dwarf_P_Debug); +int _dwarf_attr_alloc(Dwarf_Die, Dwarf_Attribute *, Dwarf_Error *); +Dwarf_Attribute _dwarf_attr_find(Dwarf_Die, Dwarf_Half); +int _dwarf_attr_gen(Dwarf_P_Debug, Dwarf_P_Section, Dwarf_Rel_Section, + Dwarf_CU, Dwarf_Die, int, Dwarf_Error *); +int _dwarf_attr_init(Dwarf_Debug, Dwarf_Section *, uint64_t *, int, + Dwarf_CU, Dwarf_Die, Dwarf_AttrDef, uint64_t, int, + Dwarf_Error *); +int _dwarf_attrdef_add(Dwarf_Debug, Dwarf_Abbrev, uint64_t, + uint64_t, uint64_t, Dwarf_AttrDef *, Dwarf_Error *); +uint64_t _dwarf_decode_lsb(uint8_t **, int); +uint64_t _dwarf_decode_msb(uint8_t **, int); +int64_t _dwarf_decode_sleb128(uint8_t **); +uint64_t _dwarf_decode_uleb128(uint8_t **); +void _dwarf_deinit(Dwarf_Debug); +int _dwarf_die_alloc(Dwarf_Debug, Dwarf_Die *, Dwarf_Error *); +int _dwarf_die_count_links(Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die); +Dwarf_Die _dwarf_die_find(Dwarf_Die, Dwarf_Unsigned); +int _dwarf_die_gen(Dwarf_P_Debug, Dwarf_CU, Dwarf_Rel_Section, + Dwarf_Error *); +void _dwarf_die_link(Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die); +int _dwarf_die_parse(Dwarf_Debug, Dwarf_Section *, Dwarf_CU, int, + uint64_t, uint64_t, Dwarf_Die *, int, Dwarf_Error *); +void _dwarf_die_pro_cleanup(Dwarf_P_Debug); +void _dwarf_elf_deinit(Dwarf_Debug); +int _dwarf_elf_init(Dwarf_Debug, Elf *, Dwarf_Error *); +int _dwarf_elf_load_section(void *, Dwarf_Half, Dwarf_Small **, + int *); +Dwarf_Endianness _dwarf_elf_get_byte_order(void *); +Dwarf_Small _dwarf_elf_get_length_size(void *); +Dwarf_Small _dwarf_elf_get_pointer_size(void *); +Dwarf_Unsigned _dwarf_elf_get_section_count(void *); +int _dwarf_elf_get_section_info(void *, Dwarf_Half, + Dwarf_Obj_Access_Section *, int *); +void _dwarf_expr_cleanup(Dwarf_P_Debug); +int _dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Error *); +Dwarf_Section *_dwarf_find_section(Dwarf_Debug, const char *); +void _dwarf_frame_cleanup(Dwarf_Debug); +int _dwarf_frame_fde_add_inst(Dwarf_P_Fde, Dwarf_Small, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +int _dwarf_frame_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t *, Dwarf_Unsigned, + Dwarf_Frame_Op **, Dwarf_Signed *, Dwarf_Error *); +int _dwarf_frame_get_internal_table(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable3 **, Dwarf_Addr *, Dwarf_Error *); +int _dwarf_frame_interal_table_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_frame_params_init(Dwarf_Debug); +void _dwarf_frame_pro_cleanup(Dwarf_P_Debug); +int _dwarf_frame_regtable_copy(Dwarf_Debug, Dwarf_Regtable3 **, + Dwarf_Regtable3 *, Dwarf_Error *); +int _dwarf_frame_section_load(Dwarf_Debug, Dwarf_Error *); +int _dwarf_frame_section_load_eh(Dwarf_Debug, Dwarf_Error *); +int _dwarf_generate_sections(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_Unsigned _dwarf_get_reloc_type(Dwarf_P_Debug, int); +int _dwarf_get_reloc_size(Dwarf_Debug, Dwarf_Unsigned); +void _dwarf_info_cleanup(Dwarf_Debug); +int _dwarf_info_first_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_info_load(Dwarf_Debug, int, Dwarf_Error *); +int _dwarf_info_next_cu(Dwarf_Debug, Dwarf_Error *); +void _dwarf_info_pro_cleanup(Dwarf_P_Debug); +int _dwarf_init(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Handler, + Dwarf_Ptr, Dwarf_Error *); +int _dwarf_lineno_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_lineno_init(Dwarf_Die, uint64_t, Dwarf_Error *); +void _dwarf_lineno_cleanup(Dwarf_LineInfo); +void _dwarf_lineno_pro_cleanup(Dwarf_P_Debug); +int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *, uint8_t *, + uint64_t, uint8_t, Dwarf_Error *); +int _dwarf_loc_fill_locexpr(Dwarf_Debug, Dwarf_Locdesc **, + uint8_t *, uint64_t, uint8_t, Dwarf_Error *); +int _dwarf_loc_add(Dwarf_Die, Dwarf_Attribute, Dwarf_Error *); +int _dwarf_loc_expr_add_atom(Dwarf_Debug, uint8_t *, uint8_t *, + Dwarf_Small, Dwarf_Unsigned, Dwarf_Unsigned, int *, + Dwarf_Error *); +int _dwarf_loclist_find(Dwarf_Debug, Dwarf_CU, uint64_t, + Dwarf_Loclist *, Dwarf_Error *); +void _dwarf_loclist_cleanup(Dwarf_Debug); +void _dwarf_loclist_free(Dwarf_Loclist); +int _dwarf_loclist_add(Dwarf_Debug, Dwarf_CU, uint64_t, + Dwarf_Loclist *, Dwarf_Error *); +void _dwarf_macinfo_cleanup(Dwarf_Debug); +int _dwarf_macinfo_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_macinfo_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_macinfo_pro_cleanup(Dwarf_P_Debug); +int _dwarf_nametbl_init(Dwarf_Debug, Dwarf_NameSec *, + Dwarf_Section *, Dwarf_Error *); +void _dwarf_nametbl_cleanup(Dwarf_NameSec *); +int _dwarf_nametbl_gen(Dwarf_P_Debug, const char *, Dwarf_NameTbl, + Dwarf_Error *); +void _dwarf_nametbl_pro_cleanup(Dwarf_NameTbl *); +int _dwarf_pro_callback(Dwarf_P_Debug, char *, int, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned *, int *); +Dwarf_P_Section _dwarf_pro_find_section(Dwarf_P_Debug, const char *); +int _dwarf_ranges_add(Dwarf_Debug, Dwarf_CU, uint64_t, + Dwarf_Rangelist *, Dwarf_Error *); +void _dwarf_ranges_cleanup(Dwarf_Debug); +int _dwarf_ranges_find(Dwarf_Debug, uint64_t, Dwarf_Rangelist *); +uint64_t _dwarf_read_lsb(uint8_t *, uint64_t *, int); +uint64_t _dwarf_read_msb(uint8_t *, uint64_t *, int); +int64_t _dwarf_read_sleb128(uint8_t *, uint64_t *); +uint64_t _dwarf_read_uleb128(uint8_t *, uint64_t *); +char *_dwarf_read_string(void *, Dwarf_Unsigned, uint64_t *); +uint8_t *_dwarf_read_block(void *, uint64_t *, uint64_t); +int _dwarf_reloc_section_finalize(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_Error *); +int _dwarf_reloc_entry_add(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_P_Section, unsigned char, unsigned char, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + const char *, Dwarf_Error *); +int _dwarf_reloc_entry_add_pair(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_P_Section, unsigned char, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +void _dwarf_reloc_cleanup(Dwarf_P_Debug); +int _dwarf_reloc_gen(Dwarf_P_Debug, Dwarf_Error *); +int _dwarf_reloc_section_gen(Dwarf_P_Debug, Dwarf_Rel_Section, + Dwarf_Error *); +int _dwarf_reloc_section_init(Dwarf_P_Debug, Dwarf_Rel_Section *, + Dwarf_P_Section, Dwarf_Error *); +void _dwarf_reloc_section_free(Dwarf_P_Debug, Dwarf_Rel_Section *); +void _dwarf_section_cleanup(Dwarf_P_Debug); +int _dwarf_section_callback(Dwarf_P_Debug, Dwarf_P_Section, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +void _dwarf_section_free(Dwarf_P_Debug, Dwarf_P_Section *); +int _dwarf_section_init(Dwarf_P_Debug, Dwarf_P_Section *, + const char *, int, Dwarf_Error *); +void _dwarf_set_error(Dwarf_Debug, Dwarf_Error *, int, int, + const char *, int); +int _dwarf_strtab_add(Dwarf_Debug, char *, uint64_t *, + Dwarf_Error *); +void _dwarf_strtab_cleanup(Dwarf_Debug); +int _dwarf_strtab_gen(Dwarf_P_Debug, Dwarf_Error *); +char *_dwarf_strtab_get_table(Dwarf_Debug); +int _dwarf_strtab_init(Dwarf_Debug, Dwarf_Error *); +void _dwarf_write_block(void *, uint64_t *, uint8_t *, uint64_t); +int _dwarf_write_block_alloc(uint8_t **, uint64_t *, uint64_t *, + uint8_t *, uint64_t, Dwarf_Error *); +void _dwarf_write_lsb(uint8_t *, uint64_t *, uint64_t, int); +int _dwarf_write_lsb_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); +void _dwarf_write_msb(uint8_t *, uint64_t *, uint64_t, int); +int _dwarf_write_msb_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, int, Dwarf_Error *); +void _dwarf_write_padding(void *, uint64_t *, uint8_t, uint64_t); +int _dwarf_write_padding_alloc(uint8_t **, uint64_t *, uint64_t *, + uint8_t, uint64_t, Dwarf_Error *); +void _dwarf_write_string(void *, uint64_t *, char *); +int _dwarf_write_string_alloc(uint8_t **, uint64_t *, uint64_t *, + char *, Dwarf_Error *); +int _dwarf_write_sleb128(uint8_t *, uint8_t *, int64_t); +int _dwarf_write_sleb128_alloc(uint8_t **, uint64_t *, uint64_t *, + int64_t, Dwarf_Error *); +int _dwarf_write_uleb128(uint8_t *, uint8_t *, uint64_t); +int _dwarf_write_uleb128_alloc(uint8_t **, uint64_t *, uint64_t *, + uint64_t, Dwarf_Error *); + +#endif /* !__LIBDWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/dwarf.3 b/contrib/elftoolchain/libdwarf/dwarf.3 new file mode 100644 index 0000000..b32299c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf.3 @@ -0,0 +1,727 @@ +.\" Copyright (c) 2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd September 17, 2011 +.Os +.Dt DWARF 3 +.Sh NAME +.Nm dwarf +.Nd access debugging information in object files +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Sh DESCRIPTION +.Pp +The +.Lb libdwarf +provides functions that allow an application to read and write debugging +information in object files. +The format of debugging information accessible through this API +is defined by the DWARF standard, see +.Xr dwarf 4 . +.Pp +The +.Xr DWARF 3 +API has two parts: +.Bl -bullet +.It +A consumer API set allows applications to read existing debug information +in a program object. +The functions that comprise the DWARF consumer API are described in +the section +.Sx "DWARF Consumer API" +below. +.It +A producer API set that allows applications to add debug information +to a program object. +The functions that comprise the DWARF producer API are described in +the section +.Sx "DWARF Producer API" +below. +.El +.Pp +Each function referenced below is further described in its own manual page. +.Ss Namespace use +The DWARF library uses the following prefixes: +.Pp +.Bl -tag -width ".Li Dwarf_*" -compact +.It Li DWARF_* +Used for error numbers and constants. +.It Li DW_* +Used for constants. +.It Li Dwarf_* +Used for types. +.It Li dwarf_* +Used for functions and macros that make up the API. +.El +.Ss Data Types +The DWARF(3) API uses the following data types: +.Pp +.Bl -tag -width ".Vt Dwarf_Unsigned" -compact +.It Vt Dwarf_Abbrev +Describes DWARF abbreviations. +.It Vt Dwarf_Addr +A program address in the target object. +.It Vt Dwarf_Arange +Describes address ranges. +.It Vt Dwarf_Attribute , Vt Dwarf_P_Attribute +Describes attributes of debugging information entries. +.It Vt Dwarf_Bool +Used for boolean states. +.It Vt Dwarf_Cie , Vt Dwarf_P_Cie +Describes call information that is common to several frames. +.It Vt Dwarf_Debug , Vt Dwarf_P_Debug +An opaque type describing a debug context. +.It Vt Dwarf_Die , Vt Dwarf_P_Die +A debugging information entry. +.It Vt Dwarf_Fde , Vt Dwarf_P_Fde +A frame descriptor. +.It Vt Dwarf_Func +A descriptor representing a function. +.It Vt Dwarf_Global +A descriptor representing a global name. +.It Vt Dwarf_Half +A 16-bit wide unsigned numeric type. +.It Vt Dwarf_Handler +A pointer to an error handling function. +.It Vt Dwarf_Line +A descriptor for a source line. +.It Vt Dwarf_Off +An unsigned file offset, corresponding to an +.Vt off_t +type supported by the underlying operating system. +.It Vt Dwarf_P_Expr +A descriptor for a location expression. +.It Vt Dwarf_Ptr +A virtual address used by an application. +.It Vt Dwarf_Signed +A 64-bit wide signed numeric type. +.It Vt Dwarf_Small +An 8-bit wide unsigned numeric type. +.It Vt Dwarf_Type +A descriptor representing a user-specified type. +.It Vt Dwarf_Unsigned +A 64-bit wide unsigned numeric type. +.It Vt Dwarf_Var +A descriptor representing a static variable. +.It Vt Dwarf_Weak +A descriptor representing a weak name. +.El +.Ss Error Handling +.Pp +Library functions that encounter an error will return with a value +other than +.Dv DW_DLV_OK . +.Pp +The +.Lb libdwarf +allows applications to specify three levels of error handling: +.Bl -enum -compact +.It +Most library functions take a parameter of type +.Vt Dwarf_Error +that specifies a location to store an error descriptor in +case of an error. +If an error occurs during the execution on an API, and if this +parameter is non-NULL, then an error descriptor is written to the +location specified. +.It +Otherwise, if the error parameter was NULL, but if an error handler +was defined for the debug context in use using +.Xr dwarf_init 3 +or +.Xr dwarf_seterrhand 3 , +then the library will invoke the specified error handler with an error +descriptor as argument. +.It +Otherwise, if a library wide error handler was specified using +.Xr dwarf_seterrhand 3 , +it is called. +.El +.Pp +Error descriptors may be used with +.Xr dwarf_errmsg 3 +or +.Xr dwarf_errno 3 . +.Sh The DWARF Consumer API +The DWARF consumer API permits applications to read DWARF information in +an object file. +.Pp +The major functional groups of functions in the consumer API are listed +below. +.Pp +.Bl -tag -compact -width "CCCC" +.It Abbreviations +.Bl -tag -compact +.It Fn dwarf_get_abbrev +Retrieve abbreviation information at a given offset. +.It Fn dwarf_get_abbrev_children_flag +Check if an abbreviation has child elements. +.It Fn dwarf_get_abbrev_code +Retrieve the abbreviation code for an abbreviation entry descriptor. +.It Fn dwarf_get_abbrev_entry +Retrieve abbreviation information for an abbreviation entry +descriptor. +.It Fn dwarf_get_abbrev_tag +Retrieve the tag for an abbreviation entry. +.El +.It Addresses +.Bl -tag -compact +.It Fn dwarf_get_address_size +Return the number of bytes needed to represent an address. +.It Fn dwarf_get_arange +Search for an address range descriptor covering an address. +.It Fn dwarf_get_arange_cu_header_offset +Retrieve the offsets associated with an address range descriptor. +.It Fn dwarf_get_arange_info +Extract address range information from a descriptor. +.It Fn dwarf_get_aranges +Retrieve program address space mappings. +.It Fn dwarf_get_cu_die_offset +Retrieve the offset associated with a compilation unit for an address +range descriptor. +.It Fn dwarf_get_ranges , Fn dwarf_get_ranges_a +Retrieve information about non-contiguous address ranges for +a debugging information entry. +.El +.It Attributes +.Bl -tag -compact +.It Fn dwarf_arrayorder +Retrieve the value of a +.Dv DW_AT_ordering +attribute. +.It Fn dwarf_attr +Retrieve an attribute descriptor. +.It Fn dwarf_attrlist +Retrieve attribute descriptors for a debugging information entry. +.It Fn dwarf_attrval_flag +Retrieve a +.Dv DW_AT_FORM_flag +value. +.It Fn dwarf_attrval_signed +Retrieve an attribute's value as a signed integral quantity. +.It Fn dwarf_attrval_string +Retrieve an attribute's value as a NUL-terminated string. +.It Fn dwarf_attrval_unsigned +Retrieve an attribute's value as an unsigned integral quantity. +.It Fn dwarf_bitoffset , +Retrieve the value of a +.Dv DW_AT_bit_offset +attribute. +.It Fn dwarf_bitsize , +Retrieve the value of a +.Dv DW_AT_bit_size +attribute. +.It Fn dwarf_bytesize +Retrieve the value of a +.Dv DW_AT_byte_size +attribute. +.It Fn dwarf_formaddr +Return the value of an +.Dv ADDRESS Ns - Ns +class attribute. +.It Fn dwarf_formblock +Return the value of a +.Dv BLOCK Ns - Ns +class attribute +.It Fn dwarf_formexprloc +Return information about a location expression. +.It Fn dwarf_formflag +Retrieve information about a +.Dv BOOLEAN Ns - Ns +class attribute. +.It Fn dwarf_formref , Fn dwarf_global_formref +Retrieve offsets for +.Dv REFERENCE Ns - Ns +class attributes. +.It Fn dwarf_formsdata , Fn dwarf_formudata +Retrieve the value of a +.Dv CONSTANT Ns - Ns +class attribute. +.It Fn dwarf_formsig8 +Return the type signature for a DWARF type. +.It Fn dwarf_formstring +Retrieve information about a +.Dv STRING Ns - Ns +class attribute. +.It Fn dwarf_get_form_class +Retrieve the form class for an attribute. +.It Fn dwarf_hasattr +Check for the presence of an attribute. +.It Fn dwarf_hasform +Check if an attribute has the given form. +.It Fn dwarf_whatattr +Retrieve the attribute code for an attribute. +.It Fn dwarf_whatform , Fn dwarf_whatform_direct +Retrieve the form of an attribute. +.El +.It Call Information Entries and Frame Descriptor Entries +.Bl -tag -compact +.It Fn dwarf_get_cie_index +Retrieve the index for a CIE descriptor. +.It Fn dwarf_get_cie_info +Retrieve information from a CIE descriptor. +.It Fn dwarf_get_cie_of_fde +Retrieve a CIE descriptor. +.It Fn dwarf_get_fde_at_pc +Retrieve an FDE descriptor for an address. +.It Fn dwarf_get_fde_info_for_all_regs +Retrieve register rule row. +.It Fn dwarf_get_fde_info_for_all_regs3 +Retrieve register rule row (revised API). +.It Fn dwarf_get_fde_info_for_cfa_reg3 +Retrieve a CFA register rule. +.It Fn dwarf_get_fde_info_for_reg +Retrieve a register rule. +.It Fn dwarf_get_fde_info_for_reg3 +Retrieve a register rule (revised API). +.It Fn dwarf_get_fde_instr_bytes +Retrieve instructions from an FDE descriptor. +.It Fn dwarf_get_fde_list , Fn dwarf_get_fde_list_eh +Retrieve frame information. +.It Fn dwarf_get_fde_n +Retrieve an FDE descriptor. +.It Fn dwarf_get_fde_range +Retrieve range information from an FDE descriptor. +.El +.It Compilation Units +.Bl -tag -compact +.It Fn dwarf_get_cu_die_offset_given_cu_header_offset +Retrieve the offset of the debugging information entry for a +compilation unit. +.It Fn dwarf_next_cu_header , Fn dwarf_next_cu_header_b +Step through compilation units in a debug context. +.El +.It Debugging Information Entries +.Bl -tag -compact +.It Fn dwarf_child +Returns the child of a debugging information entry. +.It Fn dwarf_die_abbrev_code +Returns the abbreviation code for a debugging information entry. +.It Fn dwarf_die_CU_offset , Fn dwarf_die_CU_offset_range +Retrieve offsets and lengths for a compilation unit. +.It Fn dwarf_diename +Returns the +.Dv DW_AT_name +attribute for a debugging information entry. +.It Fn dwarf_dieoffset +Retrieves the offset for a debugging information entry. +.It Fn dwarf_highpc +Return the highest PC value for a debugging information entry. +.It Fn dwarf_lowpc +Return the lowest PC value for a debugging information entry. +.It Fn dwarf_offdie +Retrieve a debugging information entry given an offset. +.It Fn dwarf_siblingof +Retrieve the sibling descriptor for a debugging information entry. +.It Fn dwarf_srclang +Retrive the source language attribute for a debugging information +entry. +.It Fn dwarf_tag +Retrieve the tag for a debugging information entry. +.El +.It Functions +.Bl -tag -compact +.It Fn dwarf_func_cu_offset +Retrieves the offset for the compilation unit for a function. +.It Fn dwarf_func_die_offset +Retrieves the offset for the debugging information entry for a +function. +.It Fn dwarf_funcname +Retrieves the name of a function. +.It Fn dwarf_func_name_offsets +Retrieve both the name and offsets for a function. +.It Fn dwarf_get_funcs +Retrieve information about static functions. +.El +.It Globals +.Bl -tag -compact +.It Fn dwarf_get_globals +Retrieve a list of globals. +.It Fn dwarf_global_cu_offset +Return the offset for compilation unit for a global. +.It Fn dwarf_global_die_offset +Return the offset for the debugging information entry for a global. +.It Fn dwarf_global_name_offsets +Return the name and offsets for a global. +.It Fn dwarf_globname +Return the name for a global. +.El +.It Initialization and Finalization +Functions +.Fn dwarf_elf_init +and +.Fn dwarf_init +may be used for initialization. +The function +.Fn dwarf_finish +may be used to release resources. +.Pp +The functions +.Fn dwarf_object_init +and +.Fn dwarf_object_finish +allow an application to specify alternate low-level file access +routines. +.It Line Numbers +.Bl -tag -compact +.It Fn dwarf_lineaddr +Retrieve the program address for a source line. +.It Fn dwarf_linebeginstatement +Check if a source line corresponds to the beginning of a statement. +.It Fn dwarf_lineblock +Check if a source line corresponds to the start of a basic block. +.It Fn dwarf_lineendsequence +Check if the source line corresponds to the end of a sequence of +instructions. +.It Fn dwarf_lineno +Retrieve the line number for a line descriptor. +.It Fn dwarf_lineoff +Retrieve the column number for a line descriptor. +.It Fn dwarf_linesrc +Retrieve the source file for a line descriptor. +.It Fn dwarf_line_srcfileno +Retrieve the index of the source file for a line descriptor. +.It Fn dwarf_srcfiles +Retrieve source files for a compilation unit. +.It Fn dwarf_srclines +Return line number information for a compilation unit. +.El +.It Location Lists +.Bl -tag -compact +.It Fn dwarf_get_loclist_entry +Retrieve a location list entry. +.It Fn dwarf_loclist , Fn dwarf_loclist_n +Retrieve location expressions. +.It Fn dwarf_loclist_from_expr , Fn dwarf_loclist_from_expr_a +Translate a location expression into a location descriptor. +.El +.It Error Handling +.Bl -tag -compact +.It Fn dwarf_errmsg +Retrieve a human-readable error message. +.It Fn dwarf_errno +Retrieve an error number from an error descriptor. +.It Fn dwarf_seterrarg +Set the argument passed to a callback error handler. +.It Fn dwarf_seterrhand +Set the callback handler to be called in case of an error. +.El +.It Frame Handling +.Bl -tag -compact +.It Fn dwarf_expand_frame_instructions +Translate frame instruction bytes. +.It Fn dwarf_set_frame_cfa_value +Set the CFA parameter for the internal register rule table. +.It Fn dwarf_set_frame_rule_initial_value +Set the initial value of the register rules in the internal register +rule table. +.It Fn dwarf_set_frame_rule_table_size +Set the maximum number of columns in the register rule table. +.It Fn dwarf_set_frame_same_value +Set the register number representing the +.Dq "same value" +rule. +.It Fn dwarf_set_frame_undefined_value +Set the register number representing the +.Dq "undefined" +rule. +.El +.It Macros +.Bl -tag -compact +.It Fn dwarf_find_macro_value_start +Return the macro value part of a macro string. +.It Fn dwarf_get_macro_details +Retrieve macro information. +.El +.It Memory Management +In the DWARF consumer API, the rules for memory management differ +between functions. +In some cases, the memory areas returned to the application by the +library are freed by calling specific API functions. +In others, the deallocation function +.Fn dwarf_dealloc +suffices. +The individual manual pages for the API's functions document the +specific memory management rules to be followed. +.Pp +The function +.Fn dwarf_dealloc +is used to mark memory arenas as unused. +Additionally, the following functions release specific types of +DWARF resources: +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc , +and +.Fn dwarf_weaks_dealloc . +.It Symbol Constants +The following functions may be used to return symbolic names +for DWARF constants: +.Fn dwarf_get_ACCESS_name , +.Fn dwarf_get_AT_name , +.Fn dwarf_get_ATE_name , +.Fn dwarf_get_CC_name , +.Fn dwarf_get_CFA_name , +.Fn dwarf_get_CHILDREN_name , +.Fn dwarf_get_DS_name , +.Fn dwarf_get_DSC_name , +.Fn dwarf_get_EH_name , +.Fn dwarf_get_END_name , +.Fn dwarf_get_FORM_name , +.Fn dwarf_get_ID_name , +.Fn dwarf_get_INL_name , +.Fn dwarf_get_LANG_name , +.Fn dwarf_get_LNE_name , +.Fn dwarf_get_LNS_name , +.Fn dwarf_get_MACINFO_name , +.Fn dwarf_get_OP_name , +.Fn dwarf_get_ORD_name , +.Fn dwarf_get_TAG_name , +.Fn dwarf_get_VIRTUALITY_name , +and +.Fn dwarf_get_VIS_name . +.It Types +.Bl -tag -compact +.It Fn dwarf_get_pubtypes , Fn dwarf_get_types +Retrieve descriptors for user-defined types. +.It Fn dwarf_pubtype_cu_offset , Fn dwarf_type_cu_offset +Return the offset for the compilation unit for a type. +.It Fn dwarf_pubtype_die_offset , Fn dwarf_type_die_offset +Return the offset for the debugging information entry for a type. +.It Fn dwarf_pubtypename , Fn dwarf_typename +Retrieve the name of a type. +.It Fn dwarf_pubtype_name_offsets , Fn dwarf_type_name_offsets +Retrieve the name and offsets for a type. +.El +.It Variables +.Bl -tag -compact +.It Fn dwarf_get_vars +Retrieve descriptors for static variables. +.It Fn dwarf_var_cu_offset +Return the offset for the compilation unit for a variable. +.It Fn dwarf_var_die_offset +Return the offset for the debugging information entry for a variable. +.It Fn dwarf_varname +Retrieve the name of a variable. +.It Fn dwarf_var_name_offsets +Retrieve the name and offsets for a variable. +.El +.It Weak Symbols +.Bl -tag -compact +.It Fn dwarf_get_weaks +Retrieve information about weak symbols. +.It Fn dwarf_weak_cu_offset +Return the offset for the compilation unit for a weak symbol. +.It Fn dwarf_weak_die_offset +Return the offset for the debugging information entry for a weak symbol. +.It Fn dwarf_weakname +Retrieve the name of a weak symbol. +.It Fn dwarf_weak_name_offsets +Retrieve the name and offsets for a weak symbol. +.El +.It Miscellaneous +.Bl -tag -compact +.It Fn dwarf_get_elf +Retrieve the ELF descriptor for a debug context, see +.Xr elf 3 . +.It Fn dwarf_get_str +Retrieve a NUL-terminated string from the DWARF string section. +.It Fn dwarf_set_reloc_application +Control whether relocations are to be handled by +.Lb libdwarf . +.El +.El +.Sh The DWARF Producer API +The DWARF producer API permits applications to add DWARF information to +an object file. +.Pp +The major functional groups of functions in the producer API are listed +below. +.Bl -tag -width "CCCC" +.It Attribute Management +The following functions are used to attach attributes to a debugging +information entry: +.Fn dwarf_add_AT_comp_dir , +.Fn dwarf_add_AT_const_value_signedint , +.Fn dwarf_add_AT_const_value_string , +.Fn dwarf_add_AT_const_value_unsignedint , +.Fn dwarf_add_AT_dataref , +.Fn dwarf_add_AT_flag , +.Fn dwarf_add_AT_location_expr , +.Fn dwarf_add_AT_name , +.Fn dwarf_add_AT_producer , +.Fn dwarf_add_AT_ref_address , +.Fn dwarf_add_AT_reference , +.Fn dwarf_add_AT_signed_const , +.Fn dwarf_add_AT_string , +.Fn dwarf_add_AT_targ_address , +.Fn dwarf_add_AT_targ_address_b +and +.Fn dwarf_add_AT_unsigned_const . +.It Debugging Information Entry Management +.Bl -tag -compact +.It Fn dwarf_add_die_to_debug +Set the root debugging information entry for a DWARF producer instance. +.It Fn dwarf_die_link +Links debugging information entries. +.It Fn dwarf_new_die +Allocate a new debugging information entry. +.El +.It Initialization and Finalization +The functions +.Fn dwarf_producer_init +and +.Fn dwarf_producer_init_b +are used to initialize a producer instance. +.Pp +When done, applications release resources using the function +.Fn dwarf_producer_finish . +.It Relocations and Sections +.Bl -tag -compact +.It Fn dwarf_get_relocation_info +Retrieve a relocation array from a producer instance. +.It Fn dwarf_get_relocation_info_count +Return the number of relocation arrays for a producer instance. +.It Fn dwarf_get_section_bytes +Retrieve the ELF byte stream for a section. +.It Fn dwarf_reset_section_bytes +Reset internal state for a producer instance. +.It Fn dwarf_transform_to_disk_form +Prepare byte streams for writing out. +.El +.It Macros +.Bl -tag -compact +.It Fn dwarf_def_macro +Add a macro definition. +.It Fn dwarf_end_macro_file , Fn dwarf_start_macro_file +Record macro file related information. +.It Fn dwarf_undef_macro +Note the removal of a macro definition. +.It Fn dwarf_vendor_ext +Enables storing macro information as specified in the DWARF standard. +.El +.It Symbols, Expressions, Addresses and Offsets +.Bl -tag -compact +.It Fn dwarf_add_arange , Fn dwarf_add_arange_b +Add address range information. +.It Fn dwarf_add_directory_decl +Add information about an include directory to a producer instance. +.It Fn dwarf_add_fde_inst +Add an operation to a frame descriptor entry. +.It Fn dwarf_add_file_decl +Add information about a source file to a producer instance. +.It Fn dwarf_add_frame_cie +Add call information to a frame descriptor. +.It Fn dwarf_add_frame_fde , Fn dwarf_add_frame_fde_b +Link a frame descriptor to a producer instance. +.It Fn dwarf_add_funcname +Add information about a function to a producer instance. +.It Fn dwarf_add_line_entry +Record mapping information between machine addresses and a source line. +.It Fn dwarf_add_expr_addr , Fn dwarf_add_expr_addr_b +Add a +.Dv DW_OP_addr +opcode to a location expression. +.It Fn dwarf_add_expr_gen +Add an operator to a location expression. +.It Fn dwarf_add_pubname +Add information about a global name to a producer instance. +.It Fn dwarf_add_typename +Add information about a type to a producer instance. +.It Fn dwarf_add_varname +Add information about a static variable to a producer instance. +.It Fn dwarf_add_weakname +Add information about a weak symbol to a producer instance. +.It Fn dwarf_expr_current_offset +Retrieve the current size of a location expression. +.It Fn dwarf_expr_into_block +Convert a location expression into a byte stream. +.It Fn dwarf_fde_cfa_offset +Append a +.Dv DW_CFA_offset +operation to a frame descriptor. +.It Fn dwarf_lne_end_sequence , Fn dwarf_lne_set_address +Note address ranges for source lines. +.It Fn dwarf_new_expr +Allocate a location expression descriptor. +.It Fn dwarf_new_fde +Allocate a frame descriptor. +.El +.It Miscellaneous +The function +.Fn dwarf_producer_set_isa +sets the instruction set architecture for the producer instance. +.El +.Sh COMPATIBILITY +This implementation is believed to be source compatible with the +SGI/GNU DWARF(3) library, version 20110113. +.Pp +Known differences with the SGI/GNU library include: +.Bl -bullet -compact +.It +The memory management scheme used differs, in a backward-compatible +way. +See +.Sx Memory Management +above, for coding guidelines for portable applications. +.It +There is provision for setting a library-wide error handler in +addition to the per-debug context handlers supported by the SGI/GNU +API, see the subsection +.Sx Error Handling +above. +.It +The following API is an extension: +.Fn dwarf_producer_set_isa . +.El +.Sh SEE ALSO +.Xr elf 3 +.Sh STANDARDS +The DWARF standard is defined by +.Rs +.%T "The DWARF Debugging Information Format" +.%V "Version 4" +.%O "http://www.dwarfstd.org/" +.Re +.Sh HISTORY +The DWARF(3) API originated at Silicon Graphics Inc. +.Pp +A BSD-licensed implementation of a subset of the API was written by +.An "John Birrell" Aq jb@FreeBSD.org +for the FreeBSD project. +The implementation was subsequently revised and completed by +.An "Kai Wang" Aq kaiwang27@users.sourceforge.net . +.Pp +Manual pages for this implementation were written by +.An "Joseph Koshy" Aq jkoshy@users.sourceforge.net +and +.An "Kai Wang" Aq kaiwang27@users.sourceforge.net . diff --git a/contrib/elftoolchain/libdwarf/dwarf.h b/contrib/elftoolchain/libdwarf/dwarf.h new file mode 100644 index 0000000..b1a3e4e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf.h @@ -0,0 +1,544 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: dwarf.h 2075 2011-10-27 03:47:28Z jkoshy $ + */ + +#ifndef _DWARF_H_ +#define _DWARF_H_ + +#define DW_TAG_array_type 0x01 +#define DW_TAG_class_type 0x02 +#define DW_TAG_entry_point 0x03 +#define DW_TAG_enumeration_type 0x04 +#define DW_TAG_formal_parameter 0x05 +#define DW_TAG_imported_declaration 0x08 +#define DW_TAG_label 0x0a +#define DW_TAG_lexical_block 0x0b +#define DW_TAG_member 0x0d +#define DW_TAG_pointer_type 0x0f +#define DW_TAG_reference_type 0x10 +#define DW_TAG_compile_unit 0x11 +#define DW_TAG_string_type 0x12 +#define DW_TAG_structure_type 0x13 +#define DW_TAG_subroutine_type 0x15 +#define DW_TAG_typedef 0x16 +#define DW_TAG_union_type 0x17 +#define DW_TAG_unspecified_parameters 0x18 +#define DW_TAG_variant 0x19 +#define DW_TAG_common_block 0x1a +#define DW_TAG_common_inclusion 0x1b +#define DW_TAG_inheritance 0x1c +#define DW_TAG_inlined_subroutine 0x1d +#define DW_TAG_module 0x1e +#define DW_TAG_ptr_to_member_type 0x1f +#define DW_TAG_set_type 0x20 +#define DW_TAG_subrange_type 0x21 +#define DW_TAG_with_stmt 0x22 +#define DW_TAG_access_declaration 0x23 +#define DW_TAG_base_type 0x24 +#define DW_TAG_catch_block 0x25 +#define DW_TAG_const_type 0x26 +#define DW_TAG_constant 0x27 +#define DW_TAG_enumerator 0x28 +#define DW_TAG_friend 0x2a +#define DW_TAG_namelist 0x2b +#define DW_TAG_namelist_item 0x2c +#define DW_TAG_packed_type 0x2d +#define DW_TAG_subprogram 0x2e +#define DW_TAG_template_type_parameter 0x2f +#define DW_TAG_template_type_param 0x2f +#define DW_TAG_template_value_parameter 0x30 +#define DW_TAG_template_value_param 0x30 +#define DW_TAG_thrown_type 0x31 +#define DW_TAG_try_block 0x32 +#define DW_TAG_variant_part 0x33 +#define DW_TAG_variable 0x34 +#define DW_TAG_volatile_type 0x35 +#define DW_TAG_dwarf_procedure 0x36 +#define DW_TAG_restrict_type 0x37 +#define DW_TAG_interface_type 0x38 +#define DW_TAG_namespace 0x39 +#define DW_TAG_imported_module 0x3a +#define DW_TAG_unspecified_type 0x3b +#define DW_TAG_partial_unit 0x3c +#define DW_TAG_imported_unit 0x3d +#define DW_TAG_condition 0x3f +#define DW_TAG_shared_type 0x40 +#define DW_TAG_type_unit 0x41 +#define DW_TAG_rvalue_reference_type 0x42 +#define DW_TAG_template_alias 0x43 +#define DW_TAG_lo_user 0x4080 +#define DW_TAG_hi_user 0xffff + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +#define DW_AT_sibling 0x01 +#define DW_AT_location 0x02 +#define DW_AT_name 0x03 +#define DW_AT_ordering 0x09 +#define DW_AT_subscr_data 0x0a +#define DW_AT_byte_size 0x0b +#define DW_AT_bit_offset 0x0c +#define DW_AT_bit_size 0x0d +#define DW_AT_element_list 0x0f +#define DW_AT_stmt_list 0x10 +#define DW_AT_low_pc 0x11 +#define DW_AT_high_pc 0x12 +#define DW_AT_language 0x13 +#define DW_AT_member 0x14 +#define DW_AT_discr 0x15 +#define DW_AT_discr_value 0x16 +#define DW_AT_visibility 0x17 +#define DW_AT_import 0x18 +#define DW_AT_string_length 0x19 +#define DW_AT_common_reference 0x1a +#define DW_AT_comp_dir 0x1b +#define DW_AT_const_value 0x1c +#define DW_AT_containing_type 0x1d +#define DW_AT_default_value 0x1e +#define DW_AT_inline 0x20 +#define DW_AT_is_optional 0x21 +#define DW_AT_lower_bound 0x22 +#define DW_AT_producer 0x25 +#define DW_AT_prototyped 0x27 +#define DW_AT_return_addr 0x2a +#define DW_AT_start_scope 0x2c +#define DW_AT_bit_stride 0x2e +#define DW_AT_stride_size 0x2e +#define DW_AT_upper_bound 0x2f +#define DW_AT_abstract_origin 0x31 +#define DW_AT_accessibility 0x32 +#define DW_AT_address_class 0x33 +#define DW_AT_artificial 0x34 +#define DW_AT_base_types 0x35 +#define DW_AT_calling_convention 0x36 +#define DW_AT_count 0x37 +#define DW_AT_data_member_location 0x38 +#define DW_AT_decl_column 0x39 +#define DW_AT_decl_file 0x3a +#define DW_AT_decl_line 0x3b +#define DW_AT_declaration 0x3c +#define DW_AT_discr_list 0x3d +#define DW_AT_encoding 0x3e +#define DW_AT_external 0x3f +#define DW_AT_frame_base 0x40 +#define DW_AT_friend 0x41 +#define DW_AT_identifier_case 0x42 +#define DW_AT_macro_info 0x43 +#define DW_AT_namelist_item 0x44 +#define DW_AT_priority 0x45 +#define DW_AT_segment 0x46 +#define DW_AT_specification 0x47 +#define DW_AT_static_link 0x48 +#define DW_AT_type 0x49 +#define DW_AT_use_location 0x4a +#define DW_AT_variable_parameter 0x4b +#define DW_AT_virtuality 0x4c +#define DW_AT_vtable_elem_location 0x4d +#define DW_AT_allocated 0x4e +#define DW_AT_associated 0x4f +#define DW_AT_data_location 0x50 +#define DW_AT_byte_stride 0x51 +#define DW_AT_entry_pc 0x52 +#define DW_AT_use_UTF8 0x53 +#define DW_AT_extension 0x54 +#define DW_AT_ranges 0x55 +#define DW_AT_trampoline 0x56 +#define DW_AT_call_column 0x57 +#define DW_AT_call_file 0x58 +#define DW_AT_call_line 0x59 +#define DW_AT_description 0x5a +#define DW_AT_binary_scale 0x5b +#define DW_AT_decimal_scale 0x5c +#define DW_AT_small 0x5d +#define DW_AT_decimal_sign 0x5e +#define DW_AT_digit_count 0x5f +#define DW_AT_picture_string 0x60 +#define DW_AT_mutable 0x61 +#define DW_AT_threads_scaled 0x62 +#define DW_AT_explicit 0x63 +#define DW_AT_object_pointer 0x64 +#define DW_AT_endianity 0x65 +#define DW_AT_elemental 0x66 +#define DW_AT_pure 0x67 +#define DW_AT_recursive 0x68 +#define DW_AT_signature 0x69 +#define DW_AT_main_subprogram 0x6a +#define DW_AT_data_bit_offset 0x6b +#define DW_AT_const_expr 0x6c +#define DW_AT_enum_class 0x6d +#define DW_AT_linkage_name 0x6e +#define DW_AT_lo_user 0x2000 +#define DW_AT_hi_user 0x3fff + +#define DW_FORM_addr 0x01 +#define DW_FORM_block2 0x03 +#define DW_FORM_block4 0x04 +#define DW_FORM_data2 0x05 +#define DW_FORM_data4 0x06 +#define DW_FORM_data8 0x07 +#define DW_FORM_string 0x08 +#define DW_FORM_block 0x09 +#define DW_FORM_block1 0x0a +#define DW_FORM_data1 0x0b +#define DW_FORM_flag 0x0c +#define DW_FORM_sdata 0x0d +#define DW_FORM_strp 0x0e +#define DW_FORM_udata 0x0f +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_ref1 0x11 +#define DW_FORM_ref2 0x12 +#define DW_FORM_ref4 0x13 +#define DW_FORM_ref8 0x14 +#define DW_FORM_ref_udata 0x15 +#define DW_FORM_indirect 0x16 +#define DW_FORM_sec_offset 0x17 +#define DW_FORM_exprloc 0x18 +#define DW_FORM_flag_present 0x19 +#define DW_FORM_ref_sig8 0x20 + +#define DW_OP_addr 0x03 +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_const1s 0x09 +#define DW_OP_const2u 0x0a +#define DW_OP_const2s 0x0b +#define DW_OP_const4u 0x0c +#define DW_OP_const4s 0x0d +#define DW_OP_const8u 0x0e +#define DW_OP_const8s 0x0f +#define DW_OP_constu 0x10 +#define DW_OP_consts 0x11 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_xderef 0x18 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2a +#define DW_OP_gt 0x2b +#define DW_OP_le 0x2c +#define DW_OP_lt 0x2d +#define DW_OP_ne 0x2e +#define DW_OP_skip 0x2f +#define DW_OP_lit0 0x30 +#define DW_OP_lit1 0x31 +#define DW_OP_lit2 0x32 +#define DW_OP_lit3 0x33 +#define DW_OP_lit4 0x34 +#define DW_OP_lit5 0x35 +#define DW_OP_lit6 0x36 +#define DW_OP_lit7 0x37 +#define DW_OP_lit8 0x38 +#define DW_OP_lit9 0x39 +#define DW_OP_lit10 0x3a +#define DW_OP_lit11 0x3b +#define DW_OP_lit12 0x3c +#define DW_OP_lit13 0x3d +#define DW_OP_lit14 0x3e +#define DW_OP_lit15 0x3f +#define DW_OP_lit16 0x40 +#define DW_OP_lit17 0x41 +#define DW_OP_lit18 0x42 +#define DW_OP_lit19 0x43 +#define DW_OP_lit20 0x44 +#define DW_OP_lit21 0x45 +#define DW_OP_lit22 0x46 +#define DW_OP_lit23 0x47 +#define DW_OP_lit24 0x48 +#define DW_OP_lit25 0x49 +#define DW_OP_lit26 0x4a +#define DW_OP_lit27 0x4b +#define DW_OP_lit28 0x4c +#define DW_OP_lit29 0x4d +#define DW_OP_lit30 0x4e +#define DW_OP_lit31 0x4f +#define DW_OP_reg0 0x50 +#define DW_OP_reg1 0x51 +#define DW_OP_reg2 0x52 +#define DW_OP_reg3 0x53 +#define DW_OP_reg4 0x54 +#define DW_OP_reg5 0x55 +#define DW_OP_reg6 0x56 +#define DW_OP_reg7 0x57 +#define DW_OP_reg8 0x58 +#define DW_OP_reg9 0x59 +#define DW_OP_reg10 0x5a +#define DW_OP_reg11 0x5b +#define DW_OP_reg12 0x5c +#define DW_OP_reg13 0x5d +#define DW_OP_reg14 0x5e +#define DW_OP_reg15 0x5f +#define DW_OP_reg16 0x60 +#define DW_OP_reg17 0x61 +#define DW_OP_reg18 0x62 +#define DW_OP_reg19 0x63 +#define DW_OP_reg20 0x64 +#define DW_OP_reg21 0x65 +#define DW_OP_reg22 0x66 +#define DW_OP_reg23 0x67 +#define DW_OP_reg24 0x68 +#define DW_OP_reg25 0x69 +#define DW_OP_reg26 0x6a +#define DW_OP_reg27 0x6b +#define DW_OP_reg28 0x6c +#define DW_OP_reg29 0x6d +#define DW_OP_reg30 0x6e +#define DW_OP_reg31 0x6f +#define DW_OP_breg0 0x70 +#define DW_OP_breg1 0x71 +#define DW_OP_breg2 0x72 +#define DW_OP_breg3 0x73 +#define DW_OP_breg4 0x74 +#define DW_OP_breg5 0x75 +#define DW_OP_breg6 0x76 +#define DW_OP_breg7 0x77 +#define DW_OP_breg8 0x78 +#define DW_OP_breg9 0x79 +#define DW_OP_breg10 0x7a +#define DW_OP_breg11 0x7b +#define DW_OP_breg12 0x7c +#define DW_OP_breg13 0x7d +#define DW_OP_breg14 0x7e +#define DW_OP_breg15 0x7f +#define DW_OP_breg16 0x80 +#define DW_OP_breg17 0x81 +#define DW_OP_breg18 0x82 +#define DW_OP_breg19 0x83 +#define DW_OP_breg20 0x84 +#define DW_OP_breg21 0x85 +#define DW_OP_breg22 0x86 +#define DW_OP_breg23 0x87 +#define DW_OP_breg24 0x88 +#define DW_OP_breg25 0x89 +#define DW_OP_breg26 0x8a +#define DW_OP_breg27 0x8b +#define DW_OP_breg28 0x8c +#define DW_OP_breg29 0x8d +#define DW_OP_breg30 0x8e +#define DW_OP_breg31 0x8f +#define DW_OP_regx 0x90 +#define DW_OP_fbreg 0x91 +#define DW_OP_bregx 0x92 +#define DW_OP_piece 0x93 +#define DW_OP_deref_size 0x94 +#define DW_OP_xderef_size 0x95 +#define DW_OP_nop 0x96 +#define DW_OP_push_object_address 0x97 +#define DW_OP_call2 0x98 +#define DW_OP_call4 0x99 +#define DW_OP_call_ref 0x9a +#define DW_OP_form_tls_address 0x9b +#define DW_OP_call_frame_cfa 0x9c +#define DW_OP_bit_piece 0x9d +#define DW_OP_implicit_value 0x9e +#define DW_OP_stack_value 0x9f +#define DW_OP_lo_user 0xe0 +#define DW_OP_GNU_push_tls_address 0xe0 +#define DW_OP_hi_user 0xff + +#define DW_ATE_address 0x1 +#define DW_ATE_boolean 0x2 +#define DW_ATE_complex_float 0x3 +#define DW_ATE_float 0x4 +#define DW_ATE_signed 0x5 +#define DW_ATE_signed_char 0x6 +#define DW_ATE_unsigned 0x7 +#define DW_ATE_unsigned_char 0x8 +#define DW_ATE_imaginary_float 0x9 +#define DW_ATE_packed_decimal 0xa +#define DW_ATE_numeric_string 0xb +#define DW_ATE_edited 0xc +#define DW_ATE_signed_fixed 0xd +#define DW_ATE_unsigned_fixed 0xe +#define DW_ATE_decimal_float 0xf +#define DW_ATE_lo_user 0x80 +#define DW_ATE_hi_user 0xff + +#define DW_ACCESS_public 0x01 +#define DW_ACCESS_protected 0x02 +#define DW_ACCESS_private 0x03 + +#define DW_END_default 0x00 +#define DW_END_big 0x01 +#define DW_END_little 0x02 +#define DW_END_lo_user 0x40 +#define DW_END_high_user 0xff + +#define DW_VIS_local 0x01 +#define DW_VIS_exported 0x02 +#define DW_VIS_qualified 0x03 + +#define DW_VIRTUALITY_none 0x00 +#define DW_VIRTUALITY_virtual 0x01 +#define DW_VIRTUALITY_pure_virtual 0x02 + +#define DW_LANG_C89 0x0001 +#define DW_LANG_C 0x0002 +#define DW_LANG_Ada83 0x0003 +#define DW_LANG_C_plus_plus 0x0004 +#define DW_LANG_Cobol74 0x0005 +#define DW_LANG_Cobol85 0x0006 +#define DW_LANG_Fortran77 0x0007 +#define DW_LANG_Fortran90 0x0008 +#define DW_LANG_Pascal83 0x0009 +#define DW_LANG_Modula2 0x000a +#define DW_LANG_Java 0x000b +#define DW_LANG_C99 0x000c +#define DW_LANG_Ada95 0x000d +#define DW_LANG_Fortran95 0x000e +#define DW_LANG_PLI 0x000f +#define DW_LANG_ObjC 0x0010 +#define DW_LANG_ObjC_plus_plus 0x0011 +#define DW_LANG_UPC 0x0012 +#define DW_LANG_D 0x0013 +#define DW_LANG_lo_user 0x8000 +#define DW_LANG_hi_user 0xffff + +#define DW_ID_case_sensitive 0x00 +#define DW_ID_up_case 0x01 +#define DW_ID_down_case 0x02 +#define DW_ID_case_insensitive 0x03 + +#define DW_CC_normal 0x01 +#define DW_CC_program 0x02 +#define DW_CC_nocall 0x03 +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + +#define DW_INL_not_inlined 0x00 +#define DW_INL_inlined 0x01 +#define DW_INL_declared_not_inlined 0x02 +#define DW_INL_declared_inlined 0x03 + +#define DW_ORD_row_major 0x00 +#define DW_ORD_col_major 0x01 + +#define DW_DS_unsigned 0x01 +#define DW_DS_leading_overpunch 0x02 +#define DW_DS_trailing_overpunch 0x03 +#define DW_DS_leading_separate 0x04 +#define DW_DS_trailing_separate 0x05 + +#define DW_DSC_label 0x00 +#define DW_DSC_range 0x01 + +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_fixed_advance_pc 0x09 +#define DW_LNS_set_prologue_end 0x0a +#define DW_LNS_set_epilogue_begin 0x0b +#define DW_LNS_set_isa 0x0c + +#define DW_LNE_end_sequence 0x01 +#define DW_LNE_set_address 0x02 +#define DW_LNE_define_file 0x03 +#define DW_LNE_lo_user 0x80 +#define DW_LNE_hi_user 0xff + +#define DW_MACINFO_define 0x01 +#define DW_MACINFO_undef 0x02 +#define DW_MACINFO_start_file 0x03 +#define DW_MACINFO_end_file 0x04 +#define DW_MACINFO_vendor_ext 0xff + +#define DW_CFA_advance_loc 0x40 +#define DW_CFA_offset 0x80 +#define DW_CFA_restore 0xc0 +#define DW_CFA_extended 0 + +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_register 0x0d +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_def_cfa_expression 0x0f +#define DW_CFA_expression 0x10 +#define DW_CFA_offset_extended_sf 0x11 +#define DW_CFA_def_cfa_sf 0x12 +#define DW_CFA_def_cfa_offset_sf 0x13 +#define DW_CFA_val_offset 0x14 +#define DW_CFA_val_offset_sf 0x15 +#define DW_CFA_val_expression 0x16 +#define DW_CFA_lo_user 0x1c +#define DW_CFA_high_user 0x3f + +/* + * LSB(Linux Standard Base) extension to DWARF2. + */ + +#define DW_EH_PE_absptr 0x00 +#define DW_EH_PE_uleb128 0x01 +#define DW_EH_PE_udata2 0x02 +#define DW_EH_PE_udata4 0x03 +#define DW_EH_PE_udata8 0x04 +#define DW_EH_PE_sleb128 0x09 +#define DW_EH_PE_sdata2 0x0a +#define DW_EH_PE_sdata4 0x0b +#define DW_EH_PE_sdata8 0x0c +#define DW_EH_PE_pcrel 0x10 +#define DW_EH_PE_textrel 0x20 +#define DW_EH_PE_datarel 0x30 +#define DW_EH_PE_funcrel 0x40 +#define DW_EH_PE_aligned 0x50 +#define DW_EH_PE_omit 0xff + +#endif /* !_DWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/dwarf_abbrev.c b/contrib/elftoolchain/libdwarf/dwarf_abbrev.c new file mode 100644 index 0000000..448dc77 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_abbrev.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_abbrev.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, + Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length, + Dwarf_Unsigned *attr_count, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + int ret; + + if (dbg == NULL || return_abbrev == NULL || length == NULL || + attr_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error); + if (ret != DW_DLE_NONE) { + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else + return (DW_DLV_ERROR); + } + + *return_abbrev = ab; + *length = ab->ab_length; + *attr_count = ab->ab_atnum; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half *return_tag, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_tag == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_tag = (Dwarf_Half) abbrev->ab_tag; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned *return_code, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_code == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_code = abbrev->ab_entry; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed *return_flag, + Dwarf_Error *error) +{ + + if (abbrev == NULL || return_flag == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_flag = (Dwarf_Signed) abbrev->ab_children; + + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx, + Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, + Dwarf_Error *error) +{ + Dwarf_AttrDef ad; + int i; + + if (abbrev == NULL || attr_num == NULL || form == NULL || + offset == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) { + DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + ad = STAILQ_FIRST(&abbrev->ab_attrdef); + for (i = 0; i < ndx && ad != NULL; i++) + ad = STAILQ_NEXT(ad, ad_next); + + assert(ad != NULL); + + *attr_num = ad->ad_attrib; + *form = ad->ad_form; + *offset = ad->ad_offset; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 new file mode 100644 index 0000000..875e13d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_comp_dir.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_COMP_DIR 3 +.Sh NAME +.Nm dwarf_add_AT_comp_dir +.Nd create and attach a DW_AT_comp_dir attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_comp_dir +.Fa "Dwarf_P_Die die" +.Fa "char *dir" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_comp_dir +creates a +.Dv DW_AT_comp_dir +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Ar die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar dir +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_comp_dir +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_comp_dir +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_comp_dir +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar die +or +.Ar dir +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_producer 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 new file mode 100644 index 0000000..d617748 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 @@ -0,0 +1,126 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_const_value_string.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_CONST_VALUE_STRING 3 +.Sh NAME +.Nm dwarf_add_AT_const_value_signedint , +.Nm dwarf_add_AT_const_value_string , +.Nm dwarf_add_AT_const_value_unsignedint +.Nd create and attach a DW_AT_const_value attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_signedint +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Signed value" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_string +.Fa "Dwarf_P_Die die" +.Fa "char *str" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_const_value_unsignedint +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions create a +.Dv DW_AT_const_value +attribute descriptor and attach it to the debugging information entry +referenced by argument +.Ar die . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Function +.Fn dwarf_add_AT_const_value_signedint +creates a +.Dv DW_AT_const_value +attribute descriptor containing the signed value specified by argument +.Ar value . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_sdata . +.Pp +Function +.Fn dwarf_add_AT_const_value_unsignedint +creates a +.Dv DW_AT_const_value +attribute descriptor containing the unsigned value specified by +argument +.Ar value . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_udata . +.Pp +Function +.Fn dwarf_add_AT_const_value_string +creates a +.Dv DW_AT_const_value +attribute descriptor containing the string pointed to by the +NUL-terminated argument +.Ar str . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_strp . +.Pp +If argument +.Ar err +is not NULL, it will be used by these functions to store error +information in case of an error. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar die +or +.Ar str +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 new file mode 100644 index 0000000..29a09e0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_dataref.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_DATAREF 3 +.Sh NAME +.Nm dwarf_add_AT_dataref +.Nd create an attribute descriptor for a relocatable address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_dataref +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_dataref +creates an attribute descriptor for a relocatable address and attaches +it to the debugging information entry referenced by argument +.Ar die . +.Pp +If flag +.Dv DW_DLC_SIZE_64 +is set, the address value will be 8 bytes in size and of the DWARF form +.Dv DW_FORM_data8 . +Otherwise, the address value will be 4 bytes in size and of the DWARF form +.Dv DW_FORM_data4 . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +specifies the attribute code of the created attribute descriptor. +.Pp +Argument +.Ar pc_value +specifies the value of the relocatable address. +.Pp +Argument +.Ar sym_index +specifies the ELF symbol index of the symbol to be used for +relocation. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_dataref +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_dataref +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_dataref +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_reference 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 new file mode 100644 index 0000000..19b345e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_flag.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_FLAG 3 +.Sh NAME +.Nm dwarf_add_AT_flag +.Nd create and attach a flag attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_flag +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Small flag" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_flag +creates an attribute descriptor belonging to the +.Sq flag +class, and attaches it to the debugging information entry referenced +by argument +.Ar die . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_flag . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +should specify the attribute code for the new attribute descriptor. +.Pp +Argument +.Ar flag +should specify the value of the new attribute descriptor. +A zero value is treated as +.Sq false +and a non-zero value as +.Sq true . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_flag +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_flag +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_flag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 new file mode 100644 index 0000000..3c93273 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_location_expr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 5, 2011 +.Os +.Dt DWARF_ADD_AT_LOCATION_EXPR 3 +.Sh NAME +.Nm dwarf_add_AT_location_expr +.Nd create an attribute descriptor for a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_location_expr +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_P_Expr loc_expr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_location_expr +creates an attribute descriptor for a location expression and attaches +it to the debugging information entry referenced by argument +.Ar die . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +specifies the attribute code of the created attribute descriptor. +.Pp +Argument +.Ar loc_expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +The attribute created by function +.Fn dwarf_add_AT_location_expr +will have one of the DWARF forms +.Dv DW_FORM_block , +.Dv DW_FORM_block1 , +.Dv DW_FORM_block2 +or +.Dv DW_FORM_block4 , +depending on the size of the byte stream generated by the location +expression descriptor referenced by argument +.Ar loc_expr . +.Pp +If argument +.Ar err +is not NULL, it will be used by to store error information in case of +an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_location_expr +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_location_expr +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_location_expr +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar loc_expr +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_new_expr 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 new file mode 100644 index 0000000..d5ee761 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_name.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_NAME 3 +.Sh NAME +.Nm dwarf_add_AT_name +.Nd create and attach a DW_AT_name attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_name +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_name +creates a +.Dv DW_AT_name +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Ar die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar name +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_name +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_name +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_name +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_comp_dir 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_producer 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 new file mode 100644 index 0000000..ae0b088 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_producer.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_PRODUCER 3 +.Sh NAME +.Nm dwarf_add_AT_producer +.Nd create and attach a DW_AT_producer attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_producer +.Fa "Dwarf_P_Die die" +.Fa "char *producer" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_producer +creates a +.Dv DW_AT_producer +attribute descriptor and attaches it to the debugging information +entry referenced by argument +.Ar die . +The created attribute will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar producer +should point to a NUL-terminated string which will become the value of +the created attribute. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_producer +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_producer +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_producer +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar die +or +.Ar producer +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_comp_dir 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_add_AT_string 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 new file mode 100644 index 0000000..8b2efc8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_ref_address.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 7, 2011 +.Os +.Dt DWARF_ADD_AT_REF_ADDRESS 3 +.Sh NAME +.Nm dwarf_add_AT_ref_address +.Nd create a reference class attribute descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_ref_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_ref_address +creates a +.Sq reference +class attribute descriptor containing a relocatable address value. +The created attribute will use DWARF form +.Dv DW_FORM_ref_addr . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +specifies the attribute code of the created attribute. +.Pp +Argument +.Ar pc_value +contains a relocatable address which will become the value of the +created attribute. +.Pp +Argument +.Ar sym_index +should specify the ELF symbol index of the symbol to be used when +relocating the address value. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_ref_address +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_ref_address +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_ref_address +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_reference 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 new file mode 100644 index 0000000..4f6d51a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 @@ -0,0 +1,117 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_reference.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_REFERENCE 3 +.Sh NAME +.Nm dwarf_add_AT_reference +.Nd create and attach an attribute that references another DIE +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Attribute" +.Fo dwarf_add_AT_reference +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_P_Die ref_die" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_reference +creates an attribute descriptor that references another debugging +information entry in the same compilation unit. +The attribute will be of DWARF form +.Dv DW_FORM_ref4 +or +.Dv DW_FORM_ref8 +depending on the target address size, and will contain the +section-relative offset of the referenced debugging information entry +as its value. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +should specify the attribute code of the created attribute descriptor. +.Pp +Argument +.Ar ref_die +should hold the debugging information entry descriptor that +the attribute should refer to. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_reference +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_reference +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_reference +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar ref_die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 new file mode 100644 index 0000000..df7900d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 @@ -0,0 +1,131 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_signed_const.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_SIGNED_CONST 3 +.Sh NAME +.Nm dwarf_add_AT_signed_const , +.Nm dwarf_add_AT_unsigned_const +.Nd create and attach constant class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_signed_const +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Signed value" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_unsigned_const +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions create attribute descriptors belonging to the +.Sq constant +class +and attach them to the debugging information entry referenced by +argument +.Ar die . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +specifies the attribute code of the created attribute descriptor. +.Pp +Function +.Fn dwarf_add_AT_signed_const +creates an attribute descriptor with the signed value specified in +argument +.Ar value . +.Pp +Function +.Fn dwarf_add_AT_unsigned_const +creates an attribute descriptor with the unsigned value specified in +argument +.Ar value . +.Pp +The attribute created by these function will have one of the +DWARF forms +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 +or +.Dv DW_FORM_data8 , +depending on the size of the value specified in argument +.Ar value . +.Pp +If argument +.Ar err +is not NULL, it will be used by these functions to store error +information in case of an error. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_signedint 3 , +.Xr dwarf_add_AT_const_value_unsignedint 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_targ_address_b 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 new file mode 100644 index 0000000..a05a19d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 @@ -0,0 +1,114 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_string.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_STRING 3 +.Sh NAME +.Nm dwarf_add_AT_string +.Nd create and attach a string class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_string +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "char *str" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_string +creates an attribute descriptor belonging to the +.Sq string +class and attaches it to the debugging information entry referenced by +argument +.Ar die . +The created attribute descriptor will have DWARF form +.Dv DW_FORM_strp . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +should specify the attribute code for the created attribute +descriptor. +.Pp +Argument +.Ar str +should hold a pointer to a NUL-terminated string which will become the +value of the created attribute descriptor. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_AT_string +returns the created attribute descriptor. +In case of an error, function +.Fn dwarf_add_AT_string +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_AT_string +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar str +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_string 3 , +.Xr dwarf_add_AT_name 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 b/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 new file mode 100644 index 0000000..ce803c8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 @@ -0,0 +1,137 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_AT_targ_address.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_ADD_AT_TARG_ADDRESS 3 +.Sh NAME +.Nm dwarf_add_AT_targ_address , +.Nm dwarf_add_AT_targ_address_b +.Nd create and attach address class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_targ_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Signed sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Attribute +.Fo dwarf_add_AT_targ_address_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned pc_value" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_AT_targ_address_b +creates an attribute descriptor belonging to the +.Sq address +class and attaches it to the debugging information entry referenced by +argument +.Ar die . +.Pp +The created attribute descriptor will have DWARF form +.Dv DW_FORM_addr . +If flag +.Dv DW_DLC_SIZE_64 +is set on the producer instance, the attribute value will be 8 bytes +in size. +Otherwise the attribute value will be 4 bytes in size. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +should reference a debugging information entry allocated using +.Xr dwarf_new_die 3 . +.Pp +Argument +.Ar attr +should specify the attribute code of the created attribute descriptor. +.Pp +Argument +.Ar pc_value +should hold a relocatable address value which will become the value of +the created attribute descriptor. +.Pp +Argument +.Ar sym_index +should specify the ELF symbol index of the symbol to be used for +relocating the address value. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +Function +.Fn dwarf_add_AT_targ_address +is deprecated. +It is similar to function +.Fn dwarf_add_AT_targ_address_b +except that it cannot handle all possible symbol index values. +.Sh RETURN VALUES +On success, these functions return the created attribute descriptor. +In case of an error, these functions return +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar die +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_const_value_unsignedint 3 , +.Xr dwarf_add_AT_dataref 3 , +.Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_signed_const 3 , +.Xr dwarf_add_AT_unsigned_const 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 b/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 new file mode 100644 index 0000000..90a088a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 @@ -0,0 +1,151 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_arange.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 18, 2011 +.Os +.Dt DWARF_ADD_ARANGE 3 +.Sh NAME +.Nm dwarf_add_arange , +.Nm dwarf_add_arange_b +.Nd add address range information to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_arange +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr start" +.Fa "Dwarf_Unsigned length" +.Fa "Dwarf_Signed symbol_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_arange_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr start" +.Fa "Dwarf_Unsigned length" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Unsigned end_symbol_index" +.Fa "Dwarf_Addr offset_from_end_symbol" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_arange_b +adds an address range entry to a producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar start +specifies the relocatable start address of the address range. +.Pp +Argument +.Ar length +specifies the length of the address range. +.Pp +Argument +.Ar symbol_index +specifies the ELF symbol index of the first symbol to be used for +relocation. +.Pp +Argument +.Ar end_symbol_index +specifies the ELF symbol index of the second symbol to be used for +relocation. +.Bl -bullet +.It +If argument +.Ar end_symbol_index +is not 0, the +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the DWARF producer instance. +The address value specified by argument +.Ar start +will be treated as an offset value from the first symbol, +and the argument +.Ar offset_from_end_symbol +should hold an offset value from the second symbol. +Application code can retrieve the relocation entries for the +symbol pair by calling function +.Xr dwarf_get_relocation_info 3 . +The relocation entry for the first symbol will have type +.Dv dwarf_drt_first_of_length_pair +and the relocation entry for the second symbol will have type +.Dv dwarf_drt_second_of_length_pair . +.It +If argument +.Ar end_symbol_index +is 0, argument +.Ar offset_from_end_symbol +will be ignored and only one symbol is used for relocation. +.El +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +Function +.Fn dwarf_add_arange +is deprecated. +It is similar to function +.Fn dwarf_add_arange_b +except that it cannot handle all possible symbol index values +and supports only one relocation symbol. +.Sh RETURN VALUES +On success, these functions return a non-zero value. +In case of an error, these functions return 0 and set +the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar end_symbol_index +was non-zero, but the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 b/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 new file mode 100644 index 0000000..5ea4e3f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_die_to_debug.3 2938 2013-04-27 05:09:17Z jkoshy $ +.\" +.Dd August 21, 2011 +.Os +.Dt DWARF_ADD_DIE_TO_DEBUG 3 +.Sh NAME +.Nm dwarf_add_die_to_debug +.Nd set the root debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Unsigned +.Fo dwarf_add_die_to_debug +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die first_die" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_die_to_debug +sets the root debugging information entry of a DWARF producer +instance. +All debugging information entries linked to the root entry will also +be added to the producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar first_die +should hold the debugging information entry which will become +the root DIE. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_die_to_debug +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_add_die_to_debug +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_die_to_debug +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar first_die +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_die_link 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 b/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 new file mode 100644 index 0000000..df19707 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_directory_decl.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 17, 2011 +.Os +.Dt DWARF_ADD_DIRECTORY_DECL 3 +.Sh NAME +.Nm dwarf_add_directory_decl +.Nd add a directory name to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_directory_decl +.Fa "Dwarf_P_Debug dbg" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_directory_decl +adds a source directory name to a producer instance and returns the +index value generated for the directory name. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar name +should point a NUL-terminated string containing the name of +the directory. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_directory_decl +returns the index value generated for the directory. +In case of an error, function +.Fn dwarf_add_directory_decl +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_directory_decl +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar dbg +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 b/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 new file mode 100644 index 0000000..4a19ee8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_expr_addr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 9, 2011 +.Os +.Dt DWARF_ADD_EXPR_ADDR 3 +.Sh NAME +.Nm dwarf_add_expr_addr , +.Nm dwarf_add_expr_addr_b +.Nd add a DW_OP_addr location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_addr +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned address" +.Fa "Dwarf_Signed sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_addr_b +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned address" +.Fa "Dwarf_Unsigned sym_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_expr_addr_b +adds a +.Dv DW_OP_addr +location expression to the location expression descriptor referenced +by argument +.Ar expr . +.Pp +Argument +.Ar expr +should reference a location expression descriptor allocated using +the function +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Ar address +specifies the operand, a relocatable address value. +.Pp +Argument +.Ar sym_index +specifies the ELF symbol index of the symbol to be used for +relocation. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +Function +.Fn dwarf_add_expr_addr +is deprecated. +It is similar to function +.Fn dwarf_add_expr_addr_b +except that it cannot handle all possible symbol index values. +.Sh RETURN VALUES +On success, these functions return the size in bytes of the location +expression byte stream generated. +In case of an error, these functions return +.Dv DW_DLV_NOCOUNT +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar expr +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 b/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 new file mode 100644 index 0000000..71f2977 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_expr_gen.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 9, 2011 +.Os +.Dt DWARF_ADD_EXPR_GEN 3 +.Sh NAME +.Nm dwarf_add_expr_gen +.Nd add an operator to a location expression descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_expr_gen +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Small opcode" +.Fa "Dwarf_Unsigned val1" +.Fa "Dwarf_Unsigned val2" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_expr_gen +adds a location expression operator to the location expression +descriptor referenced by argument +.Ar expr . +.Pp +Argument +.Ar expr +should reference a location expression descriptor allocated using +the function +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Ar opcode +specifies the operation code of the location expression operator. +Valid values for this argument are those denoted by the +.Dv DW_OP_ Ns * +constants defined in +.In libdwarf.h . +.Pp +To generate a +.Dv DW_OP_addr +operation, application code should instead use +.Xr dwarf_add_expr_addr_b 3 . +.Pp +Argument +.Ar val1 +specifies the first operand of the location expression operator. +.Pp +Argument +.Ar val2 +specifies the second operand of the location expression operator. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_expr_gen +returns the size in bytes of the location expression byte stream +generated. +In case of an error, function +.Fn dwarf_add_expr_gen +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_expr_gen +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar expr +was NULL. +.It Bq Er DW_DLE_LOC_EXPR_BAD +The operation code specified in argument +.Ar opcode +was invalid. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 b/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 new file mode 100644 index 0000000..d2d9157 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_fde_inst.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 26, 2011 +.Os +.Dt DWARF_ADD_FDE_INST 3 +.Sh NAME +.Nm dwarf_add_fde_inst +.Nd add a call frame instruction to a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_add_fde_inst +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_Small op" +.Fa "Dwarf_Unsigned val1" +.Fa "Dwarf_Unsigned val2" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_fde_inst +adds a call frame instruction to the DWARF frame descriptor +referenced by argument +.Ar fde . +.Pp +Argument +.Ar fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Ar op +specifies the operator for the frame instruction. +The DWARF standard defines the set of legal values for this argument. +.Pp +Argument +.Ar val1 +specifies the first operand of the frame instruction. +.Pp +Argument +.Ar val2 +specifies the second operand of the frame instruction. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_fde_inst +returns the frame descriptor given in argument +.Ar fde . +In case of an error, function +.Fn dwarf_add_fde_inst +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_fde_inst +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar fde +was NULL. +.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR +The frame instruction operator specified in argument +.Ar op +was invalid. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_new_fde 3 +.Rs +.%T "The DWARF Debugging Information Format" +.%V "Version 4" +.%O "http://www.dwarfstd.org/" +.Re diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 b/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 new file mode 100644 index 0000000..c389484 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_file_decl.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 17, 2011 +.Os +.Dt DWARF_ADD_FILE_DECL 3 +.Sh NAME +.Nm dwarf_add_file_decl +.Nd add a source file entry to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_file_decl +.Fa "Dwarf_P_Debug dbg" +.Fa "char *name" +.Fa "Dwarf_Unsigned dirndx" +.Fa "Dwarf_Unsigned mtime" +.Fa "Dwarf_Unsigned size" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_file_decl +adds a source file entry to a producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name of +the source file. +.Pp +If the file name in argument +.Ar name +is not a fully qualified pathname, argument +.Ar dirndx +should specify the index of the directory where the source file resides. +Otherwise, argument +.Ar dirndx +should be 0. +Valid directory indices are those returned by the function +.Xr dwarf_add_directory_decl 3 . +.Pp +Argument +.Ar mtime +specifies the time when the file was last modified. +.Pp +Argument +.Ar size +specifies the size of the file in bytes. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_file_decl +returns the index value generated for the source file. +In case of an error, function +.Fn dwarf_add_file_decl +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_file_decl +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Ar dbg +or +.Ar name +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The length of the NUL-teminated string pointed to by argument +.Ar name +was 0. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 b/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 new file mode 100644 index 0000000..1bc6db5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 @@ -0,0 +1,124 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_frame_cie.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 26, 2011 +.Os +.Dt DWARF_ADD_FRAME_CIE 3 +.Sh NAME +.Nm dwarf_add_frame_cie +.Nd add a call frame common information entry to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_cie +.Fa "Dwarf_P_Debug dbg" +.Fa "char *augmenter" +.Fa "Dwarf_Small caf" +.Fa "Dwarf_Small daf" +.Fa "Dwarf_Small ra" +.Fa "Dwarf_Ptr initinst" +.Fa "Dwarf_Unsigned initlen" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_frame_cie +adds a DWARF call frame common information entry (CIE) to a producer +instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar augmenter +should point to a NUL-terminated augmentation string for the common +information entry. +.Pp +Argument +.Ar caf +specifies the code alignment factor. +.Pp +Argument +.Ar daf +specifies the data alignment factor. +.Pp +Argument +.Ar ra +specifies the column number used for the return address register. +.Pp +Argument +.Ar initinst +should point to a byte stream containing the initial instructions +for the common information entry. +.Pp +Argument +.Ar initlen +should hold the length in bytes of the byte stream pointed to by +argument +.Ar initinst . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_frame_cie +returns the index value of the created common information entry. +In case of an error, function +.Fn dwarf_add_frame_cie +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_frame_cie +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_new_fde 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 new file mode 100644 index 0000000..3c1ee11 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 @@ -0,0 +1,201 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_frame_fde.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 26, 2011 +.Os +.Dt DWARF_ADD_FRAME_FDE 3 +.Sh NAME +.Nm dwarf_add_frame_fde +.Nd add a call frame descriptor to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_fde +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned cie" +.Fa "Dwarf_Addr virt_addr" +.Fa "Dwarf_Unsigned code_len" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Error *err" +.Fc +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_frame_fde_b +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_Unsigned cie" +.Fa "Dwarf_Addr virt_addr" +.Fa "Dwarf_Unsigned code_len" +.Fa "Dwarf_Unsigned symbol_index" +.Fa "Dwarf_Unsigned end_symbol_index" +.Fa "Dwarf_Addr offset_from_end_sym" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_frame_fde_b +adds the call frame descriptor referenced by argument +.Ar fde +to a producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Ar die +is ignored by this implementation of the +.Lb libdwarf . +.Pp +Argument +.Ar cie +specifies the index of call frame common information entry for +the frame descriptor. +Valid indices are those returned by the function +.Xr dwarf_add_frame_cie 3 . +.Pp +Argument +.Ar symbol_index +specifies the ELF symbol index of the first symbol to be used for +relocation. +.Pp +The meaning of the arguments +.Ar virt_addr , +.Ar code_len +and +.Ar offset_from_end_sym +depend on the value of argument +.Ar end_symbol_index : +.Bl -bullet +.It +If the argument +.Ar end_symbol_index +is zero, the argument +.Ar virt_addr +specifies the relocatable address of the start of the function +associated with the frame descriptor, the argument +.Ar code_len +specifies the size in bytes of the machine instructions for this +function, the argument +.Ar symbol_index +specifies the ELF symbol to be used for relocating the address in +argument +.Ar virt_addr , +and the argument +.Ar offset_from_end_symbol +is ignored. +.It +If the argument +.Ar end_symbol_index +is non-zero, it specifies the ELF symbol index of the second symbol to +be used for relocation. +In this case, the argument +.Ar virt_addr +specifies an offset from the relocatable symbol specified by argument +.Ar symbol_index , +the argument +.Ar offset_from_end_symbol +should specify an offset from the symbol named by the argument +.Ar end_symbol_index , +and the argument +.Ar code_len +will be ignored. +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should also have been set on the DWARF producer instance. +.Pp +Application code can retrieve the relocation entries for the symbol +pair by calling function +.Xr dwarf_get_relocation_info 3 . +The relocation entry for the first symbol will have type +.Dv dwarf_drt_first_of_length_pair +and the relocation entry for the second symbol will have type +.Dv dwarf_drt_second_of_length_pair . +.El +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +Function +.Fn dwarf_add_frame_fde +is similar to function +.Fn dwarf_add_frame_fde_b +except that it supports only one relocation symbol. +.Sh RETURN VALUES +On success, these functions return the index value for +the added frame descriptor. +In case of an error, these functions return +.Dv DW_DLV_NOCOUNT +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg +or +.Ar fde +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The frame descriptor referenced by argument +.Ar fde +did not belong to the producer instance referenced by argument +.Ar dbg . +.It Bq Er DW_DLE_ARGUMENT +The common information entry index specified by argument +.Ar cie +was invalid. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar end_symbol_index +was non-zero, but the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_fde_cfa_offset 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_new_fde 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 new file mode 100644 index 0000000..ebc358c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_funcname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_ADD_FUNCNAME 3 +.Sh NAME +.Nm dwarf_add_funcname +.Nd add information about a static function to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_funcname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_funcname +adds information about a static function to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +specifies the debugging information entry associated with the static +function. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the static function. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_funcname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_funcname +returns 0 and sets +the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_funcname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 new file mode 100644 index 0000000..2237717 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 @@ -0,0 +1,163 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_line_entry.3 2953 2013-06-30 20:21:38Z kaiwang27 $ +.\" +.Dd June 30, 2013 +.Os +.Dt DWARF_ADD_LINE_ENTRY 3 +.Sh NAME +.Nm dwarf_add_line_entry +.Nd add a line number information entry to a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_line_entry +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned filendx" +.Fa "Dwarf_Addr off" +.Fa "Dwarf_Unsigned lineno" +.Fa "Dwarf_Signed column" +.Fa "Dwarf_Bool is_stmt" +.Fa "Dwarf_Bool basic_block" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_line_entry +adds a line number information entry to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar filendx +specifies the index of the source file that contains the source line +in question. +Valid source file indices are those returned by the function +.Xr dwarf_add_file_decl 3 . +.Pp +Argument +.Ar off +specifies a relocatable program address. The ELF symbol to be used +for relocation is set by a prior call to the function +.Xr dwarf_lne_set_address 3 . +.Pp +Argument +.Ar lineno +specifies the line number of the source line. +.Pp +Argument +.Ar column +specifies the column number within the source line. +.Pp +If the argument +.Ar is_stmt +is set to true, it indicates that the instruction at the address +specified by argument +.Ar off +is a recommended breakpoint location, i.e., the first instruction in +the instruction sequence generated by the source line. +.Pp +If the argument +.Ar basic_block +is set to true, it indicates that the instruction at the address +specified by argument +.Ar off +is the first instruction of a basic block. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_line_entry +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_add_line_entry +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_line_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The function +.Xr dwarf_lne_set_address 3 +was not called before calling this function. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh EXAMPLE +To add line number information to the producer instance, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; +Dwarf_Unsigned dir, filendx; + +/* ... assume dbg refers to a DWARF producer instance ... */ + +dir = dwarf_add_directory_decl(dbg, "/home/foo", &de); +if (dir == DW_DLV_NOCOUNT) + errx(EXIT_FAILURE, "dwarf_add_directory_decl failed: %s", + dwarf_errmsg(-1)); + +filendx = dwarf_add_file_decl(dbg, "bar.c", dir, 0, 1234, &de); +if (filendx == DW_DLV_NOCOUNT) + errx(EXIT_FAILURE, "dwarf_add_file_decl failed: %s", + dwarf_errmsg(-1)); + +if (dwarf_lne_set_address(dbg, 0x4012b0, 12, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_lne_set_address failed: %s", + dwarf_errmsg(-1)); + +if (dwarf_add_line_entry(dbg, filendx, 10, 258, 0, 1, 1, &de) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_add_line_entry failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 new file mode 100644 index 0000000..8839178 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_pubname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_ADD_PUBNAME 3 +.Sh NAME +.Nm dwarf_add_pubname +.Nd add information about a global object to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_pubname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_pubname +adds information about a global object to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +specifies the debugging information entry associated with the global +object. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the global object. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_pubname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_pubname +returns 0 and sets +the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_pubname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 b/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 new file mode 100644 index 0000000..22a2b06 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_typename.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_ADD_TYPENAME 3 +.Sh NAME +.Nm dwarf_add_typename +.Nd add information about a user-defined type to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_typename +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_typename +adds information about a user-defined type to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +specifies the debugging information entry associated with the +user-defined type. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the user-defined type. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_typename +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_typename +returns 0 and sets +the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_typename +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 new file mode 100644 index 0000000..efcb0d3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_varname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_ADD_VARNAME 3 +.Sh NAME +.Nm dwarf_add_varname +.Nd add information about a static variable to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_varname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_varname +adds information about a static variable to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +specifies the debugging information entry associated with the static +variable. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the static variable. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_varname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_varname +returns 0 and sets +the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_varname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_weakname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 b/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 new file mode 100644 index 0000000..ac1ecbd --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_add_weakname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_ADD_WEAKNAME 3 +.Sh NAME +.Nm dwarf_add_weakname +.Nd add information about a weak object to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_add_weakname +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_P_Die die" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_add_weakname +adds information about a weak object to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar die +specifies the debugging information entry associated with the weak +object. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the weak object. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_add_weakname +returns a non-zero value. +In case of an error, function +.Fn dwarf_add_weakname +returns 0 and sets +the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_add_weakname +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar die +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_funcname 3 , +.Xr dwarf_add_pubname 3 , +.Xr dwarf_add_typename 3 , +.Xr dwarf_add_varname 3 , +.Xr dwarf_new_die 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_arange.c b/contrib/elftoolchain/libdwarf/dwarf_arange.c new file mode 100644 index 0000000..46b42cb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_arange.c @@ -0,0 +1,171 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_arange.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_get_aranges(Dwarf_Debug dbg, Dwarf_Arange **arlist, + Dwarf_Signed *ret_arange_cnt, Dwarf_Error *error) +{ + + if (dbg == NULL || arlist == NULL || ret_arange_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_arange_cnt == 0) { + if (_dwarf_arange_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_arange_cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + assert(dbg->dbg_arange_array != NULL); + + *arlist = dbg->dbg_arange_array; + *ret_arange_cnt = dbg->dbg_arange_cnt; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange(Dwarf_Arange *arlist, Dwarf_Unsigned arange_cnt, + Dwarf_Addr addr, Dwarf_Arange *ret_arange, Dwarf_Error *error) +{ + Dwarf_Arange ar; + Dwarf_Debug dbg; + int i; + + if (arlist == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + dbg = (*arlist)->ar_as->as_cu->cu_dbg; + + if (ret_arange == NULL || arange_cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + for (i = 0; (Dwarf_Unsigned)i < arange_cnt; i++) { + ar = arlist[i]; + if (addr >= ar->ar_address && addr < ar->ar_address + + ar->ar_range) { + *ret_arange = ar; + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_get_cu_die_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + cu = as->as_cu; + assert(cu != NULL); + + if (ret_offset == NULL) { + DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange_cu_header_offset(Dwarf_Arange ar, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + + if (ret_offset == NULL) { + DWARF_SET_ERROR(as->as_cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = as->as_cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_arange_info(Dwarf_Arange ar, Dwarf_Addr *start, + Dwarf_Unsigned *length, Dwarf_Off *cu_die_offset, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + + if (ar == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + as = ar->ar_as; + assert(as != NULL); + cu = as->as_cu; + assert(cu != NULL); + + if (start == NULL || length == NULL || + cu_die_offset == NULL) { + DWARF_SET_ERROR(cu->cu_dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *start = ar->ar_address; + *length = ar->ar_range; + *cu_die_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.3 b/contrib/elftoolchain/libdwarf/dwarf_attr.3 new file mode 100644 index 0000000..b1e3001 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_attr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd April 8, 2010 +.Os +.Dt DWARF_ATTR 3 +.Sh NAME +.Nm dwarf_attr +.Nd retrieve an attribute descriptor associated with a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attr +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Attribute *atp" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attr +retrieves the attribute descriptor for an attribute associated +with the DWARF debugging information entry descriptor in +argument +.Ar die . +.Pp +DWARF attribute descriptors are represented by value of the opaque +type +.Vt Dwarf_Attribute , +see +.Xr dwarf 3 . +.Pp +Argument +.Ar attr +names the desired DWARF attribute. +Legal values for argument +.Ar attr +are those denoted by the +.Dv DW_AT_* +constants in the DWARF specification. +.Pp +Argument +.Ar atp +points to a location into which the returned attribute descriptor +will be written. +The returned descriptor may then be passed to the form query functions in the +.Xr dwarf 3 +API set to access the data associated with the attribute. +.Pp +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_attr +returns +.Dv DW_DLV_OK on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Ar die +does not contain the named attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Ar err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_attr +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar die +or +.Ar atp +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar die +had no attribute corresponding to the value +in argument +.Ar attr . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attrlist 3 , +.Xr dwarf_hasattr 3 , +.Xr dwarf_hasform 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attr.c b/contrib/elftoolchain/libdwarf/dwarf_attr.c new file mode 100644 index 0000000..ce40294 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attr.c @@ -0,0 +1,275 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_attr.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Attribute at; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || atp == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *atp = at; + + return (DW_DLV_OK); +} + +int +dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute **attrbuf, + Dwarf_Signed *attrcount, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || attrbuf == NULL || attrcount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_ab->ab_atnum == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *attrcount = die->die_ab->ab_atnum; + + if (die->die_attrarray != NULL) { + *attrbuf = die->die_attrarray; + return (DW_DLV_OK); + } + + if ((die->die_attrarray = malloc(*attrcount * sizeof(Dwarf_Attribute))) + == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, at = STAILQ_FIRST(&die->die_attr); + i < *attrcount && at != NULL; i++, at = STAILQ_NEXT(at, at_next)) + die->die_attrarray[i] = at; + + *attrbuf = die->die_attrarray; + + return (DW_DLV_OK); +} + +int +dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = (_dwarf_attr_find(die, attr) != NULL); + + return (DW_DLV_OK); +} + +int +dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_lowpc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_lowpc = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_highpc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_highpc = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_byte_size)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_bit_size)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_bit_offset)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_size = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_srclang(Dwarf_Die die, Dwarf_Unsigned *ret_lang, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_lang == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_language)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_lang = at->u[0].u64; + + return (DW_DLV_OK); +} + +int +dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_order == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_order = at->u[0].u64; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 b/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 new file mode 100644 index 0000000..0cb918d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 @@ -0,0 +1,146 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_attrlist.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_ATTRLIST 3 +.Sh NAME +.Nm dwarf_attrlist +.Nd retrieve DWARF attribute descriptors +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attrlist +.Fa "Dwarf_Die die" +.Fa "Dwarf_Attribute **attrbuf" +.Fa "Dwarf_Signed *attrcount" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attrlist +retrieves the DWARF attribute descriptors associated with a +debugging information entry descriptor in argument +.Ar die . +The descriptors are returned as an array of values of the opaque type +.Vt Dwarf_Attribute . +The data associated with each returned attribute descriptor may be +queried using the form query functions in the +.Xr dwarf 3 +API set. +.Pp +Argument +.Ar attrbuf +points to a location that will hold a pointer to the returned +array of DWARF attribute descriptors. +Argument +.Ar attrcount +points to a location that will hold the number of descriptors in +the returned array. +.Pp +If argument +.Ar err +is non-NULL, it is used to return an error descriptor in case of an +error. +.Ss Memory Management +In the current implementation, the memory allocated for each DWARF +attribute descriptor and for the returned array of descriptors is +managed by the library and the application does not need to explicitly +free the returned pointers. +However, for compatibility with other implementations of the +.Xr dwarf 3 +API, the application is permitted to pass the pointers returned by to +the +.Fn dwarf_dealloc +function. +.Sh RETURN VALUES +Function +.Fn dwarf_attrlist +returns +.Dv DW_DLV_OK on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Ar die +does not contain any attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Ar err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh EXAMPLES +To retrieve the attribute list for a DWARF debugging information +entry use: +.Bd -literal -offset indent +Dwarf_Die dw_die; +Dwarf_Error dw_e; +Dwarf_Unsigned dw_count; +Dwarf_Attribute *dw_attributes; +int error, i; + +\&... variable dw_die contains a reference to the DIE of interest ... + +/* Retrieve the attribute list from the DIE. */ +if ((error = dwarf_attrlist(dw_die, &dw_attributes, &dw_count, + &dw_e)) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_attrlist: %s", dwarf_errmsg(dw_e)); + +/* Process the attribute list. */ +for (i = 0; i < dw_count; ++i) { + /* Use the returned pointers in dw_attributes[i] here. */ +} +.Ed +.Sh ERRORS +Function +.Fn dwarf_diename +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Ar die , +.Ar attrbuf , +or +.Ar attrcount +were NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar die +had no attributes. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_hasattr 3 , +.Xr dwarf_hasform 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval.c b/contrib/elftoolchain/libdwarf/dwarf_attrval.c new file mode 100644 index 0000000..0f17016 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval.c @@ -0,0 +1,210 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_flag: + *valp = (Dwarf_Bool) (!!at->u[0].u64); + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || strp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *strp = NULL; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_strp: + *strp = at->u[1].s; + break; + case DW_FORM_string: + *strp = at->u[0].s; + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + if ((at = _dwarf_attr_find(die, attr)) == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + switch (at->at_form) { + case DW_FORM_data1: + *valp = (int8_t) at->u[0].s64; + break; + case DW_FORM_data2: + *valp = (int16_t) at->u[0].s64; + break; + case DW_FORM_data4: + *valp = (int32_t) at->u[0].s64; + case DW_FORM_data8: + case DW_FORM_sdata: + *valp = at->u[0].s64; + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +int +dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err) +{ + Dwarf_Attribute at; + Dwarf_Die die1; + Dwarf_Unsigned val; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || valp == NULL) { + DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *valp = 0; + + if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) { + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + die1 = NULL; + if (at == NULL && + (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) { + switch (at->at_form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + val = at->u[0].u64; + if ((die1 = _dwarf_die_find(die, val)) == NULL || + (at = _dwarf_attr_find(die1, attr)) == NULL) { + if (die1 != NULL) + dwarf_dealloc(dbg, die1, DW_DLA_DIE); + DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + break; + default: + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + } + + switch (at->at_form) { + case DW_FORM_addr: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + *valp = at->u[0].u64; + break; + default: + if (die1 != NULL) + dwarf_dealloc(dbg, die1, DW_DLA_DIE); + DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + if (die1 != NULL) + dwarf_dealloc(dbg, die1, DW_DLA_DIE); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 new file mode 100644 index 0000000..9646990 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 @@ -0,0 +1,205 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_attrval_signed.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" +.Dd January 29, 2011 +.Os +.Dt DWARF_ATTRVAL_SIGNED 3 +.Sh NAME +.Nm dwarf_attrval_flag , +.Nm dwarf_attrval_signed , +.Nm dwarf_attrval_string , +.Nm dwarf_attrval_unsigned +.Nd retrieve the value of an attribute within a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attrval_flag +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_signed +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_string +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "const char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_attrval_unsigned +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions search the debugging information entry referenced +by argument +.Ar die +for the attribute named by argument +.Ar attr . +If the named attribute is found, the functions set the location +pointed to by argument +.Ar ret +to the value of the attribute. +The argument +.Ar err , +if non NULL, +will be used to return an error descriptor in case of an error. +.Pp +Function +.Fn dwarf_attrval_flag +sets the location pointed to by argument +.Ar ret +to 1 if the attribute named by argument +.Ar attr +has a non-zero value, or to 0 otherwise. +The form of the attribute named by argument +.Ar attr +must be +.Dv DW_FORM_flag . +.Pp +Function +.Fn dwarf_attrval_signed +stores the value for the attribute named by argument +.Ar attr , +into the location pointed to by argument +.Ar ret . +The attribute's value is treated as a signed integral quantity and is +sign-extended as needed. +The attribute named by the argument +.Ar attr +must belong to the +.Dv CONSTANT +class and must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +or +.Dv DW_FORM_sdata . +.Pp +Function +.Fn dwarf_attrval_string +sets the location pointed to by argument +.Ar ret +to a pointer to a NUL-terminated string that is the value of the +attribute named by argument +.Ar attr . +The form of the attribute must be one of +.Dv DW_FORM_string +or +.Dv DW_FORM_strp . +.Pp +Function +.Fn dwarf_attrval_unsigned +stores the value for the attribute named by argument +.Ar attr +into the location pointed to by argument +.Ar ret . +The attribute's value is treated as an unsigned integral quantity, and +is zero-extended as needed. +The named attribute must belong to one of the +.Dv CONSTANT , +.Dv ADDRESS +or +.Dv REFERENCE +classes and must have one of the following forms: +.Dv DW_FORM_addr , +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 , +.Dv DW_FORM_udata , +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 , +or +.Dv DW_FORM_ref_udata . +.Pp +If the attribute named by argument +.Ar attr +is not present in the debugging information entry referenced by +argument +.Ar die , +and if a +.Dv DW_AT_abstract_origin +attribute is present in the debugging information entry, +function +.Fn dwarf_attrval_unsigned +will search for the named attribute in the debugging information entry +referenced by the +.Dv DW_AT_abstract_origin +attribute. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +If the named attribute was not found in the specified debugging +information entry descriptor these functions return +.Dv DW_DLV_NO_ENTRY +and set argument +.Ar err . +For other errors, these functions return +.Dv DW_DLV_ERROR +and set argument +.Ar err . +.Sh COMPATIBILITY +These functions are extensions added by this implementation of the +DWARF(3) API. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Va die +or +.Va ret +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar die +did not contain an attribute corresponding to the value in argument +.Ar attr . +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute named by argument +.Ar attr +was not of a permitted form. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_child.3 b/contrib/elftoolchain/libdwarf/dwarf_child.3 new file mode 100644 index 0000000..57549c0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_child.3 @@ -0,0 +1,202 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_child.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_CHILD 3 +.Sh NAME +.Nm dwarf_child , +.Nm dwarf_siblingof , +.Nm dwarf_offdie +.Nd retrieve DWARF Debugging Information Entry descriptors +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err" +.Ft int +.Fo dwarf_siblingof +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Die die" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_offdie +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to retrieve and traverse DWARF +Debugging Information Entry (DIE) descriptors associated with +a compilation unit. +These descriptors are arranged in the form of a tree, traversable +using +.Dq child +and +.Dq sibling +links; see +.Xr dwarf 3 +for more information. +DWARF Debugging Information Entry descriptors are represented +by the +.Vt Dwarf_Die +opaque type. +.Pp +Function +.Fn dwarf_child +retrieves the child of descriptor denoted by argument +.Ar die , +and stores it in the location pointed to by argument +.Ar ret_die . +.Pp +Function +.Fn dwarf_siblingof +retrieves the sibling of the descriptor denoted by argument +.Ar die , +and stores it in the location pointed to by argument +.Ar ret_die . +If argument +.Ar die +is NULL, the first debugging information entry descriptor for the +current compilation unit will be returned. +This function and function +.Fn dwarf_child +may be used together to traverse the tree of debugging information +entry descriptors for a compilation unit. +.Pp +Function +.Fn dwarf_offdie +retrieves the debugging information entry descriptor at global offset +.Ar offset +in the +.Dq .debug_info +section of the object associated with argument +.Ar dbg . +The returned descriptor is written to the location pointed to by argument +.Ar ret_die . +.Ss Memory Management +The memory area used for the +.Vt Dwarf_Die +descriptor returned in argument +.Ar ret_die +is allocated by the +.Lb libdwarf . +Application code should use function +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_DIE +to free the memory area when the +.Vt Dwarf_Die +descriptor is no longer needed. +.Sh RETURN VALUES +These functions return the following values: +.Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" +.It Bq Er DW_DLV_OK +The call succeeded. +.It Bq Er DW_DLV_ERROR +The requested operation failed. +Additional information about the error encountered will be recorded in +argument +.Ar err , +if it is not NULL. +.It Bq Er DW_DLV_NO_ENTRY +For functions +.Fn dwarf_child +and +.Fn dwarf_siblingof , +the descriptor denoted by argument +.Ar die +did not have a child or sibling. +For function +.Fn dwarf_offdie , +there was no debugging information entry at the offset specified by +argument +.Ar offset . +.El +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_DIE_NO_CU_CONTEXT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Ar dbg , +.Ar die +or +.Ar ret_die +were NULL. +.It Bq Er DW_DLE_DIE_NO_CU_CONTEXT +Argument +.Ar dbg +was not associated with a compilation unit. +.It Bq Er DW_DLE_NO_ENTRY +The descriptor denoted by argument +.Ar die +had no child or sibling, or there was no DWARF debugging information +entry at the offset specified by argument +.Va offset . +.El +.Sh EXAMPLES +To retrieve the first DWARF Debugging Information Entry descriptor for +the first compilation unit associated with a +.Vt Dwarf_Debug +instance, and to traverse all its children, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Die die, die0; +Dwarf_Error de; + +\&... allocate dbg using dwarf_init() etc ... + +if (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &de) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", + dwarf_errmsg(de)); + +/* Get the first DIE for the current compilation unit. */ +die = NULL; +if (dwarf_siblingof(dbg, die, &die0, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de)); + +/* Get the first child of this DIE. */ +die = die0; +if (dwarf_child(die, &die0, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_child: %s", dwarf_errmsg(de)); + +/* Get the rest of children. */ +do { + die = die0; + if (dwarf_siblingof(dbg, die, &die0, &de) == DW_DLV_ERROR) + errx(EXIT_FAILURE, "dwarf_siblingof: %s", + dwarf_errmsg(de)); +} while (die0 != NULL); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_next_cu_header 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_cu.c b/contrib/elftoolchain/libdwarf/dwarf_cu.c new file mode 100644 index 0000000..c203dc2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_cu.c @@ -0,0 +1,99 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_cu.c 2072 2011-10-27 03:26:49Z jkoshy $"); + +int +dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, + Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, + Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size, + Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset, + Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_cu_current == NULL) + ret = _dwarf_info_first_cu(dbg, error); + else + ret = _dwarf_info_next_cu(dbg, error); + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (dbg->dbg_cu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_cu_current; + + if (cu_length) + *cu_length = cu->cu_length; + if (cu_version) + *cu_version = cu->cu_version; + if (cu_abbrev_offset) + *cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset; + if (cu_pointer_size) + *cu_pointer_size = cu->cu_pointer_size; + if (cu_offset_size) { + if (cu->cu_length_size == 4) + *cu_offset_size = 4; + else + *cu_offset_size = 8; + } + if (cu_extension_size) { + if (cu->cu_length_size == 4) + *cu_extension_size = 0; + else + *cu_extension_size = 4; + } + if (cu_next_offset) + *cu_next_offset = dbg->dbg_cu_current->cu_next_offset; + + return (DW_DLV_OK); +} + +int +dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, + Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, + Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset, + Dwarf_Error *error) +{ + + return (dwarf_next_cu_header_b(dbg, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset, + error)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 b/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 new file mode 100644 index 0000000..51d355b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2009-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_dealloc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 23, 2011 +.Os +.Dt DWARF_DEALLOC 3 +.Sh NAME +.Nm dwarf_dealloc , +.Nm dwarf_fde_cie_list_dealloc , +.Nm dwarf_funcs_dealloc , +.Nm dwarf_globals_dealloc , +.Nm dwarf_pubtypes_dealloc , +.Nm dwarf_ranges_dealloc , +.Nm dwarf_srclines_dealloc , +.Nm dwarf_types_dealloc , +.Nm dwarf_vars_dealloc , +.Nm dwarf_weaks_dealloc +.Nd release resources +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft void +.Fo dwarf_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr ptr" +.Fa "Dwarf_Unsigned type" +.Fc +.Fo dwarf_fde_cie_list_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie *cie_list" +.Fa "Dwarf_Signed cie_count" +.Fa "Dwarf_Fde *fde_list" +.Fa "Dwarf_Signed fde_count" +.Fc +.Ft void +.Fo dwarf_funcs_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Func *funcs" +.Fa "Dwarf_Signed funccount" +.Fc +.Ft void +.Fo dwarf_globals_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Global *globals" +.Fa "Dwarf_Signed globalcount" +.Fc +.Ft void +.Fo dwarf_pubtypes_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type *pubtypes" +.Fa "Dwarf_Signed pubtypecount" +.Fc +.Ft void +.Fo dwarf_ranges_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ranges *ranges" +.Fa "Dwarf_Signed rangecount" +.Fc +.Ft void +.Fo dwarf_srclines_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Line *lines" +.Fa "Dwarf_Signed linecount" +.Fc +.Ft void +.Fo dwarf_types_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type *types" +.Fa "Dwarf_Signed typecount" +.Fc +.Ft void +.Fo dwarf_vars_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Var *vars" +.Fa "Dwarf_Signed varcount" +.Fc +.Ft void +.Fo dwarf_weaks_dealloc +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Weak *weaks" +.Fa "Dwarf_Signed weakcount" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_dealloc +is used by applications to indicate that memory areas returned by +.Lb libdwarf +may be safely disposed off. +Due to the way memory is managed in the current implementation, the +use of +.Fn dwarf_dealloc +is only necessary for a small set of DWARF types. +.Pp +Argument +.Ar dbg +should reference a valid debugging context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar ptr +should point to an object or memory area obtained by a prior call +to a DWARF(3) function. +.Pp +Argument +.Ar type +indicates the type of object being deallocated. +The indicated type must match that of the object being passed in +argument +.Ar ptr . +Valid values for the +.Ar type +argument are: +.Bl -tag -width ".Dv DW_DLA_FRAME_BLOCK" +.It Dv DW_DLA_ABBREV +An object of type +.Vt Dwarf_Abbrev , +as returned by a call to the function +.Xr dwarf_get_abbrev 3 . +.It Dv DW_DLA_DIE +An object of type +.Vt Dwarf_Die , +as returned by calls to the functions +.Xr dwarf_child 3 , +.Xr dwarf_offdie 3 +or +.Xr dwarf_siblingof 3 . +.It Dv DW_DLA_FRAME_BLOCK +An array of objects of type +.Vt Dwarf_Frame_op , +as returned by a call to the function +.Xr dwarf_expand_frame_instructions 3 . +.El +.Pp +Calls to +.Fn dwarf_dealloc +with other values for argument +.Ar type +are no-ops in this implementation. +.Pp +The functions +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc +and +.Fn dwarf_weaks_dealloc +are provided for compatibility with other implementations of the +DWARF(3) API. +Due to the way memory is managed in the current implementation, these +functions are effectively no-ops. +.Pp +See +.Xr dwarf 3 +for more information about the memory management scheme in this +implementation of the DWARF(3) API. +.Sh RETURN VALUES +Functions +.Fn dwarf_dealloc , +.Fn dwarf_fde_cie_list_dealloc , +.Fn dwarf_funcs_dealloc , +.Fn dwarf_globals_dealloc , +.Fn dwarf_pubtypes_dealloc , +.Fn dwarf_ranges_dealloc , +.Fn dwarf_srclines_dealloc , +.Fn dwarf_types_dealloc , +.Fn dwarf_vars_dealloc +and +.Fn dwarf_weaks_dealloc +have no return value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_child 3 , +.Xr dwarf_expand_frame_instructions 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_offdie 3 , +.Xr dwarf_siblingof 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dealloc.c b/contrib/elftoolchain/libdwarf/dwarf_dealloc.c new file mode 100644 index 0000000..eb7ed1c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dealloc.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_dealloc.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +void +dwarf_dealloc(Dwarf_Debug dbg, Dwarf_Ptr p, Dwarf_Unsigned alloc_type) +{ + Dwarf_Abbrev ab; + Dwarf_AttrDef ad, tad; + Dwarf_Attribute at, tat; + Dwarf_Die die; + + /* + * This libdwarf implementation does not use the SGI/libdwarf + * style of memory allocation. In most cases it does not copy + * things to return to the client, so the client does not need + * to remember to free them. The remaining cases are handled + * below. + */ + + (void) dbg; + + if (alloc_type == DW_DLA_LIST || alloc_type == DW_DLA_FRAME_BLOCK || + alloc_type == DW_DLA_LOC_BLOCK || alloc_type == DW_DLA_LOCDESC) + free(p); + else if (alloc_type == DW_DLA_ABBREV) { + ab = p; + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + free(ab); + } else if (alloc_type == DW_DLA_DIE) { + die = p; + STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { + STAILQ_REMOVE(&die->die_attr, at, + _Dwarf_Attribute, at_next); + if (at->at_ld != NULL) + free(at->at_ld); + free(at); + } + if (die->die_attrarray) + free(die->die_attrarray); + free(die); + } +} + +void +dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line *linebuf, + Dwarf_Signed count) +{ + /* + * In this libdwarf implementation, line information remains + * associated with the DIE for a compilation unit for the + * lifetime of the DIE. The client does not need to free + * the memory returned by `dwarf_srclines()`. + */ + + (void) dbg; (void) linebuf; (void) count; +} + +void +dwarf_ranges_dealloc(Dwarf_Debug dbg, Dwarf_Ranges *ranges, + Dwarf_Signed range_count) +{ + /* + * In this libdwarf implementation, ranges information is + * kept by a STAILQ inside Dwarf_Debug object. The client + * does not need to free the memory returned by + * `dwarf_get_ranges()` or `dwarf_get_ranges_a()`. + */ + + (void) dbg; (void) ranges; (void) range_count; +} + +void +dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, Dwarf_Cie *cie_list, + Dwarf_Signed cie_count, Dwarf_Fde *fde_list, Dwarf_Signed fde_count) +{ + /* + * In this implementation, FDE and CIE information is managed + * as part of the Dwarf_Debug object. The client does not need + * to explicitly free these memory arenas. + */ + (void) dbg; + (void) cie_list; + (void) cie_count; + (void) fde_list; + (void) fde_count; +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 b/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 new file mode 100644 index 0000000..d4849b1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 @@ -0,0 +1,129 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_def_macro.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_DEF_MACRO 3 +.Sh NAME +.Nm dwarf_def_macro +.Nd add a macro definition to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_def_macro +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "char *name" +.Fa "char *value" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_def_macro +adds a macro definition to a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar lineno +specifies the line number of the source line where the macro is +defined. +A line number of zero is used for macros that are defined +before any source file is read. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the macro. +For function-like macros this parameter should also include +parentheses and parameter names if any. +.Pp +Argument +.Ar value +should point to a NUL-terminated string containing the value +of the macro. +If the macro doesn't have a value, argument +.Ar value +should be set to NULL. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_def_macro +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_def_macro +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh EXAMPLE +To record the fact that a macro named +.Dv _STDIO_H_ +was defined at line 20 of the current macro file, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; + +/* ... Assume 'dbg' refers to a DWARF producer instance... */ +if (dwarf_def_macro(dbg, 20, "_STDIO_H_", NULL, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_def_macro +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Ar dbg +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_die.c b/contrib/elftoolchain/libdwarf/dwarf_die.c new file mode 100644 index 0000000..b2b3840 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die.c @@ -0,0 +1,335 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_die.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + int ret; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_ab->ab_children == DW_CHILDREN_no) + return (DW_DLE_NO_ENTRY); + + dbg = die->die_dbg; + cu = die->die_cu; + ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu, + cu->cu_dwarf_size, die->die_next_off, cu->cu_next_offset, + ret_die, 0, error); + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + +int +dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Attribute at; + uint64_t offset; + int ret, search_sibling; + + if (dbg == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((cu = dbg->dbg_cu_current) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT); + return (DW_DLV_ERROR); + } + + /* Application requests the first DIE in this CU. */ + if (die == NULL) + return (dwarf_offdie(dbg, cu->cu_1st_offset, ret_die, + error)); + + /* + * If the DIE doesn't have any children, its sibling sits next + * right to it. + */ + search_sibling = 0; + if (die->die_ab->ab_children == DW_CHILDREN_no) + offset = die->die_next_off; + else { + /* + * Look for DW_AT_sibling attribute for the offset of + * its sibling. + */ + if ((at = _dwarf_attr_find(die, DW_AT_sibling)) != NULL) { + if (at->at_form != DW_FORM_ref_addr) + offset = at->u[0].u64 + cu->cu_offset; + else + offset = at->u[0].u64; + } else { + offset = die->die_next_off; + search_sibling = 1; + } + } + + ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu, + cu->cu_dwarf_size, offset, cu->cu_next_offset, ret_die, + search_sibling, error); + + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + +static int +_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off offset, + Dwarf_Die *ret_die, Dwarf_Error *error) +{ + + assert(dbg != NULL && cu != NULL && ret_die != NULL); + + return (_dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, + offset, cu->cu_next_offset, ret_die, 0, error)); +} + +int +dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + if (dbg == NULL || ret_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + /* First search the current CU. */ + if (dbg->dbg_cu_current != NULL) { + cu = dbg->dbg_cu_current; + if (offset > cu->cu_offset && offset < cu->cu_next_offset) { + ret = _dwarf_search_die_within_cu(dbg, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + } + + /* Search other CUs. */ + ret = _dwarf_info_load(dbg, 1, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (offset < cu->cu_offset || offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, cu, offset, + ret_die, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + return (DW_DLV_OK); + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || tag == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(die->die_ab != NULL); + + *tag = (Dwarf_Half) die->die_ab->ab_tag; + + return (DW_DLV_OK); +} + +int +dwarf_dieoffset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_offset = die->die_offset; + + return (DW_DLV_OK); +} + +int +dwarf_die_CU_offset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = die->die_cu; + assert(cu != NULL); + + *ret_offset = die->die_offset - cu->cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_die_CU_offset_range(Dwarf_Die die, Dwarf_Off *cu_offset, + Dwarf_Off *cu_length, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || cu_offset == NULL || cu_length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + cu = die->die_cu; + assert(cu != NULL); + + *cu_offset = cu->cu_offset; + *cu_length = cu->cu_length + cu->cu_length_size; + + return (DW_DLV_OK); +} + +int +dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || ret_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (die->die_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_name = die->die_name; + + return (DW_DLV_OK); +} + +int +dwarf_die_abbrev_code(Dwarf_Die die) +{ + + assert(die != NULL); + + return (die->die_abnum); +} + +int +dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset, + Dwarf_Error *error) +{ + Dwarf_CU cu; + + if (dbg == NULL || out_cu_die_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } + } + + if (cu == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, + Dwarf_Error *error) +{ + + if (dbg == NULL || addr_size == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *addr_size = dbg->dbg_pointer_size; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 b/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 new file mode 100644 index 0000000..82caf3b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 @@ -0,0 +1,55 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_die_abbrev_code.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd April 14, 2010 +.Os +.Dt DWARF_DIE_ABBREV_CODE 3 +.Sh NAME +.Nm dwarf_die_abbrev_code +.Nd retrieve the abbreviation code for a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_die_abbrev_code "Dwarf_Die die" +.Sh DESCRIPTION +Function +.Fn dwarf_die_abbrev_code +returns the abbreviation code for the debugging information entry descriptor +referenced by argument +.Ar die . +Argument +.Ar die +should be a valid pointer to a value of type +.Vt Dwarf_Die . +.Sh RETURN VALUES +The function returns an integral value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_diename 3 , +.Xr dwarf_dieoffset 3 , +.Xr dwarf_tag 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_die_link.3 b/contrib/elftoolchain/libdwarf/dwarf_die_link.3 new file mode 100644 index 0000000..89ddb5b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_die_link.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_die_link.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_DIE_LINK 3 +.Sh NAME +.Nm dwarf_die_link +.Nd link a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Die +.Fo dwarf_die_link +.Fa "Dwarf_P_Die die" +.Fa "Dwarf_P_Die parent" +.Fa "Dwarf_P_Die child" +.Fa "Dwarf_P_Die left" +.Fa "Dwarf_P_Die right" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_die_link +links debugging information entries together. +.Pp +Argument +.Ar die +should specify the debugging information entry to be updated. +.Pp +Argument +.Ar parent +specifies the new parent link for the debugging information entry. +.Pp +Argument +.Ar child +specifies the new first child link for the debugging information entry. +.Pp +Argument +.Ar left +specifies the new left sibling link for the debugging information entry. +.Pp +Argument +.Ar right +specifies the new right sibling link for the debugging information entry. +.Pp +Only one of arguments +.Ar parent , +.Ar child , +.Ar left +and +.Ar right +is allowed to be non-NULL. +Existing links to parent, child, left or right debugging information +entries, if any, will be unlinked before the specified link is +established. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_die_link +returns the debugging information entry provided in argument +.Ar die . +In case of an error, function +.Fn dwarf_die_link +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +The function +.Fn dwarf_die_link +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar die +was NULL. +.It Bq Er DW_DLE_ARGUMENT +More than one of the arguments +.Ar parent , +.Ar child , +.Ar left +and +.Ar right +were non-NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_die_to_debug 3 , +.Xr dwarf_new_die 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_diename.3 b/contrib/elftoolchain/libdwarf/dwarf_diename.3 new file mode 100644 index 0000000..d9404de --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_diename.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_diename.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd March 31, 2010 +.Os +.Dt DWARF_DIENAME 3 +.Sh NAME +.Nm dwarf_diename +.Nd retrieve the name associated with a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_diename "Dwarf_Die die" "char **ret_name" "Dwarf_Error *err" +.Sh DESCRIPTION +Function +.Fn dwarf_diename +retrieves a pointer to the NUL-terminated string associated with the +.Dv DW_AT_name +attribute of the debugging information entry descriptor referenced by +argument +.Ar die . +If the pointer was successfully retrieved, it is stored in the location +pointed to by argument +.Ar ret_name . +.Sh RETURN VALUES +Function +.Fn dwarf_diename +returns +.Dv DW_DLV_OK on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Ar die +does not contain a +.Dv DW_AT_name +attribute, the function returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Ar err . +For other errors, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_diename +can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar die +or +.Ar ret_name +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar die +had no +.Dv DW_AT_name +attribute. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_tag 3 , +.Xr dwarf_dieoffset 3 , +.Xr dwarf_die_abbrev_code 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 new file mode 100644 index 0000000..545bf26 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 @@ -0,0 +1,172 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_dieoffset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd April 17, 2010 +.Os +.Dt DWARF_DIEOFFSET 3 +.Sh NAME +.Nm dwarf_die_CU_offset , +.Nm dwarf_die_CU_offset_range , +.Nm dwarf_dieoffset , +.Nm dwarf_get_cu_die_offset_given_cu_header_offset +.Nd return offsets of DWARF debugging information entries +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_die_CU_offset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *ret_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_die_CU_offset_range +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Off *cu_length" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_dieoffset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Off *ret_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_cu_die_offset_given_cu_header_offset +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off in_cu_header_offset" +.Fa "Dwarf_Off *out_cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to retrieve offsets for DWARF debugging +information entries. +.Pp +Function +.Fn dwarf_die_CU_offset +returns the offset of the debugging information entry referenced by +argument +.Ar die +relative to the start of its containing compilation unit. +Argument +.Ar ret_offset +should point to the location that is to hold the returned offset. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case of +an error. +.Pp +Function +.Fn dwarf_die_CU_offset_range +returns the section-relative offset and length of the compilation unit +containing the debugging information entry referenced by argument +.Ar die . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +Argument +.Ar cu_length +should point to a location that will hold the returned length of the +compilation unit. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case of +an error. +.Pp +Function +.Fn dwarf_dieoffset +retrieves the section-relative offset of the debugging information +entry referenced by argument +.Ar die . +Argument +.Ar ret_offset +should point to a location that is to hold the returned +section-relative offset. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case of +an error. +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +returns the offset for the debugging information entry for a +compilation unit, given an offset to the header of the compilation +unit. +Argument +.Ar dbg +should reference a valid debugging context allocated using +.Xr dwarf_init 3 . +Argument +.Ar in_cu_header_offset +contains the offset to the start of a compilation unit. +Argument +.Ar out_cu_die_offset +points to a location that will hold the returned offset. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in case of +an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, these functions return +.Dv DW_DLV_ERROR +and set argument +.Ar err . +.Pp +Function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +returns +.Dv DW_DLV_NO_ENTRY +and sets argument +.Ar err +if there is no compilation unit located at the +offset specified in argument +.Ar in_cu_header_offset . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_length , +.Va cu_offset , +.Va dbg , +.Va die , +.Va out_cu_die_offset +or +.Va ret_offset +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar in_cu_header_offset +specified an unknown offset. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_next_cu_header 3 , +.Xr dwarf_offdie 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_dump.c b/contrib/elftoolchain/libdwarf/dwarf_dump.c new file mode 100644 index 0000000..9b5d1f7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_dump.c @@ -0,0 +1,1292 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_dump.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_get_ACCESS_name(unsigned access, const char **s) +{ + + assert(s != NULL); + + switch (access) { + case DW_ACCESS_public: + *s = "DW_ACCESS_public"; break; + case DW_ACCESS_protected: + *s = "DW_ACCESS_protected"; break; + case DW_ACCESS_private: + *s = "DW_ACCESS_private"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_AT_name(unsigned attr, const char **s) +{ + + assert(s != NULL); + + switch (attr) { + case DW_AT_abstract_origin: + *s = "DW_AT_abstract_origin"; break; + case DW_AT_accessibility: + *s = "DW_AT_accessibility"; break; + case DW_AT_address_class: + *s = "DW_AT_address_class"; break; + case DW_AT_artificial: + *s = "DW_AT_artificial"; break; + case DW_AT_allocated: + *s = "DW_AT_allocated"; break; + case DW_AT_associated: + *s = "DW_AT_associated"; break; + case DW_AT_base_types: + *s = "DW_AT_base_types"; break; + case DW_AT_binary_scale: + *s = "DW_AT_binary_scale"; break; + case DW_AT_bit_offset: + *s = "DW_AT_bit_offset"; break; + case DW_AT_bit_size: + *s = "DW_AT_bit_size"; break; + case DW_AT_bit_stride: + *s = "DW_AT_bit_stride"; break; + case DW_AT_byte_size: + *s = "DW_AT_byte_size"; break; + case DW_AT_byte_stride: + *s = "DW_AT_byte_stride"; break; + case DW_AT_calling_convention: + *s = "DW_AT_calling_convention"; break; + case DW_AT_common_reference: + *s = "DW_AT_common_reference"; break; + case DW_AT_comp_dir: + *s = "DW_AT_comp_dir"; break; + case DW_AT_const_expr: + *s = "DW_AT_const_expr"; break; + case DW_AT_const_value: + *s = "DW_AT_const_value"; break; + case DW_AT_containing_type: + *s = "DW_AT_containing_type"; break; + case DW_AT_count: + *s = "DW_AT_count"; break; + case DW_AT_call_column: + *s = "DW_AT_call_column"; break; + case DW_AT_call_file: + *s = "DW_AT_call_file"; break; + case DW_AT_call_line: + *s = "DW_AT_call_line"; break; + case DW_AT_data_bit_offset: + *s = "DW_AT_data_bit_offset"; break; + case DW_AT_data_location: + *s = "DW_AT_data_location"; break; + case DW_AT_data_member_location: + *s = "DW_AT_data_member_location"; break; + case DW_AT_decl_column: + *s = "DW_AT_decl_column"; break; + case DW_AT_decl_file: + *s = "DW_AT_decl_file"; break; + case DW_AT_decl_line: + *s = "DW_AT_decl_line"; break; + case DW_AT_declaration: + *s = "DW_AT_declaration"; break; + case DW_AT_default_value: + *s = "DW_AT_default_value"; break; + case DW_AT_decimal_scale: + *s = "DW_AT_decimal_scale"; break; + case DW_AT_decimal_sign: + *s = "DW_AT_decimal_sign"; break; + case DW_AT_description: + *s = "DW_AT_description"; break; + case DW_AT_digit_count: + *s = "DW_AT_digit_count"; break; + case DW_AT_discr: + *s = "DW_AT_discr"; break; + case DW_AT_discr_list: + *s = "DW_AT_discr_list"; break; + case DW_AT_discr_value: + *s = "DW_AT_discr_value"; break; + case DW_AT_element_list: + *s = "DW_AT_element_list"; break; + case DW_AT_encoding: + *s = "DW_AT_encoding"; break; + case DW_AT_enum_class: + *s = "DW_AT_enum_class"; break; + case DW_AT_external: + *s = "DW_AT_external"; break; + case DW_AT_entry_pc: + *s = "DW_AT_entry_pc"; break; + case DW_AT_extension: + *s = "DW_AT_extension"; break; + case DW_AT_explicit: + *s = "DW_AT_explicit"; break; + case DW_AT_endianity: + *s = "DW_AT_endianity"; break; + case DW_AT_elemental: + *s = "DW_AT_elemental"; break; + case DW_AT_frame_base: + *s = "DW_AT_frame_base"; break; + case DW_AT_friend: + *s = "DW_AT_friend"; break; + case DW_AT_high_pc: + *s = "DW_AT_high_pc"; break; + case DW_AT_hi_user: + *s = "DW_AT_hi_user"; break; + case DW_AT_identifier_case: + *s = "DW_AT_identifier_case"; break; + case DW_AT_import: + *s = "DW_AT_import"; break; + case DW_AT_inline: + *s = "DW_AT_inline"; break; + case DW_AT_is_optional: + *s = "DW_AT_is_optional"; break; + case DW_AT_language: + *s = "DW_AT_language"; break; + case DW_AT_linkage_name: + *s = "DW_AT_linkage_name"; break; + case DW_AT_lo_user: + *s = "DW_AT_lo_user"; break; + case DW_AT_location: + *s = "DW_AT_location"; break; + case DW_AT_low_pc: + *s = "DW_AT_low_pc"; break; + case DW_AT_lower_bound: + *s = "DW_AT_lower_bound"; break; + case DW_AT_macro_info: + *s = "DW_AT_macro_info"; break; + case DW_AT_main_subprogram: + *s = "DW_AT_main_subprogram"; break; + case DW_AT_mutable: + *s = "DW_AT_mutable"; break; + case DW_AT_member: + *s = "DW_AT_member"; break; + case DW_AT_name: + *s = "DW_AT_name"; break; + case DW_AT_namelist_item: + *s = "DW_AT_namelist_item"; break; + case DW_AT_ordering: + *s = "DW_AT_ordering"; break; + case DW_AT_object_pointer: + *s = "DW_AT_object_pointer"; break; + case DW_AT_priority: + *s = "DW_AT_priority"; break; + case DW_AT_producer: + *s = "DW_AT_producer"; break; + case DW_AT_prototyped: + *s = "DW_AT_prototyped"; break; + case DW_AT_picture_string: + *s = "DW_AT_picture_string"; break; + case DW_AT_pure: + *s = "DW_AT_pure"; break; + case DW_AT_return_addr: + *s = "DW_AT_return_addr"; break; + case DW_AT_ranges: + *s = "DW_AT_ranges"; break; + case DW_AT_recursive: + *s = "DW_AT_recursive"; break; + case DW_AT_segment: + *s = "DW_AT_segment"; break; + case DW_AT_sibling: + *s = "DW_AT_sibling"; break; + case DW_AT_signature: + *s = "DW_AT_signature"; break; + case DW_AT_specification: + *s = "DW_AT_specification"; break; + case DW_AT_start_scope: + *s = "DW_AT_start_scope"; break; + case DW_AT_static_link: + *s = "DW_AT_static_link"; break; + case DW_AT_stmt_list: + *s = "DW_AT_stmt_list"; break; + case DW_AT_string_length: + *s = "DW_AT_string_length"; break; + case DW_AT_subscr_data: + *s = "DW_AT_subscr_data"; break; + case DW_AT_small: + *s = "DW_AT_small"; break; + case DW_AT_type: + *s = "DW_AT_type"; break; + case DW_AT_trampoline: + *s = "DW_AT_trampoline"; break; + case DW_AT_threads_scaled: + *s = "DW_AT_threads_scaled"; break; + case DW_AT_upper_bound: + *s = "DW_AT_upper_bound"; break; + case DW_AT_use_location: + *s = "DW_AT_use_location"; break; + case DW_AT_use_UTF8: + *s = "DW_AT_use_UTF8"; break; + case DW_AT_variable_parameter: + *s = "DW_AT_variable_parameter"; break; + case DW_AT_virtuality: + *s = "DW_AT_virtuality"; break; + case DW_AT_visibility: + *s = "DW_AT_visibility"; break; + case DW_AT_vtable_elem_location: + *s = "DW_AT_vtable_elem_location"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ATE_name(unsigned ate, const char **s) +{ + + assert(s != NULL); + + switch(ate) { + case DW_ATE_address: + *s = "DW_ATE_address"; break; + case DW_ATE_boolean: + *s = "DW_ATE_boolean"; break; + case DW_ATE_complex_float: + *s = "DW_ATE_complex_float"; break; + case DW_ATE_float: + *s = "DW_ATE_float"; break; + case DW_ATE_signed: + *s = "DW_ATE_signed"; break; + case DW_ATE_signed_char: + *s = "DW_ATE_signed_char"; break; + case DW_ATE_unsigned: + *s = "DW_ATE_unsigned"; break; + case DW_ATE_unsigned_char: + *s = "DW_ATE_unsigned_char"; break; + case DW_ATE_imaginary_float: + *s = "DW_ATE_imaginary_float"; break; + case DW_ATE_packed_decimal: + *s = "DW_ATE_packed_decimal"; break; + case DW_ATE_numeric_string: + *s = "DW_ATE_numeric_string"; break; + case DW_ATE_edited: + *s = "DW_ATE_edited"; break; + case DW_ATE_signed_fixed: + *s = "DW_ATE_signed_fixed"; break; + case DW_ATE_unsigned_fixed: + *s = "DW_ATE_unsigned_fixed"; break; + case DW_ATE_decimal_float: + *s = "DW_ATE_decimal_float"; break; + case DW_ATE_lo_user: + *s = "DW_ATE_lo_user"; break; + case DW_ATE_hi_user: + *s = "DW_ATE_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CC_name(unsigned cc, const char **s) +{ + + assert(s != NULL); + + switch (cc) { + case DW_CC_normal: + *s = "DW_CC_normal"; break; + case DW_CC_program: + *s = "DW_CC_program"; break; + case DW_CC_nocall: + *s = "DW_CC_nocall"; break; + case DW_CC_lo_user: + *s = "DW_CC_lo_user"; break; + case DW_CC_hi_user: + *s = "DW_CC_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CFA_name(unsigned cfa, const char **s) +{ + + assert(s != NULL); + + switch (cfa) { + case DW_CFA_advance_loc: + *s = "DW_CFA_advance_loc"; break; + case DW_CFA_offset: + *s = "DW_CFA_offset"; break; + case DW_CFA_restore: + *s = "DW_CFA_restore"; break; + case DW_CFA_nop: + *s = "DW_CFA_nop"; break; + case DW_CFA_set_loc: + *s = "DW_CFA_set_loc"; break; + case DW_CFA_advance_loc1: + *s = "DW_CFA_advance_loc1"; break; + case DW_CFA_advance_loc2: + *s = "DW_CFA_advance_loc2"; break; + case DW_CFA_advance_loc4: + *s = "DW_CFA_advance_loc4"; break; + case DW_CFA_offset_extended: + *s = "DW_CFA_offset_extended"; break; + case DW_CFA_restore_extended: + *s = "DW_CFA_restore_extended"; break; + case DW_CFA_undefined: + *s = "DW_CFA_undefined"; break; + case DW_CFA_same_value: + *s = "DW_CFA_same_value"; break; + case DW_CFA_register: + *s = "DW_CFA_register"; break; + case DW_CFA_remember_state: + *s = "DW_CFA_remember_state"; break; + case DW_CFA_restore_state: + *s = "DW_CFA_restore_state"; break; + case DW_CFA_def_cfa: + *s = "DW_CFA_def_cfa"; break; + case DW_CFA_def_cfa_register: + *s = "DW_CFA_def_cfa_register"; break; + case DW_CFA_def_cfa_offset: + *s = "DW_CFA_def_cfa_offset"; break; + case DW_CFA_def_cfa_expression: + *s = "DW_CFA_def_cfa_expression"; break; + case DW_CFA_expression: + *s = "DW_CFA_expression"; break; + case DW_CFA_offset_extended_sf: + *s = "DW_CFA_offset_extended_sf"; break; + case DW_CFA_def_cfa_sf: + *s = "DW_CFA_def_cfa_sf"; break; + case DW_CFA_def_cfa_offset_sf: + *s = "DW_CFA_def_cfa_offset_sf"; break; + case DW_CFA_val_offset: + *s = "DW_CFA_val_offset"; break; + case DW_CFA_val_offset_sf: + *s = "DW_CFA_val_offset_sf"; break; + case DW_CFA_val_expression: + *s = "DW_CFA_val_expression"; break; + case DW_CFA_lo_user: + *s = "DW_CFA_lo_user"; break; + case DW_CFA_high_user: + *s = "DW_CFA_high_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_CHILDREN_name(unsigned children, const char **s) +{ + + assert(s != NULL); + + switch (children) { + case DW_CHILDREN_no: + *s = "DW_CHILDREN_no"; break; + case DW_CHILDREN_yes: + *s = "DW_CHILDREN_yes"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_FORM_name(unsigned form, const char **s) +{ + + assert(s != NULL); + + switch (form) { + case DW_FORM_addr: + *s = "DW_FORM_addr"; break; + case DW_FORM_block: + *s = "DW_FORM_block"; break; + case DW_FORM_block1: + *s = "DW_FORM_block1"; break; + case DW_FORM_block2: + *s = "DW_FORM_block2"; break; + case DW_FORM_block4: + *s = "DW_FORM_block4"; break; + case DW_FORM_data1: + *s = "DW_FORM_data1"; break; + case DW_FORM_data2: + *s = "DW_FORM_data2"; break; + case DW_FORM_data4: + *s = "DW_FORM_data4"; break; + case DW_FORM_data8: + *s = "DW_FORM_data8"; break; + case DW_FORM_exprloc: + *s = "DW_FORM_exprloc"; break; + case DW_FORM_flag: + *s = "DW_FORM_flag"; break; + case DW_FORM_flag_present: + *s = "DW_FORM_flag_present"; break; + case DW_FORM_indirect: + *s = "DW_FORM_indirect"; break; + case DW_FORM_ref1: + *s = "DW_FORM_ref1"; break; + case DW_FORM_ref2: + *s = "DW_FORM_ref2"; break; + case DW_FORM_ref4: + *s = "DW_FORM_ref4"; break; + case DW_FORM_ref8: + *s = "DW_FORM_ref8"; break; + case DW_FORM_ref_addr: + *s = "DW_FORM_ref_addr"; break; + case DW_FORM_ref_sig8: + *s = "DW_FORM_ref_sig8"; break; + case DW_FORM_ref_udata: + *s = "DW_FORM_ref_udata"; break; + case DW_FORM_sdata: + *s = "DW_FORM_sdata"; break; + case DW_FORM_sec_offset: + *s = "DW_FORM_sec_offset"; break; + case DW_FORM_string: + *s = "DW_FORM_string"; break; + case DW_FORM_strp: + *s = "DW_FORM_strp"; break; + case DW_FORM_udata: + *s = "DW_FORM_udata"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_DS_name(unsigned ds, const char **s) +{ + + assert(s != NULL); + + switch (ds) { + case DW_DS_unsigned: + *s = "DW_DS_unsigned"; break; + case DW_DS_leading_overpunch: + *s = "DW_DS_leading_overpunch"; break; + case DW_DS_trailing_overpunch: + *s = "DW_DS_trailing_overpunch"; break; + case DW_DS_leading_separate: + *s = "DW_DS_leading_separate"; break; + case DW_DS_trailing_separate: + *s = "DW_DS_trailing_separate"; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_DSC_name(unsigned dsc, const char **s) +{ + + assert(s != NULL); + + switch (dsc) { + case DW_DSC_label: + *s = "DW_DSC_label"; break; + case DW_DSC_range: + *s = "DW_DSC_range"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_EH_name(unsigned eh, const char **s) +{ + + assert(s != NULL); + + switch (eh) { + case DW_EH_PE_absptr: + *s = "DW_EH_PE_absptr"; break; + case DW_EH_PE_uleb128: + *s = "DW_EH_PE_uleb128"; break; + case DW_EH_PE_udata2: + *s = "DW_EH_PE_udata2"; break; + case DW_EH_PE_udata4: + *s = "DW_EH_PE_udata4"; break; + case DW_EH_PE_udata8: + *s = "DW_EH_PE_udata8"; break; + case DW_EH_PE_sleb128: + *s = "DW_EH_PE_sleb128"; break; + case DW_EH_PE_sdata2: + *s = "DW_EH_PE_sdata2"; break; + case DW_EH_PE_sdata4: + *s = "DW_EH_PE_sdata4"; break; + case DW_EH_PE_sdata8: + *s = "DW_EH_PE_sdata8"; break; + case DW_EH_PE_pcrel: + *s = "DW_EH_PE_pcrel"; break; + case DW_EH_PE_textrel: + *s = "DW_EH_PE_textrel"; break; + case DW_EH_PE_datarel: + *s = "DW_EH_PE_datarel"; break; + case DW_EH_PE_funcrel: + *s = "DW_EH_PE_funcrel"; break; + case DW_EH_PE_aligned: + *s = "DW_EH_PE_aligned"; break; + case DW_EH_PE_omit: + *s = "DW_EH_PE_omit"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_END_name(unsigned end, const char **s) +{ + + assert(s != NULL); + + switch (end) { + case DW_END_default: + *s = "DW_END_default"; break; + case DW_END_big: + *s = "DW_END_big"; break; + case DW_END_little: + *s = "DW_END_little"; break; + case DW_END_lo_user: + *s = "DW_END_lo_user"; break; + case DW_END_high_user: + *s = "DW_END_high_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ID_name(unsigned id, const char **s) +{ + + assert(s != NULL); + + switch (id) { + case DW_ID_case_sensitive: + *s = "DW_ID_case_sensitive"; break; + case DW_ID_up_case: + *s = "DW_ID_up_case"; break; + case DW_ID_down_case: + *s = "DW_ID_down_case"; break; + case DW_ID_case_insensitive: + *s = "DW_ID_case_insensitive"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_INL_name(unsigned inl, const char **s) +{ + + assert(s != NULL); + + switch (inl) { + case DW_INL_not_inlined: + *s = "DW_INL_not_inlined"; break; + case DW_INL_inlined: + *s = "DW_INL_inlined"; break; + case DW_INL_declared_not_inlined: + *s = "DW_INL_declared_not_inlined"; break; + case DW_INL_declared_inlined: + *s = "DW_INL_declared_inlined"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LANG_name(unsigned lang, const char **s) +{ + + assert(s != NULL); + + switch (lang) { + case DW_LANG_C89: + *s = "DW_LANG_C89"; break; + case DW_LANG_C: + *s = "DW_LANG_C"; break; + case DW_LANG_Ada83: + *s = "DW_LANG_Ada83"; break; + case DW_LANG_C_plus_plus: + *s = "DW_LANG_C_plus_plus"; break; + case DW_LANG_Cobol74: + *s = "DW_LANG_Cobol74"; break; + case DW_LANG_Cobol85: + *s = "DW_LANG_Cobol85"; break; + case DW_LANG_Fortran77: + *s = "DW_LANG_Fortran77"; break; + case DW_LANG_Fortran90: + *s = "DW_LANG_Fortran90"; break; + case DW_LANG_Pascal83: + *s = "DW_LANG_Pascal83"; break; + case DW_LANG_Modula2: + *s = "DW_LANG_Modula2"; break; + case DW_LANG_Java: + *s = "DW_LANG_Java"; break; + case DW_LANG_C99: + *s = "DW_LANG_C99"; break; + case DW_LANG_Ada95: + *s = "DW_LANG_Ada95"; break; + case DW_LANG_Fortran95: + *s = "DW_LANG_Fortran95"; break; + case DW_LANG_PLI: + *s = "DW_LANG_PLI"; break; + case DW_LANG_ObjC: + *s = "DW_LANG_ObjC"; break; + case DW_LANG_ObjC_plus_plus: + *s = "DW_LANG_ObjC_plus_plus"; break; + case DW_LANG_UPC: + *s = "DW_LANG_UPC"; break; + case DW_LANG_D: + *s = "DW_LANG_D"; break; + case DW_LANG_lo_user: + *s = "DW_LANG_lo_user"; break; + case DW_LANG_hi_user: + *s = "DW_LANG_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LNE_name(unsigned lne, const char **s) +{ + + assert(s != NULL); + + switch (lne) { + case DW_LNE_end_sequence: + *s = "DW_LNE_end_sequence"; break; + case DW_LNE_set_address: + *s = "DW_LNE_set_address"; break; + case DW_LNE_define_file: + *s = "DW_LNE_define_file"; break; + case DW_LNE_lo_user: + *s = "DW_LNE_lo_user"; break; + case DW_LNE_hi_user: + *s = "DW_LNE_hi_user"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_LNS_name(unsigned lns, const char **s) +{ + + assert(s != NULL); + + switch (lns) { + case DW_LNS_copy: + *s = "DW_LNS_copy"; break; + case DW_LNS_advance_pc: + *s = "DW_LNS_advance_pc"; break; + case DW_LNS_advance_line: + *s = "DW_LNS_advance_line"; break; + case DW_LNS_set_file: + *s = "DW_LNS_set_file"; break; + case DW_LNS_set_column: + *s = "DW_LNS_set_column"; break; + case DW_LNS_negate_stmt: + *s = "DW_LNS_negate_stmt"; break; + case DW_LNS_set_basic_block: + *s = "DW_LNS_set_basic_block"; break; + case DW_LNS_const_add_pc: + *s = "DW_LNS_const_add_pc"; break; + case DW_LNS_fixed_advance_pc: + *s = "DW_LNS_fixed_advance_pc"; break; + case DW_LNS_set_prologue_end: + *s = "DW_LNS_set_prologue_end"; break; + case DW_LNS_set_epilogue_begin: + *s = "DW_LNS_set_epilogue_begin"; break; + case DW_LNS_set_isa: + *s = "DW_LNS_set_isa"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_MACINFO_name(unsigned mi, const char **s) +{ + + assert(s != NULL); + + switch (mi) { + case DW_MACINFO_define: + *s = "DW_MACINFO_define"; break; + case DW_MACINFO_undef: + *s = "DW_MACINFO_undef"; break; + case DW_MACINFO_start_file: + *s = "DW_MACINFO_start_file"; break; + case DW_MACINFO_end_file: + *s = "DW_MACINFO_end_file"; break; + case DW_MACINFO_vendor_ext: + *s = "DW_MACINFO_vendor_ext"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_OP_name(unsigned op, const char **s) +{ + + assert(s != NULL); + + switch (op) { + case DW_OP_deref: + *s = "DW_OP_deref"; break; + case DW_OP_reg0: + *s = "DW_OP_reg0"; break; + case DW_OP_reg1: + *s = "DW_OP_reg1"; break; + case DW_OP_reg2: + *s = "DW_OP_reg2"; break; + case DW_OP_reg3: + *s = "DW_OP_reg3"; break; + case DW_OP_reg4: + *s = "DW_OP_reg4"; break; + case DW_OP_reg5: + *s = "DW_OP_reg5"; break; + case DW_OP_reg6: + *s = "DW_OP_reg6"; break; + case DW_OP_reg7: + *s = "DW_OP_reg7"; break; + case DW_OP_reg8: + *s = "DW_OP_reg8"; break; + case DW_OP_reg9: + *s = "DW_OP_reg9"; break; + case DW_OP_reg10: + *s = "DW_OP_reg10"; break; + case DW_OP_reg11: + *s = "DW_OP_reg11"; break; + case DW_OP_reg12: + *s = "DW_OP_reg12"; break; + case DW_OP_reg13: + *s = "DW_OP_reg13"; break; + case DW_OP_reg14: + *s = "DW_OP_reg14"; break; + case DW_OP_reg15: + *s = "DW_OP_reg15"; break; + case DW_OP_reg16: + *s = "DW_OP_reg16"; break; + case DW_OP_reg17: + *s = "DW_OP_reg17"; break; + case DW_OP_reg18: + *s = "DW_OP_reg18"; break; + case DW_OP_reg19: + *s = "DW_OP_reg19"; break; + case DW_OP_reg20: + *s = "DW_OP_reg20"; break; + case DW_OP_reg21: + *s = "DW_OP_reg21"; break; + case DW_OP_reg22: + *s = "DW_OP_reg22"; break; + case DW_OP_reg23: + *s = "DW_OP_reg23"; break; + case DW_OP_reg24: + *s = "DW_OP_reg24"; break; + case DW_OP_reg25: + *s = "DW_OP_reg25"; break; + case DW_OP_reg26: + *s = "DW_OP_reg26"; break; + case DW_OP_reg27: + *s = "DW_OP_reg27"; break; + case DW_OP_reg28: + *s = "DW_OP_reg28"; break; + case DW_OP_reg29: + *s = "DW_OP_reg29"; break; + case DW_OP_reg30: + *s = "DW_OP_reg30"; break; + case DW_OP_reg31: + *s = "DW_OP_reg31"; break; + case DW_OP_lit0: + *s = "DW_OP_lit0"; break; + case DW_OP_lit1: + *s = "DW_OP_lit1"; break; + case DW_OP_lit2: + *s = "DW_OP_lit2"; break; + case DW_OP_lit3: + *s = "DW_OP_lit3"; break; + case DW_OP_lit4: + *s = "DW_OP_lit4"; break; + case DW_OP_lit5: + *s = "DW_OP_lit5"; break; + case DW_OP_lit6: + *s = "DW_OP_lit6"; break; + case DW_OP_lit7: + *s = "DW_OP_lit7"; break; + case DW_OP_lit8: + *s = "DW_OP_lit8"; break; + case DW_OP_lit9: + *s = "DW_OP_lit9"; break; + case DW_OP_lit10: + *s = "DW_OP_lit10"; break; + case DW_OP_lit11: + *s = "DW_OP_lit11"; break; + case DW_OP_lit12: + *s = "DW_OP_lit12"; break; + case DW_OP_lit13: + *s = "DW_OP_lit13"; break; + case DW_OP_lit14: + *s = "DW_OP_lit14"; break; + case DW_OP_lit15: + *s = "DW_OP_lit15"; break; + case DW_OP_lit16: + *s = "DW_OP_lit16"; break; + case DW_OP_lit17: + *s = "DW_OP_lit17"; break; + case DW_OP_lit18: + *s = "DW_OP_lit18"; break; + case DW_OP_lit19: + *s = "DW_OP_lit19"; break; + case DW_OP_lit20: + *s = "DW_OP_lit20"; break; + case DW_OP_lit21: + *s = "DW_OP_lit21"; break; + case DW_OP_lit22: + *s = "DW_OP_lit22"; break; + case DW_OP_lit23: + *s = "DW_OP_lit23"; break; + case DW_OP_lit24: + *s = "DW_OP_lit24"; break; + case DW_OP_lit25: + *s = "DW_OP_lit25"; break; + case DW_OP_lit26: + *s = "DW_OP_lit26"; break; + case DW_OP_lit27: + *s = "DW_OP_lit27"; break; + case DW_OP_lit28: + *s = "DW_OP_lit28"; break; + case DW_OP_lit29: + *s = "DW_OP_lit29"; break; + case DW_OP_lit30: + *s = "DW_OP_lit30"; break; + case DW_OP_lit31: + *s = "DW_OP_lit31"; break; + case DW_OP_dup: + *s = "DW_OP_dup"; break; + case DW_OP_drop: + *s = "DW_OP_drop"; break; + case DW_OP_over: + *s = "DW_OP_over"; break; + case DW_OP_swap: + *s = "DW_OP_swap"; break; + case DW_OP_rot: + *s = "DW_OP_rot"; break; + case DW_OP_xderef: + *s = "DW_OP_xderef"; break; + case DW_OP_abs: + *s = "DW_OP_abs"; break; + case DW_OP_and: + *s = "DW_OP_and"; break; + case DW_OP_div: + *s = "DW_OP_div"; break; + case DW_OP_minus: + *s = "DW_OP_minus"; break; + case DW_OP_mod: + *s = "DW_OP_mod"; break; + case DW_OP_mul: + *s = "DW_OP_mul"; break; + case DW_OP_neg: + *s = "DW_OP_neg"; break; + case DW_OP_not: + *s = "DW_OP_not"; break; + case DW_OP_or: + *s = "DW_OP_or"; break; + case DW_OP_plus: + *s = "DW_OP_plus"; break; + case DW_OP_shl: + *s = "DW_OP_shl"; break; + case DW_OP_shr: + *s = "DW_OP_shr"; break; + case DW_OP_shra: + *s = "DW_OP_shra"; break; + case DW_OP_xor: + *s = "DW_OP_xor"; break; + case DW_OP_eq: + *s = "DW_OP_eq"; break; + case DW_OP_ge: + *s = "DW_OP_ge"; break; + case DW_OP_gt: + *s = "DW_OP_gt"; break; + case DW_OP_le: + *s = "DW_OP_le"; break; + case DW_OP_lt: + *s = "DW_OP_lt"; break; + case DW_OP_ne: + *s = "DW_OP_ne"; break; + case DW_OP_nop: + *s = "DW_OP_nop"; break; + case DW_OP_const1u: + *s = "DW_OP_const1u"; break; + case DW_OP_const1s: + *s = "DW_OP_const1s"; break; + case DW_OP_pick: + *s = "DW_OP_pick"; break; + case DW_OP_deref_size: + *s = "DW_OP_deref_size"; break; + case DW_OP_xderef_size: + *s = "DW_OP_xderef_size"; break; + case DW_OP_const2u: + *s = "DW_OP_const2u"; break; + case DW_OP_const2s: + *s = "DW_OP_const2s"; break; + case DW_OP_bra: + *s = "DW_OP_bra"; break; + case DW_OP_skip: + *s = "DW_OP_skip"; break; + case DW_OP_const4u: + *s = "DW_OP_const4u"; break; + case DW_OP_const4s: + *s = "DW_OP_const4s"; break; + case DW_OP_const8u: + *s = "DW_OP_const8u"; break; + case DW_OP_const8s: + *s = "DW_OP_const8s"; break; + case DW_OP_constu: + *s = "DW_OP_constu"; break; + case DW_OP_plus_uconst: + *s = "DW_OP_plus_uconst"; break; + case DW_OP_regx: + *s = "DW_OP_regx"; break; + case DW_OP_piece: + *s = "DW_OP_piece"; break; + case DW_OP_consts: + *s = "DW_OP_consts"; break; + case DW_OP_breg0: + *s = "DW_OP_breg0"; break; + case DW_OP_breg1: + *s = "DW_OP_breg1"; break; + case DW_OP_breg2: + *s = "DW_OP_breg2"; break; + case DW_OP_breg3: + *s = "DW_OP_breg3"; break; + case DW_OP_breg4: + *s = "DW_OP_breg4"; break; + case DW_OP_breg5: + *s = "DW_OP_breg5"; break; + case DW_OP_breg6: + *s = "DW_OP_breg6"; break; + case DW_OP_breg7: + *s = "DW_OP_breg7"; break; + case DW_OP_breg8: + *s = "DW_OP_breg8"; break; + case DW_OP_breg9: + *s = "DW_OP_breg9"; break; + case DW_OP_breg10: + *s = "DW_OP_breg10"; break; + case DW_OP_breg11: + *s = "DW_OP_breg11"; break; + case DW_OP_breg12: + *s = "DW_OP_breg12"; break; + case DW_OP_breg13: + *s = "DW_OP_breg13"; break; + case DW_OP_breg14: + *s = "DW_OP_breg14"; break; + case DW_OP_breg15: + *s = "DW_OP_breg15"; break; + case DW_OP_breg16: + *s = "DW_OP_breg16"; break; + case DW_OP_breg17: + *s = "DW_OP_breg17"; break; + case DW_OP_breg18: + *s = "DW_OP_breg18"; break; + case DW_OP_breg19: + *s = "DW_OP_breg19"; break; + case DW_OP_breg20: + *s = "DW_OP_breg20"; break; + case DW_OP_breg21: + *s = "DW_OP_breg21"; break; + case DW_OP_breg22: + *s = "DW_OP_breg22"; break; + case DW_OP_breg23: + *s = "DW_OP_breg23"; break; + case DW_OP_breg24: + *s = "DW_OP_breg24"; break; + case DW_OP_breg25: + *s = "DW_OP_breg25"; break; + case DW_OP_breg26: + *s = "DW_OP_breg26"; break; + case DW_OP_breg27: + *s = "DW_OP_breg27"; break; + case DW_OP_breg28: + *s = "DW_OP_breg28"; break; + case DW_OP_breg29: + *s = "DW_OP_breg29"; break; + case DW_OP_breg30: + *s = "DW_OP_breg30"; break; + case DW_OP_breg31: + *s = "DW_OP_breg31"; break; + case DW_OP_fbreg: + *s = "DW_OP_fbreg"; break; + case DW_OP_bregx: + *s = "DW_OP_bregx"; break; + case DW_OP_addr: + *s = "DW_OP_addr"; break; + case DW_OP_push_object_address: + *s = "DW_OP_push_object_address"; break; + case DW_OP_call2: + *s = "DW_OP_call2"; break; + case DW_OP_call4: + *s = "DW_OP_call4"; break; + case DW_OP_call_ref: + *s = "DW_OP_call_ref"; break; + case DW_OP_form_tls_address: + *s = "DW_OP_form_tls_address"; break; + case DW_OP_call_frame_cfa: + *s = "DW_OP_call_frame_cfa"; break; + case DW_OP_bit_piece: + *s = "DW_OP_bit_piece"; break; + case DW_OP_implicit_value: + *s = "DW_OP_implicit_value"; break; + case DW_OP_stack_value: + *s = "DW_OP_stack_value"; break; + case DW_OP_GNU_push_tls_address: + *s = "DW_OP_GNU_push_tls_address"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_ORD_name(unsigned ord, const char **s) +{ + + assert(s != NULL); + + switch (ord) { + case DW_ORD_row_major: + *s = "DW_ORD_row_major"; break; + case DW_ORD_col_major: + *s = "DW_ORD_col_major"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_TAG_name(unsigned tag, const char **s) +{ + + assert(s != NULL); + + switch (tag) { + case DW_TAG_access_declaration: + *s = "DW_TAG_access_declaration"; break; + case DW_TAG_array_type: + *s = "DW_TAG_array_type"; break; + case DW_TAG_base_type: + *s = "DW_TAG_base_type"; break; + case DW_TAG_catch_block: + *s = "DW_TAG_catch_block"; break; + case DW_TAG_class_type: + *s = "DW_TAG_class_type"; break; + case DW_TAG_common_block: + *s = "DW_TAG_common_block"; break; + case DW_TAG_common_inclusion: + *s = "DW_TAG_common_inclusion"; break; + case DW_TAG_compile_unit: + *s = "DW_TAG_compile_unit"; break; + case DW_TAG_condition: + *s = "DW_TAG_condition"; break; + case DW_TAG_const_type: + *s = "DW_TAG_const_type"; break; + case DW_TAG_constant: + *s = "DW_TAG_constant"; break; + case DW_TAG_dwarf_procedure: + *s = "DW_TAG_dwarf_procedure"; break; + case DW_TAG_entry_point: + *s = "DW_TAG_entry_point"; break; + case DW_TAG_enumeration_type: + *s = "DW_TAG_enumeration_type"; break; + case DW_TAG_enumerator: + *s = "DW_TAG_enumerator"; break; + case DW_TAG_formal_parameter: + *s = "DW_TAG_formal_parameter"; break; + case DW_TAG_friend: + *s = "DW_TAG_friend"; break; + case DW_TAG_imported_declaration: + *s = "DW_TAG_imported_declaration"; break; + case DW_TAG_imported_module: + *s = "DW_TAG_imported_module"; break; + case DW_TAG_imported_unit: + *s = "DW_TAG_imported_unit"; break; + case DW_TAG_inheritance: + *s = "DW_TAG_inheritance"; break; + case DW_TAG_inlined_subroutine: + *s = "DW_TAG_inlined_subroutine"; break; + case DW_TAG_interface_type: + *s = "DW_TAG_interface_type"; break; + case DW_TAG_label: + *s = "DW_TAG_label"; break; + case DW_TAG_lexical_block: + *s = "DW_TAG_lexical_block"; break; + case DW_TAG_member: + *s = "DW_TAG_member"; break; + case DW_TAG_module: + *s = "DW_TAG_module"; break; + case DW_TAG_namelist: + *s = "DW_TAG_namelist"; break; + case DW_TAG_namelist_item: + *s = "DW_TAG_namelist_item"; break; + case DW_TAG_namespace: + *s = "DW_TAG_namespace"; break; + case DW_TAG_packed_type: + *s = "DW_TAG_packed_type"; break; + case DW_TAG_partial_unit: + *s = "DW_TAG_partial_unit"; break; + case DW_TAG_pointer_type: + *s = "DW_TAG_pointer_type"; break; + case DW_TAG_ptr_to_member_type: + *s = "DW_TAG_ptr_to_member_type"; break; + case DW_TAG_reference_type: + *s = "DW_TAG_reference_type"; break; + case DW_TAG_restrict_type: + *s = "DW_TAG_restrict_type"; break; + case DW_TAG_rvalue_reference_type: + *s = "DW_TAG_rvalue_reference_type"; break; + case DW_TAG_set_type: + *s = "DW_TAG_set_type"; break; + case DW_TAG_shared_type: + *s = "DW_TAG_shared_type"; break; + case DW_TAG_string_type: + *s = "DW_TAG_string_type"; break; + case DW_TAG_structure_type: + *s = "DW_TAG_structure_type"; break; + case DW_TAG_subprogram: + *s = "DW_TAG_subprogram"; break; + case DW_TAG_subrange_type: + *s = "DW_TAG_subrange_type"; break; + case DW_TAG_subroutine_type: + *s = "DW_TAG_subroutine_type"; break; + case DW_TAG_template_alias: + *s = "DW_TAG_template_alias"; break; + case DW_TAG_template_type_parameter: + *s = "DW_TAG_template_type_parameter"; break; + case DW_TAG_template_value_parameter: + *s = "DW_TAG_template_value_parameter"; break; + case DW_TAG_thrown_type: + *s = "DW_TAG_thrown_type"; break; + case DW_TAG_try_block: + *s = "DW_TAG_try_block"; break; + case DW_TAG_type_unit: + *s = "DW_TAG_type_unit"; break; + case DW_TAG_typedef: + *s = "DW_TAG_typedef"; break; + case DW_TAG_union_type: + *s = "DW_TAG_union_type"; break; + case DW_TAG_unspecified_parameters: + *s = "DW_TAG_unspecified_parameters"; break; + case DW_TAG_unspecified_type: + *s = "DW_TAG_unspecified_type"; break; + case DW_TAG_variable: + *s = "DW_TAG_variable"; break; + case DW_TAG_variant: + *s = "DW_TAG_variant"; break; + case DW_TAG_variant_part: + *s = "DW_TAG_variant_part"; break; + case DW_TAG_volatile_type: + *s = "DW_TAG_volatile_type"; break; + case DW_TAG_with_stmt: + *s = "DW_TAG_with_stmt"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_VIRTUALITY_name(unsigned vir, const char **s) +{ + + assert(s != NULL); + + switch (vir) { + case DW_VIRTUALITY_none: + *s = "DW_VIRTUALITY_none"; break; + case DW_VIRTUALITY_virtual: + *s = "DW_VIRTUALITY_virtual"; break; + case DW_VIRTUALITY_pure_virtual: + *s = "DW_VIRTUALITY_pure_virtual"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_VIS_name(unsigned vis, const char **s) +{ + + assert(s != NULL); + + switch (vis) { + case DW_VIS_local: + *s = "DW_VIS_local"; break; + case DW_VIS_exported: + *s = "DW_VIS_exported"; break; + case DW_VIS_qualified: + *s = "DW_VIS_qualified"; break; + default: + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 b/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 new file mode 100644 index 0000000..a4de18c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 @@ -0,0 +1,90 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_end_macro_file.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd September 25, 2011 +.Os +.Dt DWARF_END_MACRO_FILE 3 +.Sh NAME +.Nm dwarf_end_macro_file +.Nd mark the end of the current source file inclusion +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_end_macro_file +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fa +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_end_macro_file +marks the end of the current source file inclusion. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_end_macro_file +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_end_macro_file +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_end_macro_file +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 b/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 new file mode 100644 index 0000000..466c091 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 @@ -0,0 +1,67 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_errmsg.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd December 12, 2009 +.Os +.Dt DWARF_ERRMSG 3 +.Sh NAME +.Nm dwarf_errmsg +.Nd retrieve a human-readable string corresponding to a +.Vt Dwarf_Error +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "const char *" +.Fn dwarf_errmsg "Dwarf_Error err" +.Sh DESCRIPTION +Function +.Fn dwarf_errmsg +returns a +.Dv NUL Ns - Ns +terminated string for the error denoted by +argument +.Ar err . +.Pp +Argument +.Ar err +should be a valid handle to a +.Vt Dwarf_Error +instance. +.Sh Memory Management +The returned pointer should not be freed using +.Xr free 3 +or +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_errmsg +returns a pointer to a +.Dv NUL Ns - Ns +terminated string. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errno 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_errmsg.c b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c new file mode 100644 index 0000000..86afa28 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errmsg.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_errmsg.c 2576 2012-09-13 09:16:11Z jkoshy $"); + +const char *_libdwarf_errors[] = { +#define DEFINE_ERROR(N,S) [DW_DLE_##N] = S + DEFINE_ERROR(NONE, "No Error"), + DEFINE_ERROR(ERROR, "An error"), + DEFINE_ERROR(NO_ENTRY, "No entry found"), + DEFINE_ERROR(ARGUMENT, "Invalid argument"), + DEFINE_ERROR(DEBUG_INFO_NULL, "Debug info NULL"), + DEFINE_ERROR(MEMORY, "Insufficient memory"), + DEFINE_ERROR(ELF, "ELF error"), + DEFINE_ERROR(CU_LENGTH_ERROR, "Invalid compilation unit data"), + DEFINE_ERROR(VERSION_STAMP_ERROR, "Unsupported version"), + DEFINE_ERROR(DEBUG_ABBREV_NULL, "Abbrev not found"), + DEFINE_ERROR(DIE_NO_CU_CONTEXT, "No current compilation unit"), + DEFINE_ERROR(LOC_EXPR_BAD, "Invalid location expression"), + DEFINE_ERROR(EXPR_LENGTH_BAD, "Invalid DWARF expression length"), + DEFINE_ERROR(DEBUG_LOC_SECTION_SHORT, "Loclist section too short"), + DEFINE_ERROR(ATTR_FORM_BAD, "Invalid attribute form"), + DEFINE_ERROR(DEBUG_LINE_LENGTH_BAD, "Line info section too short"), + DEFINE_ERROR(LINE_FILE_NUM_BAD, "Invalid file number."), + DEFINE_ERROR(DIR_INDEX_BAD, "Invalid dir index."), + DEFINE_ERROR(DEBUG_FRAME_LENGTH_BAD, "Frame section too short"), + DEFINE_ERROR(NO_CIE_FOR_FDE, "FDE without corresponding CIE"), + DEFINE_ERROR(FRAME_AUGMENTATION_UNKNOWN, "Unknown CIE augmentation"), + DEFINE_ERROR(FRAME_INSTR_EXEC_ERROR, "Frame instruction exec error"), + DEFINE_ERROR(FRAME_VERSION_BAD, "Unsupported frame section version"), + DEFINE_ERROR(FRAME_TABLE_COL_BAD, "Invalid table column value"), + DEFINE_ERROR(DF_REG_NUM_TOO_HIGH, "Register number too large"), + DEFINE_ERROR(PC_NOT_IN_FDE_RANGE, "PC requested not in the FDE range"), + DEFINE_ERROR(ARANGE_OFFSET_BAD, "Invalid address range offset"), + DEFINE_ERROR(DEBUG_MACRO_INCONSISTENT, "Invalid macinfo data"), + DEFINE_ERROR(ELF_SECT_ERR, "Application callback failed"), + DEFINE_ERROR(NUM, "Unknown DWARF error") +#undef DEFINE_ERROR +}; + +const char * +dwarf_errmsg_(Dwarf_Error *error) +{ + const char *p; + + if (error == NULL) + return NULL; + + if (error->err_error < 0 || error->err_error >= DW_DLE_NUM) + return _libdwarf_errors[DW_DLE_NUM]; + else if (error->err_error == DW_DLE_NONE) + return _libdwarf_errors[DW_DLE_NONE]; + else + p = _libdwarf_errors[error->err_error]; + + if (error->err_error == DW_DLE_ELF) + snprintf(error->err_msg, sizeof(error->err_msg), + "ELF error : %s [%s(%d)]", elf_errmsg(error->err_elferror), + error->err_func, error->err_line); + else + snprintf(error->err_msg, sizeof(error->err_msg), + "%s [%s(%d)]", p, error->err_func, error->err_line); + + return (const char *) error->err_msg; +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_errno.3 b/contrib/elftoolchain/libdwarf/dwarf_errno.3 new file mode 100644 index 0000000..7e1a1eb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_errno.3 @@ -0,0 +1,58 @@ +.\" Copyright (c) 2009,2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_errno.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd March 25, 2010 +.Os +.Dt DWARF_ERRNO 3 +.Sh NAME +.Nm dwarf_errno +.Nd retrieve the error number corresponding to a +.Vt Dwarf_Error +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_errno "Dwarf_Error err" +.Sh DESCRIPTION +Function +.Fn dwarf_errno +returns the error number associated with a +.Vt Dwarf_Error +instance. +.Pp +Argument +.Ar err +should be a valid handle to a +.Vt Dwarf_Error +instance. +.Sh RETURN VALUES +Function +.Fn dwarf_errno +returns an integral value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 b/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 new file mode 100644 index 0000000..eaeb320 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 @@ -0,0 +1,182 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_expand_frame_instructions.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_EXPAND_FRAME_INSTRUCTIONS 3 +.Sh NAME +.Nm dwarf_expand_frame_instructions +.Nd expand frame instructions +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_expand_frame_instructions +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Ptr instructions" +.Fa "Dwarf_Unsigned len" +.Fa "Dwarf_Frame_Op **ret_ops" +.Fa "Dwarf_Signed *ret_opcnt" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expand_frame_instructions +translates DWARF frame instruction bytes into an array of +.Vt Dwarf_Frame_Op +descriptors. +.Pp +Argument +.Ar cie +should reference the CIE descriptor associated with the instructions +to be translated. +.Pp +Arugment +.Ar instructions +should point to an array of frame instruction bytes, as +returned by the functions +.Xr dwarf_get_cie_info 3 +or +.Xr dwarf_get_fde_instr_bytes 3 . +.Pp +Argument +.Ar len +should specify the number of the frame instruction bytes to be +translated. +.Pp +Argument +.Ar ret_ops +should point to a location that will be set to a pointer to +an array of translated +.Vt Dwarf_Frame_Op +descriptors. +.Pp +Argument +.Ar ret_opcnt +should point to a location that will hold the total number of the +returned descriptors. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory area used for the descriptor array returned in argument +.Ar ret_ops +is allocated by +.Lb libdwarf . +Application code should use function +.Xr dwarf_dealloc 3 +with type +.Dv DW_DLA_FRAME_BLOCK +to free the memory area when the descriptor array is no longer needed. +.Sh RETURN VALUES +Function +.Fn dwarf_expand_frame_instructions +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_expand_frame_instructions +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar cie , +.Ar instructions , +.Ar ret_ops +or +.Ar ret_opcnt +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar len +was 0. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR +An unknown instruction was found in the instruction bytes provided +in argument +.Ar instructions . +.El +.Sh EXAMPLE +To retrieve and expand the frame instructions for a given FDE +descriptor, use: +.Bd -literal -offset indent +Dwarf_Dbg dbg; +Dwarf_Cie cie; +Dwarf_Fde fde; +Dwarf_Ptr fde_inst; +Dwarf_Unsigned fde_instlen; +Dwarf_Frame_Op *ops; +Dwarf_Signed opcnt; +Dwarf_Error de; + +/* ... assuming `dbg` references a valid DWARF debugging context, + `fde` references a valid FDE descriptor and `cie` holds the CIE + descriptor associated with the FDE descriptor ... */ + +if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, + &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_fde_instr_bytes failed: %s", + dwarf_errmsg(de)); + +if (dwarf_expand_frame_instructions(cie, fde_inst, fde_instlen, + &ops, &opcnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, + "dwarf_expand_frame_instructions failed: %s", + dwarf_errmsg(de)); + +for (i = 0; i < opcnt; i++) { + /* ... use ops[i] ... */ +} + +/* Free the memory area when no longer needed. */ +dwarf_dealloc(dbg, ops, DW_DLA_FRAME_BLOCK); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_frame_instructions_dealloc 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 new file mode 100644 index 0000000..f22294e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 @@ -0,0 +1,84 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_expr_current_offset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd September 13, 2011 +.Os +.Dt DWARF_EXPR_CURRENT_OFFSET 3 +.Sh NAME +.Nm dwarf_expr_current_offset +.Nd retrieve the number of bytes in a location expression stream +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_expr_current_offset +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expr_current_offset +returns the size in bytes of the stream representation of a location +expression. +.Pp +Argument +.Ar expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_expr_current_offset +returns the size in bytes of the location descriptor's stream +representation. +In case of an error, function +.Fn dwarf_expr_current_offset +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_expr_current_offset +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar expr +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 b/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 new file mode 100644 index 0000000..69f1d9c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_expr_into_block.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd September 13, 2011 +.Os +.Dt DWARF_EXPR_INTO_BLOCK 3 +.Sh NAME +.Nm dwarf_expr_into_block +.Nd retrieve the byte stream for a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Addr" +.Fo dwarf_expr_into_block +.Fa "Dwarf_P_Expr expr" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_expr_into_block +retrieves the byte stream representation of a location expression. +.Pp +Argument +.Ar expr +should reference a location expression descriptor allocated using +.Xr dwarf_new_expr 3 . +.Pp +Argument +.Ar length +should point to a location which will hold the size in bytes of +the retrieved byte stream. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_expr_into_block +returns the address of the first byte of the generated byte stream. +In case of an error, function +.Fn dwarf_expr_into_block +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_expr_into_block +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar expr +or +.Ar length +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_new_expr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 new file mode 100644 index 0000000..8150e78 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_fde_cfa_offset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd September 26, 2011 +.Os +.Dt DWARF_FDE_CFA_OFFSET 3 +.Sh NAME +.Nm dwarf_fde_cfa_offset +.Nd add a DW_CFA_offset frame instruction to a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_fde_cfa_offset +.Fa "Dwarf_P_Fde fde" +.Fa "Dwarf_Unsigned reg" +.Fa "Dwarf_Signed offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_fde_cfa_offset +appends a +.Dv DW_CFA_offset +frame instruction to the frame descriptor referenced by argument +.Ar fde . +.Pp +Argument +.Ar fde +should reference a frame descriptor allocated using +.Xr dwarf_new_fde 3 . +.Pp +Argument +.Ar reg +specifies the register operand for the frame instruction. +.Pp +Argument +.Ar offset +specifies the offset operand for the frame instruction. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_fde_cfa_offset +returns the frame descriptor given in argument +.Ar fde . +In case of an error, function +.Fn dwarf_fde_cfa_offset +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_fde_cfa_offset +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar fde +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_new_fde 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 b/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 new file mode 100644 index 0000000..ede0df9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 @@ -0,0 +1,68 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_find_macro_value_start.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd March 26, 2011 +.Os +.Dt DWARF_FIND_MACRO_VALUE_START 3 +.Sh NAME +.Nm dwarf_find_macro_value_start +.Nd return the address of the first byte of a macro value +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft char * +.Fo dwarf_find_macro_value_start +.Fa "char *macro_string" +.Fc +.Sh DESCRIPTION +Given a DWARF macro string, function +.Fn dwarf_find_macro_value_start +returns a pointer to the first byte of the macro value part of the +macro string. +.Pp +Argument +.Ar macro_string +should be a NUL-terminated string conforming to the macro format +defined in the DWARF standard; see +.Xr dwarf 4 . +.Sh RETURN VALUES +On success, function +.Fn dwarf_find_macro_value_start +returns a pointer to the first byte of the macro value. +If the macro value part was not found, function +.Fn dwarf_find_macro_value_start +returns a pointer to the NUL-byte terminating argument +.Ar macro_string . +.Pp +Function +.Fn dwarf_find_macro_value_start +returns NULL if argument +.Ar macro_string +was NULL. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_macro_details 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_finish.3 b/contrib/elftoolchain/libdwarf/dwarf_finish.3 new file mode 100644 index 0000000..a26bf9b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_finish.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 2009,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_finish.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_FINISH 3 +.Sh NAME +.Nm dwarf_finish , +.Nm dwarf_object_finish +.Nd free resources associated with a debug descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_finish "Dwarf_Debug dbg" "Dwarf_Error *err" +.Ft int +.Fn dwarf_object_finish "Dwarf_Debug dbg" "Dwarf_Error *err" +.Sh DESCRIPTION +The +.Fn dwarf_finish +and +.Fn dwarf_object_finish +functions are used to release the resources associated with a debug +descriptor allocated by a prior call to +.Xr dwarf_init 3 +and +.Xr dwarf_object_init 3 +respectively. +.Pp +Argument +.Ar dbg +denotes a valid +.Vt Dwarf_Debug +instance. +Argument +.Ar err +will be used to record error information in case of an error. +.Pp +After a call to +.Fn dwarf_finish +or +.Fn dwarf_object_finish , +the argument +.Ar dbg +will be invalid and should not be used further. +.Pp +For +.Vt Dwarf_Debug +descriptors opened using +.Xr dwarf_init 3 , +the application would need to explicitly release the +.Vt Elf +instance associated with the descriptor by first retrieving +the instance using +.Xr dwarf_get_elf 3 +and closing it using +.Xr elf_end 3 . +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +if successful. +In case of an error, the functions return +.Dv DW_DLV_ERROR +and record additional information in argument +.Ar err . +.Sh EXAMPLES +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_elf_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; + +if (dwarf_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); +.Ed +.Pp +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_object_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; + +if (dwarf_object_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_object_finish: %s", + dwarf_errmsg(de)); +.Ed +.Pp +To deallocate a +.Vt Dwarf_Debug +instance allocated using +.Xr dwarf_init 3 +use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dward_Error de; +Elf *e; + +if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(&de)); + +if (dwarf_finish(dbg, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); + +(void) elf_end(e); +.Ed +.Sh SEE ALSO +.Xr elf_end 3 , +.Xr dwarf_elf_init 3 , +.Xr dwarf_get_elf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_object_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_finish.c b/contrib/elftoolchain/libdwarf/dwarf_finish.c new file mode 100644 index 0000000..b3bdc0b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_finish.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_finish.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_finish(Dwarf_Debug dbg, Dwarf_Error *error) +{ + (void) error; /* unused */ + + if (dbg == NULL) + return (DW_DLV_OK); + + _dwarf_deinit(dbg); + _dwarf_elf_deinit(dbg); + + free(dbg); + + return (DW_DLV_OK); +} + + +int +dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error *error) +{ + (void) error; /* unused */ + + if (dbg == NULL) + return (DW_DLV_OK); + + _dwarf_deinit(dbg); + + free(dbg); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_form.c b/contrib/elftoolchain/libdwarf/dwarf_form.c new file mode 100644 index 0000000..a9a22cb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_form.c @@ -0,0 +1,480 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009,2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_form.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_hasform(Dwarf_Attribute at, Dwarf_Half form, Dwarf_Bool *return_hasform, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_hasform == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_hasform = (at->at_form == form); + + return (DW_DLV_OK); +} + +int +dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_form == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_form = at->at_form; + + return (DW_DLV_OK); +} + +int +dwarf_whatform_direct(Dwarf_Attribute at, Dwarf_Half *return_form, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_form == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_indirect) + *return_form = DW_FORM_indirect; + else + *return_form = (Dwarf_Half) at->at_form; + + return (DW_DLV_OK); +} + +int +dwarf_whatattr(Dwarf_Attribute at, Dwarf_Half *return_attr, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_attr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *return_attr = (Dwarf_Half) at->at_attrib; + + return (DW_DLV_OK); +} + +int +dwarf_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + *return_offset = (Dwarf_Off) at->u[0].u64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_global_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_ref_addr: + case DW_FORM_sec_offset: + *return_offset = (Dwarf_Off) at->u[0].u64; + ret = DW_DLV_OK; + break; + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + *return_offset = (Dwarf_Off) at->u[0].u64 + + at->at_die->die_cu->cu_offset; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formaddr(Dwarf_Attribute at, Dwarf_Addr *return_addr, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_addr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form == DW_FORM_addr) { + *return_addr = at->u[0].u64; + ret = DW_DLV_OK; + } else { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formflag(Dwarf_Attribute at, Dwarf_Bool *return_bool, Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_bool == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form == DW_FORM_flag || + at->at_form == DW_FORM_flag_present) { + *return_bool = (Dwarf_Bool) (!!at->u[0].u64); + ret = DW_DLV_OK; + } else { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formudata(Dwarf_Attribute at, Dwarf_Unsigned *return_uvalue, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_uvalue == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + *return_uvalue = at->u[0].u64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formsdata(Dwarf_Attribute at, Dwarf_Signed *return_svalue, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_svalue == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_data1: + *return_svalue = (int8_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data2: + *return_svalue = (int16_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data4: + *return_svalue = (int32_t) at->u[0].s64; + ret = DW_DLV_OK; + break; + case DW_FORM_data8: + case DW_FORM_sdata: + *return_svalue = at->u[0].s64; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formblock(Dwarf_Attribute at, Dwarf_Block **return_block, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_block == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + *return_block = &at->at_block; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +int +dwarf_formsig8(Dwarf_Attribute at, Dwarf_Sig8 *return_sig8, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_sig8 == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form != DW_FORM_ref_sig8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + assert(at->u[0].u64 == 8); + memcpy(return_sig8->signature, at->u[1].u8p, at->u[0].u64); + + return (DW_DLV_OK); +} + +int +dwarf_formexprloc(Dwarf_Attribute at, Dwarf_Unsigned *return_exprlen, + Dwarf_Ptr *return_expr, Dwarf_Error *error) +{ + + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_exprlen == NULL || return_expr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (at->at_form != DW_FORM_exprloc) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + + *return_exprlen = at->u[0].u64; + *return_expr = (void *) at->u[1].u8p; + + return (DW_DLV_OK); +} + +int +dwarf_formstring(Dwarf_Attribute at, char **return_string, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || return_string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_form) { + case DW_FORM_string: + *return_string = (char *) at->u[0].s; + ret = DW_DLV_OK; + break; + case DW_FORM_strp: + *return_string = (char *) at->u[1].s; + ret = DW_DLV_OK; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLV_ERROR; + } + + return (ret); +} + +enum Dwarf_Form_Class +dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr, + Dwarf_Half offset_size, Dwarf_Half form) +{ + + switch (form) { + case DW_FORM_addr: + return (DW_FORM_CLASS_ADDRESS); + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + return (DW_FORM_CLASS_BLOCK); + case DW_FORM_string: + case DW_FORM_strp: + return (DW_FORM_CLASS_STRING); + case DW_FORM_flag: + case DW_FORM_flag_present: + return (DW_FORM_CLASS_FLAG); + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_ref_udata: + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + return (DW_FORM_CLASS_REFERENCE); + case DW_FORM_exprloc: + return (DW_FORM_CLASS_EXPRLOC); + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_sdata: + case DW_FORM_udata: + return (DW_FORM_CLASS_CONSTANT); + case DW_FORM_data4: + case DW_FORM_data8: + if (dwversion > 3) + return (DW_FORM_CLASS_CONSTANT); + if (form == DW_FORM_data4 && offset_size != 4) + return (DW_FORM_CLASS_CONSTANT); + if (form == DW_FORM_data8 && offset_size != 8) + return (DW_FORM_CLASS_CONSTANT); + /* FALLTHROUGH */ + case DW_FORM_sec_offset: + /* + * DW_FORM_data4 and DW_FORM_data8 can be used as + * offset/pointer before DWARF4. Newly added + * DWARF4 form DW_FORM_sec_offset intents to replace + * DW_FORM_data{4,8} for this purpose. Anyway, to + * determine the actual class for these forms, we need + * to also look at the attribute number. + */ + switch (attr) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + return (DW_FORM_CLASS_LOCLISTPTR); + case DW_AT_stmt_list: + return (DW_FORM_CLASS_LINEPTR); + case DW_AT_start_scope: + case DW_AT_ranges: + return (DW_FORM_CLASS_RANGELISTPTR); + case DW_AT_macro_info: + return (DW_FORM_CLASS_MACPTR); + default: + if (form == DW_FORM_data4 || form == DW_FORM_data8) + return (DW_FORM_CLASS_CONSTANT); + else + return (DW_FORM_CLASS_UNKNOWN); + } + default: + return (DW_FORM_CLASS_UNKNOWN); + } +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 b/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 new file mode 100644 index 0000000..6b8c70d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formaddr.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 23, 2010 +.Os +.Dt DWARF_FORMADDR 3 +.Sh NAME +.Nm dwarf_formaddr +.Nd return the value of an ADDRESS class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formaddr +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Addr *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formaddr +sets the location pointed to by argument +.Ar ret +to the address represented by the attribute referenced +by argument +.Ar attr . +The form of argument +.Ar attr +must be +.Dv DW_FORM_addr . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formaddr +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formblock +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of form +.Dv DW_FORM_addr . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formblock.3 b/contrib/elftoolchain/libdwarf/dwarf_formblock.3 new file mode 100644 index 0000000..4ae824f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formblock.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formblock.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 23, 2010 +.Os +.Dt DWARF_FORMBLOCK 3 +.Sh NAME +.Nm dwarf_formblock +.Nd return the value of a BLOCK attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formblock +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Block **ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formblock +sets the location pointed to by argument +.Ar ret +to a pointer to a +.Vt Dwarf_Block +structure containing the value of the attribute referenced +by argument +.Ar attr . +The form of argument +.Ar attr +must be one of +.Dv DW_FORM_block , +.Dv DW_FORM_block1 , +.Dv DW_FORM_block2 +or +.Dv DW_FORM_block4 . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Ss Memory Management +The memory area referenced by the returned pointer is managed by +the DWARF(3) library. +The application should not attempt to free this memory +area. +Portable code may indicate that the memory area is to be freed by +by using +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_formblock +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formblock +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 b/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 new file mode 100644 index 0000000..231ba3a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 @@ -0,0 +1,109 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formexprloc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 25, 2010 +.Os +.Dt DWARF_FORMEXPRLOC 3 +.Sh NAME +.Nm dwarf_formexprloc +.Nd return information about a location expression +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formexprloc +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Unsigned *retlen" +.Fa "Dwarf_Ptr *retexpr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formexprloc +allows an application to retrieve the length and the bytes of a +DWARF location expression. +.Pp +Argument +.Ar attr +should reference a DWARF attribute of the form +.Dv DW_FORM_exprloc . +Argument +.Ar retlen +should point to a location that will be set to the length of the +location expression. +Argument +.Ar retexpr +should point to a location that will be set to a pointer to the +content of the location expression itself. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Ss Memory Management +The application should not attempt to free the memory +area referenced by the pointer returned in argument +.Ar retexpr . +.Sh RETURN VALUES +Function +.Fn dwarf_formexprloc +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formexprloc +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of arguments +.Ar attr , +.Ar retlen +or +.Ar retexpr +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of form +.Dv DW_FORM_exprloc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formflag.3 b/contrib/elftoolchain/libdwarf/dwarf_formflag.3 new file mode 100644 index 0000000..93d5902 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formflag.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formflag.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd June 21, 2010 +.Os +.Dt DWARF_FORMFLAG 3 +.Sh NAME +.Nm dwarf_formflag +.Nd return the value of a BOOLEAN class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formflag +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formflag +sets the location pointed to by argument +.Ar ret +to 1 if the attribute referenced by argument +.Ar attr +has a non-zero value, or 0 otherwise. +The form of argument +.Ar attr +must be one of +.Dv DW_FORM_flag +or +.Dv DW_FORM_flag_present . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formflag +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formflag +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formref.3 b/contrib/elftoolchain/libdwarf/dwarf_formref.3 new file mode 100644 index 0000000..9e3458f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formref.3 @@ -0,0 +1,136 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formref.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd June 21, 2010 +.Os +.Dt DWARF_FORMREF 3 +.Sh NAME +.Nm dwarf_formref , +.Nm dwarf_global_formref +.Nd retrieve offsets for REFERENCE class attributes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formref +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Off *retoffset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_formref +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Off *retoffset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions return the offsets associated with a DWARF attribute +descriptor. +.Pp +Function +.Fn dwarf_formref +returns the compilation unit relative offset of the descriptor +referenced by argument +.Ar attr +in the location pointed to by argument +.Ar retoffset . +Argument +.Ar attr +must be a reference that is local to a compilation unit. +Permitted forms for argument +.Ar attr +are +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 +and +.Dv DW_FORM_ref_udata . +.Pp +Function +.Fn dwarf_global_formref +returns the section-relative offset of the descriptor referenced by +argument +.Ar attr +in the location pointed to by argument +.Ar retoffset . +Argument +.Ar attr +should be a legal +.Sy REFERENCE +class form. +Permitted forms for argument +.Ar attr +are: +.Dv DW_FORM_ref_addr , +.Dv DW_FORM_ref_udata , +.Dv DW_FORM_ref1 , +.Dv DW_FORM_ref2 , +.Dv DW_FORM_ref4 , +.Dv DW_FORM_ref8 +and +.Dv DW_FORM_sec_offset . +The returned offset is relative to the start of the +.Dq .debug_info +ELF section. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, these functions return +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar retoffset +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 b/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 new file mode 100644 index 0000000..5445324 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formsig8.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 24, 2010 +.Os +.Dt DWARF_FORMSIG8 3 +.Sh NAME +.Nm dwarf_formsig8 +.Nd return the 64-bit type signature for a DWARF type +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formsig8 +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Sig8 *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formsig8 +sets the location pointed to by argument +.Ar ret +to the 64-bit type signature that is the value of +the attribute referenced by argument +.Ar attr . +The form of argument +.Ar attr +must be +.Dv DW_FORM_ref_sig8 . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_formsig8 +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formsig8 +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 +.Sh HISTORY +Type signatures were added in version 4 of the DWARF specification. diff --git a/contrib/elftoolchain/libdwarf/dwarf_formstring.3 b/contrib/elftoolchain/libdwarf/dwarf_formstring.3 new file mode 100644 index 0000000..63e83f6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formstring.3 @@ -0,0 +1,101 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formstring.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd July 24, 2010 +.Os +.Dt DWARF_FORMSTRING 3 +.Sh NAME +.Nm dwarf_formstring +.Nd return the value of a STRING class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formstring +.Fa "Dwarf_Attribute attr" +.Fa "char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_formstring +sets the location pointed to by argument +.Ar ret +to a pointer to a NUL-terminated string containing +the value of the attribute referenced by argument +.Ar attr . +The form of argument +.Ar attr +must be one of +.Dv DW_FORM_string +or +.Dv DW_FORM_strp . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Ss Memory Management +The memory area referenced by the returned pointer is managed by +the DWARF(3) library. +The application should not attempt to directly free this memory +area. +.Sh RETURN VALUES +Function +.Fn dwarf_formstring +returns +.Dv DW_DLV_OK +on success. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_formstring +may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsdata 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formudata 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_formudata.3 b/contrib/elftoolchain/libdwarf/dwarf_formudata.3 new file mode 100644 index 0000000..f95fdea --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_formudata.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_formudata.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd June 21, 2010 +.Os +.Dt DWARF_FORMUDATA 3 +.Sh NAME +.Nm dwarf_formudata , +.Nm dwarf_formsdata +.Nd return the value of a CONSTANT class attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_formudata +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_formsdata +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions return the value associated with a DWARF attribute +describing a constant. +.Pp +Function +.Fn dwarf_formudata +sets the location pointed to by argument +.Ar ret +to the value of the attribute referenced by argument +.Ar attr , +treating the value as an unsigned quantity. +Argument +.Ar attr +must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +and +.Dv DW_FORM_udata . +.Pp +Function +.Fn dwarf_formsdata +sets the location pointed to by argument +.Ar ret +to the value of the attribute referenced by argument +.Ar attr , +appropriately sign extended. +Argument +.Ar attr +must have one of the following forms: +.Dv DW_FORM_data1 , +.Dv DW_FORM_data2 , +.Dv DW_FORM_data4 , +.Dv DW_FORM_data8 +and +.Dv DW_FORM_sdata . +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, they return +.Dv DW_DLV_ERROR +and set argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar attr +or +.Ar ret +was NULL. +.It Bq Er DW_DLE_ATTR_FORM_BAD +The attribute referenced by argument +.Ar attr +was not of a permitted kind. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_formblock 3 , +.Xr dwarf_formflag 3 , +.Xr dwarf_formref 3 , +.Xr dwarf_formsig8 3 , +.Xr dwarf_formstring 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_frame.c b/contrib/elftoolchain/libdwarf/dwarf_frame.c new file mode 100644 index 0000000..5ccbbc4 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_frame.c @@ -0,0 +1,603 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list, + Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, + Dwarf_Error *error) +{ + + if (dbg == NULL || cie_list == NULL || cie_count == NULL || + fde_list == NULL || fde_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_internal_reg_table == NULL) { + if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + if (dbg->dbg_frame == NULL) { + if (_dwarf_frame_section_load(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_frame == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + if (dbg->dbg_frame->fs_ciearray == NULL || + dbg->dbg_frame->fs_fdearray == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *cie_list = dbg->dbg_frame->fs_ciearray; + *cie_count = dbg->dbg_frame->fs_cielen; + *fde_list = dbg->dbg_frame->fs_fdearray; + *fde_count = dbg->dbg_frame->fs_fdelen; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie **cie_list, + Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, + Dwarf_Error *error) +{ + + if (dbg == NULL || cie_list == NULL || cie_count == NULL || + fde_list == NULL || fde_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_internal_reg_table == NULL) { + if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + if (dbg->dbg_eh_frame == NULL) { + if (_dwarf_frame_section_load_eh(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (dbg->dbg_eh_frame == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + if (dbg->dbg_eh_frame->fs_ciearray == NULL || + dbg->dbg_eh_frame->fs_fdearray == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *cie_list = dbg->dbg_eh_frame->fs_ciearray; + *cie_count = dbg->dbg_eh_frame->fs_cielen; + *fde_list = dbg->dbg_eh_frame->fs_fdearray; + *fde_count = dbg->dbg_eh_frame->fs_fdelen; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_n(Dwarf_Fde *fdelist, Dwarf_Unsigned fde_index, + Dwarf_Fde *ret_fde, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Debug dbg; + + dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; + + if (fdelist == NULL || ret_fde == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + fs = fdelist[0]->fde_fs; + assert(fs != NULL); + + if (fde_index >= fs->fs_fdelen) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *ret_fde = fdelist[fde_index]; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_at_pc(Dwarf_Fde *fdelist, Dwarf_Addr pc, Dwarf_Fde *ret_fde, + Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Debug dbg; + Dwarf_Fde fde; + int i; + + dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; + + if (fdelist == NULL || ret_fde == NULL || lopc == NULL || + hipc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + fs = fdelist[0]->fde_fs; + assert(fs != NULL); + + for (i = 0; (Dwarf_Unsigned)i < fs->fs_fdelen; i++) { + fde = fdelist[i]; + if (pc >= fde->fde_initloc && pc < fde->fde_initloc + + fde->fde_adrange) { + *ret_fde = fde; + *lopc = fde->fde_initloc; + *hipc = fde->fde_initloc + fde->fde_adrange - 1; + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); +} + +int +dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *ret_cie, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || ret_cie == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_cie = fde->fde_cie; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len, + Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset, + Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || low_pc == NULL || func_len == NULL || + fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL || + cie_index == NULL || fde_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *low_pc = fde->fde_initloc; + *func_len = fde->fde_adrange; + *fde_bytes = fde->fde_addr; + *fde_byte_len = fde->fde_length; + *cie_offset = fde->fde_cieoff; + *cie_index = fde->fde_cie->cie_index; + *fde_offset = fde->fde_offset; + + return (DW_DLV_OK); +} + +int +dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, + Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf, + Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst, + Dwarf_Unsigned *inst_len, Dwarf_Error *error) +{ + + if (cie == NULL || bytes_in_cie == NULL || version == NULL || + augmenter == NULL || caf == NULL || daf == NULL || ra == NULL || + initinst == NULL || inst_len == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *bytes_in_cie = cie->cie_length; + *version = cie->cie_version; + *augmenter = (char *) cie->cie_augment; + *caf = cie->cie_caf; + *daf = cie->cie_daf; + *ra = cie->cie_ra; + *initinst = cie->cie_initinst; + *inst_len = cie->cie_instlen; + + return (DW_DLV_OK); +} + +int +dwarf_get_cie_index(Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error) +{ + + if (cie == NULL || cie_index == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *cie_index = cie->cie_index; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_instr_bytes(Dwarf_Fde fde, Dwarf_Ptr *ret_inst, + Dwarf_Unsigned *ret_len, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || ret_inst == NULL || ret_len == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_inst = fde->fde_inst; + *ret_len = fde->fde_instlen; + + return (DW_DLV_OK); +} + +#define RL rt->rt3_rules[table_column] +#define CFA rt->rt3_cfa_rule + +int +dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, + Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, + Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || offset_relevant == NULL || register_num == NULL || + offset == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (table_column == dbg->dbg_frame_cfa_value) { + /* Application ask for CFA. */ + *offset_relevant = CFA.dw_offset_relevant; + *register_num = CFA.dw_regnum; + *offset = CFA.dw_offset_or_block_len; + } else { + /* Application ask for normal registers. */ + if (table_column >= dbg->dbg_frame_rule_table_size || + table_column >= DW_REG_TABLE_SIZE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + *offset_relevant = RL.dw_offset_relevant; + *register_num = RL.dw_regnum; + *offset = RL.dw_offset_or_block_len; + } + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Regtable3 *rt; + Dwarf_Addr pc; + Dwarf_Half cfa; + int i, ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg_table == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(dbg != NULL); + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + /* + * Copy the CFA rule to the column intended for holding the CFA, + * if it's within the range of regtable. + */ + cfa = dbg->dbg_frame_cfa_value; + if (cfa < DW_REG_TABLE_SIZE) { + reg_table->rules[cfa].dw_offset_relevant = + CFA.dw_offset_relevant; + reg_table->rules[cfa].dw_regnum = CFA.dw_regnum; + reg_table->rules[cfa].dw_offset = CFA.dw_offset_or_block_len; + } + + /* + * Copy other columns. + */ + for (i = 0; i < DW_REG_TABLE_SIZE && i < dbg->dbg_frame_rule_table_size; + i++) { + + /* Do not overwrite CFA column */ + if (i == cfa) + continue; + + reg_table->rules[i].dw_offset_relevant = + rt->rt3_rules[i].dw_offset_relevant; + reg_table->rules[i].dw_regnum = rt->rt3_rules[i].dw_regnum; + reg_table->rules[i].dw_offset = + rt->rt3_rules[i].dw_offset_or_block_len; + } + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, + Dwarf_Addr pc_requested, Dwarf_Small *value_type, + Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, + Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, + Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || value_type == NULL || offset_relevant == NULL || + register_num == NULL || offset_or_block_len == NULL || + block_ptr == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (table_column >= dbg->dbg_frame_rule_table_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); + return (DW_DLV_ERROR); + } + + *value_type = RL.dw_value_type; + *offset_relevant = RL.dw_offset_relevant; + *register_num = RL.dw_regnum; + *offset_or_block_len = RL.dw_offset_or_block_len; + *block_ptr = RL.dw_block_ptr; + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, + Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, + Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || value_type == NULL || offset_relevant == NULL || + register_num == NULL || offset_or_block_len == NULL || + block_ptr == NULL || row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *value_type = CFA.dw_value_type; + *offset_relevant = CFA.dw_offset_relevant; + *register_num = CFA.dw_regnum; + *offset_or_block_len = CFA.dw_offset_or_block_len; + *block_ptr = CFA.dw_block_ptr; + *row_pc = pc; + + return (DW_DLV_OK); +} + +#undef RL +#undef CFA + +int +dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested, + Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + Dwarf_Debug dbg; + Dwarf_Addr pc; + int ret; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg_table == NULL || reg_table->rt3_rules == NULL || + row_pc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + assert(dbg != NULL); + + if (pc_requested < fde->fde_initloc || + pc_requested >= fde->fde_initloc + fde->fde_adrange) { + DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + ret = _dwarf_frame_regtable_copy(dbg, ®_table, rt, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *row_pc = pc; + + return (DW_DLV_OK); +} + +int +dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, + Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int ret; + + dbg = cie != NULL ? cie->cie_dbg : NULL; + + if (cie == NULL || instruction == NULL || len == 0 || + ret_oplist == NULL || ret_opcnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_frame_get_fop(dbg, instruction, len, ret_oplist, ret_opcnt, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + return (DW_DLV_OK); +} + +Dwarf_Half +dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_rule_table_size; + dbg->dbg_frame_rule_table_size = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_rule_initial_value; + dbg->dbg_frame_rule_initial_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_cfa_value; + dbg->dbg_frame_cfa_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_same_value; + dbg->dbg_frame_same_value = value; + + return (old_value); +} + +Dwarf_Half +dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value) +{ + Dwarf_Half old_value; + + old_value = dbg->dbg_frame_undefined_value; + dbg->dbg_frame_undefined_value = value; + + return (old_value); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 b/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 new file mode 100644 index 0000000..5960ee9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_funcs.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_funcs.m4 2073 2011-10-27 03:30:47Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(func,Func,func,static_func) diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 new file mode 100644 index 0000000..5b5d5a1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 @@ -0,0 +1,258 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_AT_name.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 22, 2011 +.Os +.Dt DWARF_GET_AT_NAME 3 +.Sh NAME +.Nm dwarf_get_ACCESS_name , +.Nm dwarf_get_AT_name , +.Nm dwarf_get_ATE_name , +.Nm dwarf_get_CC_name , +.Nm dwarf_get_CFA_name , +.Nm dwarf_get_CHILDREN_name , +.Nm dwarf_get_DS_name , +.Nm dwarf_get_DSC_name , +.Nm dwarf_get_EH_name , +.Nm dwarf_get_END_name , +.Nm dwarf_get_FORM_name , +.Nm dwarf_get_ID_name , +.Nm dwarf_get_INL_name , +.Nm dwarf_get_LANG_name , +.Nm dwarf_get_LNE_name , +.Nm dwarf_get_LNS_name , +.Nm dwarf_get_MACINFO_name , +.Nm dwarf_get_OP_name , +.Nm dwarf_get_ORD_name , +.Nm dwarf_get_TAG_name , +.Nm dwarf_get_VIRTUALITY_name , +.Nm dwarf_get_VIS_name +.Nd retrieve the symbolic names of DWARF constants +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_ACCESS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_AT_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ATE_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CC_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CFA_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_CHILDREN_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_DS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_DSC_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_EH_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_END_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_FORM_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ID_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_INL_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LANG_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LNE_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_LNS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_MACINFO_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_OP_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_ORD_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_TAG_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_VIRTUALITY_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Ft int +.Fo dwarf_get_VIS_name +.Fa "unsigned val" +.Fa "char **str" +.Fc +.Sh DESCRIPTION +These functions return the symbolic name of a numeric DWARF constant. +.Pp +Argument +.Ar val +specifies the numeric value whose symbolic name is desired. +.Pp +Argument +.Ar str +should point to a location which will hold the returned +NUL-terminated string containing the symbolic name of the +specified value. +.Pp +The list of functions and the DWARF constants that they accept are: +.Pp +.Bl -tag -width ".Fn dwarf_get_VIRTUALITY_name" -compact +.It Fn dwarf_get_ACCESS_name +.Dv DW_ACCESS_* +constants. +.It Fn dwarf_get_AT_name +.Dv DW_AT_* +constants. +.It Fn dwarf_get_ATE_name +.Dv DW_ATE_* +constants. +.It Fn dwarf_get_CC_name +.Dv DW_CC_* +constants. +.It Fn dwarf_get_CFA_name +.Dv DW_CFA_* +constants. +.It Fn dwarf_get_CHILDREN_name +.Dv DW_CHILDREN_* +constants. +.It Fn dwarf_get_DS_name +.Dv DW_DS_* +constants. +.It Fn dwarf_get_DSC_name +.Dv DW_DSC_* +constants. +.It Fn dwarf_get_EH_name +.Dv DW_EH_PE_* +constants. +.It Fn dwarf_get_END_name +.Dv DW_END_* +constants. +.It Fn dwarf_get_FORM_name +.Dv DW_FORM_* +constants. +.It Fn dwarf_get_ID_name +.Dv DW_ID_* +constants. +.It Fn dwarf_get_INL_name +.Dv DW_INL_* +constants. +.It Fn dwarf_get_LANG_name +.Dv DW_LANG_* +constants. +.It Fn dwarf_get_LNE_name +.Dv DW_LNE_* +constants. +.It Fn dwarf_get_LNS_name +.Dv DW_LNS_* +constants. +.It Fn dwarf_get_MACINFO_name +.Dv DW_MACINFO_* +constants. +.It Fn dwarf_get_OP_name +.Dv DW_OP_* +constants. +.It Fn dwarf_get_ORD_name +.Dv DW_ORD_* +constants. +.It Fn dwarf_get_TAG_name +.Dv DW_TAG_* +constants. +.It Fn dwarf_get_VIRTUALITY_name +.Dv DW_VIRTUALITY_* +constants. +.It Fn dwarf_get_VIS_name +.Dv DW_VIS_* +constants. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK on success. +If the DWARF constant denoted by argument +.Ar val +is not recognized, these function return +.Dv DW_DLV_NO_ENTRY . +.Sh SEE ALSO +.Xr dwarf 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 new file mode 100644 index 0000000..afb5468 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 @@ -0,0 +1,179 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_abbrev.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd March 27, 2011 +.Os +.Dt DWARF_GET_ABBREV 3 +.Sh NAME +.Nm dwarf_get_abbrev +.Nd retrieve abbreviation information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned offset" +.Fa "Dwarf_Abbrev *ret_abbrev" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Unsigned *attr_count" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev +retrieves information about an abbreviation from the DWARF abbreviations +section, +.Dq ".debug_abbrev" . +Abbreviation information is returned using an opaque descriptor +of type +.Vt Dwarf_Abbrev . +The returned +.Vt Dwarf_Abbrev +descriptor may then be passed to the other abbreviation related APIs +in the DWARF(3) API to retrieve specific information about the +abbreviation. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar offset +should be an offset, relative to the +.Dq ".debug_abbrev" +section, to the start of an abbreviation entry. +.Pp +Argument +.Ar ret_abbrev +should point to a location that will hold a pointer to the +returned +.Vt Dwarf_Abbrev +descriptor. +.Pp +Argument +.Ar length +should point to a location that will hold the number of bytes used +by the abbrevation in the DWARF +.Dq ".debug_abbrev" +section. +.Pp +Argument +.Ar attr_count +should point to a location that will hold the number of +attributes in the abbrevation. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory area used for the +.Vt Dwarf_Abbrev +descriptor returned in argument +.Ar ret_abbrev +is allocated by the +.Lb libdwarf . +Application code should use function +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_ABBREV +to free the memory area when the +.Vt Dwarf_Abbrev +descriptor is no longer needed. +.Ss Application Programming Notes +The last abbreviation entry in a standard DWARF abbreviation section +will have a special length value of 1. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no abbreviation information at offset +.Ar offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ret_abbrev , +.Ar length +or +.Ar attr_count +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no abbreviation information at offset +.Ar offset . +.El +.Sh EXAMPLE +To loop through all the abbreviation information associated with +a DWARF debug context, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Abbrev ab; +Dwarf_Off aboff; +Dwarf_Unsigned length, attr_count; +Dwarf_Half tag; +Dwarf_Error de; +int ret; + +while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, + NULL, NULL, &de)) == DW_DLV_OK) { + while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, + &attr_count, &de)) == DW_DLV_OK) { + if (length == 1) /* Last entry. */ + break; + aboff += length; + if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + if (ret != DW_DLV_OK) + warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); +} +if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_abbrev_tag 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 new file mode 100644 index 0000000..6f9ed84 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_abbrev_children_flag.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd March 14, 2011 +.Os +.Dt DWARF_GET_ABBREV_CHILDREN_FLAG 3 +.Sh NAME +.Nm dwarf_get_abbrev_children_flag +.Nd return a flag indicating the presence of children +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_children_flag +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_children_flag +retrieves a flag indicating whether the DWARF debug information entry +associated with a DWARF abbreviation descriptor has child entries. +.Pp +Argument +.Ar abbrev +should be a valid DWARF abbreviation descriptor, as returned by +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Ar ret +should point to a location which will hold the returned +flag. +The value returned will be one of the following: +.Bl -tag -width ".Dv DW_CHILDREN_yes" -compact +.It Dv DW_CHILDREN_yes +The debugging information entry associated with the +specified abbreviation descriptor has children. +.It Dv DW_CHILDREN_no +The debugging information entry associated with the +specified abbreviation descriptor has no children. +.El +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_children_flag +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_children_flag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar abbrev +or +.Ar ret +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_tag 3 , +.Xr dwarf_get_abbrev_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 new file mode 100644 index 0000000..18c3c29 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_abbrev_code.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd March 13, 2011 +.Os +.Dt DWARF_GET_ABBREV_CODE 3 +.Sh NAME +.Nm dwarf_get_abbrev_code +.Nd retrieve the abbreviation code for an abbreviation +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_code +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_code +retrieves the abbreviation code for the abbreviation entry descriptor +referenced by argument +.Ar abbrev . +.Pp +Argument +.Ar ret +should point to a location which will hold the returned +abbreviation code. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_code +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_code +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar abbrev +or +.Ar ret +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_tag 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 new file mode 100644 index 0000000..f9e084b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 @@ -0,0 +1,159 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_abbrev_entry.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 02, 2011 +.Os +.Dt DWARF_GET_ABBREV_ENTRY 3 +.Sh NAME +.Nm dwarf_get_abbrev_entry +.Nd retrieve attribute information from an abbreviation descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_entry +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Signed ndx" +.Fa "Dwarf_Half *code" +.Fa "Dwarf_Signed *form" +.Fa "Dwarf_Off *offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_entry +retrieves attribute information from a DWARF abbreviation descriptor. +.Pp +Argument +.Ar abbrev +should be a valid abbreviation descriptor, as returned by function +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Ar ndx +specifies the 0-based index of the attribute. +The total count of the attributes contained in the abbreviation +entry can be retrieved using the function +.Xr dwarf_get_abbrev 3 . +.Pp +Argument +.Ar code +should point to a location which will hold a returned +attribute code. +.Pp +Argument +.Ar form +should point to a location which will hold the returned +form of the attribute. +.Pp +Argument +.Ar offset +should point to a location which will hold a returned offset, relative +to the +.Dq ".debug_abbrev" +section, for the specified attribute. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_entry +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if the attribute index specified by argument +.Ar ndx +is out of range. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar abbrev , +.Ar code , +.Ar form +or +.Ar offset +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The attribute index specified by argument +.Ar ndx +was out of range. +.El +.Sh EXAMPLE +To loop through all the attribute entries contained in the +abbreviation section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Abbrev ab; +Dwarf_Off aboff, atoff; +Dwarf_Signed form; +Dwarf_Half attr; +Dwarf_Unsigned length, attr_count; +Dwarf_Error de; +int i, ret; + +/* ...allocate 'dbg' using dwarf_init(3) ... */ + +while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, + NULL, NULL, &de)) == DW_DLV_OK) { + while ((ret = dwarf_get_abbrev(dbg, aboff, &ab, &length, + &attr_count, &de)) == DW_DLV_OK) { + if (length == 1) /* Last entry. */ + break; + aboff += length; + for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { + if (dwarf_get_abbrev_entry(ab, i, + &attr, &form, &atoff, &de) != DW_DLV_OK) { + warnx("dwarf_get_abbrev_entry failed:" + " %s", dwarf_errmsg(de)); + continue; + } + /* .. use the retrieved information ... */ + } + } + + if (ret != DW_DLV_OK) + warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); +} + +if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 new file mode 100644 index 0000000..c1fc37f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_abbrev_tag.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd March 13, 2011 +.Os +.Dt DWARF_GET_ABBREV_TAG 3 +.Sh NAME +.Nm dwarf_get_abbrev_tag +.Nd retrieve the tag for an abbreviation +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_abbrev_tag +.Fa "Dwarf_Abbrev abbrev" +.Fa "Dwarf_Half *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_abbrev_tag +retrieves the tag for the abbreviation entry descriptor referenced by +argument +.Ar abbrev . +.Pp +Argument +.Ar ret +should point to a location which will hold the returned +abbreviation tag. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_abbrev_tag +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_tag +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar abbrev +or +.Ar ret +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_abbrev 3 , +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 b/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 new file mode 100644 index 0000000..856b375 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 @@ -0,0 +1,82 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_address_size.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 14, 2010 +.Os +.Dt DWARF_GET_ADDRESS_SIZE 3 +.Sh NAME +.Nm dwarf_get_address_size +.Nd return the number of bytes needed to represent an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_address_size +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half *addr_size" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_address_size +returns the size in bytes of a native address for a program object. +.Pp +Argument +.Ar dbg +should denote a DWARF debug context created from a program object using +.Xr dwarf_init 3 . +Argument +.Ar addr_size +should point to a location that will hold the returned size. +Argument +.Ar err , +if non-NULL, it will be used to return error information. +.Sh RETURN VALUES +On success, function +.Fn dwarf_tag +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_address_size +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arguments +.Ar dbg +or +.Ar addr_size +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_finish 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 new file mode 100644 index 0000000..b169140 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_arange.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 16, 2011 +.Os +.Dt DWARF_GET_ARANGE 3 +.Sh NAME +.Nm dwarf_get_arange +.Nd retrieve the address range descriptor for an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange +.Fa "Dwarf_Arange *ar_list" +.Fa "Dwarf_Unsigned ar_cnt" +.Fa "Dwarf_Addr addr" +.Fa "Dwarf_Arange *ret_ar" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_arange +searches an array of +.Vt Dwarf_Arange +descriptors for one that covers a given address. +.Pp +Argument +.Ar ar_list +should point to an array of +.Vt Dwarf_Arange +descriptors. +.Pp +Argument +.Ar ar_cnt +specifies the number of +.Vt Dwarf_Arange +descriptors in the array pointed to by argument +.Ar ar_list . +.Pp +Argument +.Ar addr +specifies the address being looked up. +.Pp +Argument +.Ar ret_ar +will be used to store the +.Vt Dwarf_Arange +descriptor that covers the given address. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_arange +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Vt Dwarf_Arange +descriptor that covers the provided address. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_arange +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ar_list +or +.Ar ret_ar +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Value of argument +.Ar ar_cnt +equals to 0. +.It Bq Er DW_DLE_NO_ENTRY +A +.Vt Dwarf_Arange +descriptor that covers the given address +was not found. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_aranges 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 new file mode 100644 index 0000000..e8dac78 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_arange_info.3 2134 2011-11-10 08:40:14Z jkoshy $ +.\" +.Dd April 16, 2011 +.Os +.Dt DWARF_GET_ARANGE_INFO 3 +.Sh NAME +.Nm dwarf_get_arange_info +.Nd extract address range information from a descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange_info +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Addr *start" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_arange_info +extracts address range information from a +.Vt Dwarf_Arange +descriptor. +.Pp +Argument +.Ar ar +should reference a valid +.Vt Dwarf_Arange +descriptor returned by function +.Xr dwarf_get_aranges 3 . +.Pp +Argument +.Ar start +should point to a location which will hold the start value of the +address range associated with the descriptor. +.Pp +Argument +.Ar length +should point to a location which will hold the length in bytes of the +address range associated with the descriptor. +.Pp +Argument +.Ar cu_die_offset +should point to a location which will be set to an offset, relative to +the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Ar ar . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_arange_info +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_arange_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar ar , +.Ar start , +.Ar length +or +.Ar cu_die_offset +was NULL. +.Sh EXAMPLE +To loop through all the address lookup table entries, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Addr start; +Dwarf_Arange *aranges; +Dwarf_Off die_off; +Dwarf_Signed i, cnt; +Dwarf_Unsigned length; +Dwarf_Error de; + +if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_aranges: %s", + dwarf_errmsg(de)); +for (i = 0; i < cnt; i++) { + if (dwarf_get_arange_info(aranges[i], &start, &length, + &die_off, &de) != DW_DLV_OK) { + warnx("dwarf_get_arange_info: %s", + dwarf_errmsg(de)); + continue; + } + /* Do something with the returned information. */ +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_aranges 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 b/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 new file mode 100644 index 0000000..1444704 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 @@ -0,0 +1,148 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_aranges.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_GET_ARANGES 3 +.Sh NAME +.Nm dwarf_get_aranges +.Nd retrieve program address space mappings +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_aranges +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Arange **ar_list" +.Fa "Dwarf_Signed *ar_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_get_aranges +retrieves address range information from the +.Dq ".debug_aranges" +DWARF section. +Information about address ranges is returned using opaque descriptors +of type +.Vt Dwarf_Arange , +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar ar_list +should point to a location which will be set to a pointer to an array +of +.Vt Dwarf_Arange +descriptors. +.Pp +Argument +.Ar ar_cnt +should point to a location which will be set to the number of +descriptors returned. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory area used for the array returned in argument +.Ar ar_list +is owned by +.Lb libdwarf . +Application code should not attempt to directly free this area. +Portable applications should instead use +.Xr dwarf_dealloc 3 +to indicate that the memory area may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_get_aranges +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Dq ".debug_aranges" +section associated with the specified debugging context. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_aranges +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ar_list +or +.Ar ar_cnt +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The debugging context +.Ar dbg +did not contain a +.Dq ".debug_aranges" +string section. +.El +.Sh EXAMPLE +To loop through all the address lookup table entries, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Addr start; +Dwarf_Arange *aranges; +Dwarf_Off die_off; +Dwarf_Signed i, cnt; +Dwarf_Unsigned length; +Dwarf_Error de; + +if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_aranges: %s", + dwarf_errmsg(de)); + +for (i = 0; i < cnt; i++) { + if (dwarf_get_arange_info(aranges[i], &start, &length, + &die_off, &de) != DW_DLV_OK) { + warnx("dwarf_get_arange_info: %s", + dwarf_errmsg(de)); + continue; + } + /* Do something with the returned information. */ +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_cu_die_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 new file mode 100644 index 0000000..d6bc015 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_cie_index.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 22, 2011 +.Os +.Dt DWARF_GET_CIE_INDEX 3 +.Sh NAME +.Nm dwarf_get_cie_index +.Nd retrieve the index of a CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_index +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Signed *cie_index" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_index +retrieves the zero-based index of a given CIE descriptor in the array +of CIE descriptors returned by the functions +.Xr dwarf_get_fde_list 3 +and +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Ar cie +should reference a valid DWARF CIE descriptor. +.Pp +Argument +.Ar cie_index +should point to a location that will hold the returned index. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_index +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_index +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arugments +.Ar cie +or +.Ar cie_index +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 new file mode 100644 index 0000000..f3710ca --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 @@ -0,0 +1,150 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_cie_info.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 29, 2011 +.Os +.Dt DWARF_GET_CIE_INFO 3 +.Sh NAME +.Nm dwarf_get_cie_info +.Nd retrieve information associated with a CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_info +.Fa "Dwarf_Cie cie" +.Fa "Dwarf_Unsigned *cie_byte_len" +.Fa "Dwarf_Small *version" +.Fa "char **augmentation" +.Fa "Dwarf_Unsigned *caf" +.Fa "Dwarf_Unsigned *daf" +.Fa "Dwarf_Half *ra" +.Fa "Dwarf_Ptr *init_inst" +.Fa "Dwarf_Unsigned *inst_len" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_info +retrieves the information associated with a given CIE descriptor. +.Pp +Argument +.Ar cie +should reference a valid DWARF CIE descriptor, such as would be +returned by function +.Xr dwarf_get_cie_of_fde 3 . +.Pp +Argument +.Ar cie_byte_len +should point to a location that will hold the length in bytes of +the CIE descriptor itself. +.Pp +Argument +.Ar version +should point to a location that will hold the version number of +the CIE descriptor. +.Pp +Arugment +.Ar augmentation +should point to a location that will be set to a pointer to a +NUL-terminated string containing augmentation data encoded as UTF-8. +.Pp +Argument +.Ar caf +should point to a location that will hold the code alignment +factor recorded in the CIE descriptor. +.Pp +Arugment +.Ar daf +should point to a location that will hold the data alignment +factor recorded in the CIE descriptor. +.Pp +Argument +.Ar ra +should point to a location that will hold the return address +recorded in the CIE descriptor. +.Pp +Argument +.Ar init_inst +should point to a location that will be set to a pointer to an array +of bytes containing the initial instructions associated with the CIE +descriptor. +.Pp +Argument +.Ar inst_len +should point to a location that will hold the length in bytes +of the initial instructions returned in argument +.Ar init_inst . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_info +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar cie , +.Ar cie_byte_len , +.Ar version , +.Ar augmentation , +.Ar caf , +.Ar daf , +.Ar ra , +.Ar init_inst +or +.Ar inst_len +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 new file mode 100644 index 0000000..4fa5c5d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 @@ -0,0 +1,88 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_cie_of_fde.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 22, 2011 +.Os +.Dt DWARF_GET_CIE_OF_FDE 3 +.Sh NAME +.Nm dwarf_get_cie_of_fde +.Nd retrieve CIE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_cie_of_fde +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Cie *ret_cie" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_cie_of_fde +retrieves the CIE descriptor associated with a given FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid FDE descriptor. +.Pp +Argument +.Ar ret_cie +should point to a location that will hold the returned CIE +descriptor. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_cie_of_fde +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_cie_of_fde +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of arugments +.Ar fde +or +.Ar ret_cie +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 b/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 new file mode 100644 index 0000000..b71e431 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_cu_die_offset.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 10, 2011 +.Os +.Dt DWARF_GET_CU_DIE_OFFSET 3 +.Sh NAME +.Nm dwarf_get_arange_cu_header_offset , +.Nm dwarf_get_cu_die_offset +.Nd retrieve compilation unit offsets +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_arange_cu_header_offset +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Off *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_cu_die_offset +.Fa "Dwarf_Arange ar" +.Fa "Dwarf_Off *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve the offsets, relative to the +.Dq ".debug_info" +DWARF section, of the debugging information entries describing the +compilation unit associated with a +.Vt Dwarf_Arange +descriptor. +.Pp +Function +.Fn dwarf_get_arange_cu_header_offset +retrieves the offset of the compilation unit header associated with +argument +.Ar ar , +and stores it in the location pointed to by argument +.Ar ret . +.Pp +Function +.Fn dwarf_get_cu_die_offset +retrieves the offset of the debugging information entry for the +compilation unit associated with argument +.Ar ar , +and stores it in the location pointed to by argument +.Ar ret . +.Pp +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar ar +was not a valid +.Vt Dwarf_Arange +descriptor. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar ret +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_arange 3 , +.Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_aranges 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 b/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 new file mode 100644 index 0000000..c93a7ef --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 @@ -0,0 +1,103 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_get_elf.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_GET_ELF 3 +.Sh NAME +.Nm dwarf_get_elf +.Nd retrieve the +.Vt Elf +descriptor associated with a +.Vt Dwarf_Debug +instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_elf +.Fa "Dwarf_Debug dbg" +.Fa "Elf **elf" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_elf +returns the +.Vt Elf +descriptor associated with a +.Vt Dwarf_Debug +instance. +.Pp +Argument +.Ar dbg +should be a handle to a valid +.Vt Dwarf_Debug +instance returned by a prior call to +.Xr dwarf_init 3 +or +.Xr dwarf_elf_init 3 . +.Pp +Argument +.Ar elf +points a location into which a handle to an +.Vt Elf +descriptor will be written. +.Pp +Argument +.Ar err +is used to record error information in case of failure. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_elf +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh EXAMPLES +To retrieve the +.Vt Elf +instance associated with a +.Vt Dwarf_Debug +instance use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Error de; +Elf *elf; + +\&... allocate dbg using dwarf_init() etc ... + +if (dwarf_get_elf(dbg, &elf, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_init 3 , +.Xr dwarf_finish 3 , +.Xr elf 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 new file mode 100644 index 0000000..8aa36ec --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_at_pc.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 22, 2011 +.Os +.Dt DWARF_GET_FDE_AT_PC 3 +.Sh NAME +.Nm dwarf_get_fde_at_pc +.Nd retrieve the FDE descriptor for an address +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_at_pc +.Fa "Dwarf_Fde *fdelist" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Fde *ret_fde" +.Fa "Dwarf_Addr *lopc" +.Fa "Dwarf_Addr *hipc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_at_pc +searches the provided array of DWARF FDE descriptors for a descriptor +covering a given program counter address. +.Pp +Argument +.Ar fdelist +should point to an array of FDE descriptors, as returned by the functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Ar pc +should contain the program counter address being looked up. +.Pp +Argument +.Ar ret_fde +should point to a location that will hold the returned FDE descriptor. +.Pp +Argument +.Ar lopc +should point to a location that will be set to the lowest address +covered by the returned FDE descriptor. +.Pp +Argument +.Ar hipc +should point to a location that will be set to the highest address +covered by the returned FDE descriptor. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_at_pc +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if a FDE descriptor that covers the address specified by argument +.Ar pc +is not found. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_at_pc +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va fdelist , +.Va ret_fde , +.Va lopc , +or +.Va hipc +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +These was no FDE descriptor covering the address specified by argument +.Ar pc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 new file mode 100644 index 0000000..014d138 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 @@ -0,0 +1,155 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_info_for_all_regs.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd June 4, 2011 +.Os +.Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS 3 +.Sh NAME +.Nm dwarf_get_fde_info_for_all_regs +.Nd retrieve register rule row +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_all_regs +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Regtable *reg_table" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_all_regs +retrieves a row from the register rule table associated with the given +FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Ar pc +should hold the program counter address to be used to locate the +desired table row. +.Pp +Argument +.Ar reg_table +should point to a +.Vt Dwarf_Regtable +descriptor which will hold the returned table row of register rules. +.Pp +Argument +.Ar row_pc +should point to a location which will be set to the lowest program +counter address associated with the table row. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +The +.Vt Dwarf_Regtable +descriptor is defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct { + struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Half dw_regnum; + Dwarf_Addr dw_offset; + } rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable; +.Ed +.Pp +For each of the register rules returned, +the +.Va dw_offset_relevant +field is set to 1 if the register rule has a offset value. The +.Va dw_regnum +field is set to the register number associated with the regsiter rule. +The +.Va dw_offset +field is set to the offset value associated with the register rule. +.Pp +The number of register columns returned is either the constant +value +.Dv DW_REG_TABLE_SIZE as defined +in the header file +.In libdwarf.h , +or the value set by function +.Xr dwarf_set_frame_rule_table_size 3 , +whichever is smaller. +.Ss COMPATIBILITY +Function +.Fn dwarf_get_fde_info_for_all_regs +is deprecated since it only supports DWARF2 frame sections. +Applications should instead use function +.Xr dwarf_get_fde_info_for_all_regs3 3 +which supports both DWARF2 and DWARF3 frame sections. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_all_regs +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_all_regs +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar fde , +.Ar reg_table +or +.Ar row_pc +was NULL. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 new file mode 100644 index 0000000..841d983 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 @@ -0,0 +1,183 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_info_for_all_regs3.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd June 26, 2011 +.Os +.Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS3 3 +.Sh NAME +.Nm dwarf_get_fde_info_for_all_regs3 +.Nd retrieve register rule row +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_all_regs3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Regtable3 *reg_table" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_all_regs3 +retrieves a row from the register rule table associated with the given +FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Ar pc +should hold the program counter address to be used to locate the +desired table row. +.Pp +Argument +.Ar reg_table +should point to a +.Vt Dwarf_Regtable3 +descriptor which will hold the returned table row of register rules. +The +.Vt Dwarf_Regtable3 +descriptor is defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; +} Dwarf_Regtable_Entry3; + +typedef struct { + Dwarf_Regtable_Entry3 rt3_cfa_rule; + Dwarf_Half rt3_reg_table_size; + Dwarf_Regtable_Entry3 *rt3_rules; +} Dwarf_Regtable3; +.Ed +.Pp +The +.Va rt3_reg_table_size +field specifies the maximum number of register rule columns to be +returned, and should be set by the application before calling the +function. +The +.Va rt3_rules +field should point to a memory arena allocated by the application with +space for at least +.Vt rt3_reg_table_size +descriptors of type +.Vt Dwarf_Regtable_Entry3 . +.Pp +On a successful execution of this function, the +.Va rt3_cfa_rule +field will be set to the CFA register rule associated with the table +row, and the +.Va rt3_rules +array will hold the returned register rules contained in the table row. +.Pp +For each register rule descriptor returned, +the +.Va dw_offset_relevant +field will be set to 1 if the register rule has a offset value, +the +.Va dw_value_type +field will be set to the type code of the register rule and the +.Va dw_regnum +field will be set to the register number associated with the register rule. +If the register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the +.Va dw_offset_or_block_len +field will be set to the offset value associated with the register rule. +If the type is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the +.Va dw_offset_or_block_len +field will be set to the length in bytes of the DWARF expression block +associated with the register rule. +The +.Va dw_block_ptr +field will be set to a pointer to the content of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Ar row_pc +should point to a location which will be set to the lowest program +counter address associated with the table row. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_all_regs3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_all_regs3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar fde , +.Ar reg_table +or +.Ar row_pc +was NULL. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 new file mode 100644 index 0000000..f8271f0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 @@ -0,0 +1,171 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_info_for_cfa_reg3.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd June 12, 2011 +.Os +.Dt DWARF_GET_FDE_INFO_FOR_CFA_REGS3 3 +.Sh NAME +.Nm dwarf_get_fde_info_for_cfa_regs3 +.Nd retrieve a CFA register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_cfa_regs3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Small *type" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset_or_block_len" +.Fa "Dwarf_Ptr *block_ptr" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +retrieves the CFA register rule for a given program counter address +from the register rule table associated with an FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Ar pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_cfa_reg3 +stores information about the CFA register rule found into the locations +pointed to by the arguments +.Ar type , +.Ar offset_relevant , +.Ar register_num , +.Ar offset_or_block_len , +.Ar block_ptr +and +.Ar row_pc . +.Pp +Argument +.Ar type +should point to a location which will hold the type code of the +register rule found. +The returned value is one of the +.Dv DW_EXPR_* +contants defined in the header file +.In libdwarf.h . +.Pp +If there is an offset value associated with the CFA register rule, +the location pointed to by argument +.Ar offset_relevant +will be set to 1. +.Pp +Argument +.Ar register_num +should point to a location which will hold the register number associated +with the CFA register rule. +.Pp +If the CFA register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the location pointed to by argument +.Ar offset_or_block_len +will be set to the offset value associated with the register rule, +or to 0 if the register rule does not have an offset value. +If the type code is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the location pointed to by argument +.Ar offset_or_block_len +will be set to the length in bytes of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Ar block_ptr +should point to a location which will be set to a pointer to the +content of the DWARF expression block associated with the CFA register +rule. +.Pp +Argument +.Ar row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_cfa_reg3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar block_ptr , +.Ar fde , +.Ar offset_or_block_len , +.Ar offset_relevant , +.Ar register_num , +.Ar row_pc , +or +.Ar type +was NULL. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 new file mode 100644 index 0000000..3d46806 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 @@ -0,0 +1,156 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_info_for_reg.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd June 4, 2011 +.Os +.Dt DWARF_GET_FDE_INFO_FOR_REG 3 +.Sh NAME +.Nm dwarf_get_fde_info_for_reg +.Nd retrieve register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_reg +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Half table_column" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_reg +retrieves a register rule from the register rule table associated with +a given FDE descriptor, given a program counter address and rule +column number. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Arugment +.Ar table_column +should hold the column number of the register rule desired. +.Pp +Argument +.Ar pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_reg +stores information about the register rule found into the locations +pointed to by the arguments +.Ar offset_relevant , +.Ar register_num , +.Ar offset +and +.Ar row_pc . +.Pp +If there is an offset value associated with the register rule, +the location pointed to by argument +.Ar offset_relevant +will be set to 1. +.Pp +Argument +.Ar register_num +should point to a location which will hold the register number associated +with the register rule. +.Pp +Argument +.Ar offset +should point to a location which will be set to the offset value +associated with the register rule, or to 0 if the register rule +does not have an offset value. +.Pp +Argument +.Ar row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Ss COMPATIBILITY +Function +.Fn dwarf_get_fde_info_for_reg +is deprecated since it only supports DWARF2 frame sections. +Applications should instead use function +.Xr dwarf_get_fde_info_for_reg3 3 +which supports both DWARF2 and DWARF3 frame sections. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_reg +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_reg +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar fde , +.Ar offset_relevant , +.Ar register_num , +.Ar offset +or +.Ar row_pc +was NULL. +.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD +The column number provided in argument +.Ar table_column +was too large. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 new file mode 100644 index 0000000..85c0f7f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 @@ -0,0 +1,214 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_info_for_reg3.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_GET_FDE_INFO_FOR_REG3 3 +.Sh NAME +.Nm dwarf_get_fde_info_for_reg3 +.Nd retrieve register rule +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_info_for_reg3 +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Half table_column" +.Fa "Dwarf_Addr pc" +.Fa "Dwarf_Small *type" +.Fa "Dwarf_Signed *offset_relevant" +.Fa "Dwarf_Signed *register_num" +.Fa "Dwarf_Signed *offset_or_block_len" +.Fa "Dwarf_Ptr *block_ptr" +.Fa "Dwarf_Addr *row_pc" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_info_for_reg3 +retrieves a register rule from the register rule table associated with +a given FDE descriptor, given a program counter address and rule +column number. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Arugment +.Ar table_column +should hold the column number of the register rule desired. +.Pp +Argument +.Ar pc +should hold the program counter address to be used to locate the +desired register rule row. +.Pp +On successful execution, +.Fn dwarf_get_fde_info_for_reg3 +stores information about the register rule found into the locations +pointed to by the arguments +.Ar type , +.Ar offset_relevant , +.Ar register_num , +.Ar offset_or_block_len , +.Ar block_ptr +and +.Ar row_pc . +.Pp +Argument +.Ar type +should point to a location which will hold the type code of the +register rule found. +The returned value is one of the +.Dv DW_EXPR_* +contants defined in the header file +.In libdwarf.h . +.Pp +If there is an offset value associated with the register rule, +the location pointed to by argument +.Ar offset_relevant +will be set to 1. +.Pp +Argument +.Ar register_num +should point to a location which will hold the register number associated +with the register rule. +.Pp +If the register rule is of type +.Dv DW_EXPR_OFFSET +or +.Dv DW_EXPR_VAL_OFFSET , +the location pointed to by argument +.Ar offset_or_block_len +will be set to the offset value associated with the register rule, +or to 0 if the register rule does not have an offset value. +If the type code is +.Dv DW_EXPR_EXPRESSION +or +.Dv DW_EXPR_VAL_EXPRESSION , +the location pointed to by argument +.Ar offset_or_block_len +will be set to the length in bytes of the DWARF expression block +associated with the register rule. +.Pp +Argument +.Ar block_ptr +should point to a location which will be set to a pointer to the +content of the DWARF expression block associated with the register +rule. +.Pp +Argument +.Ar row_pc +should point to a location which will be set to the lowest program +counter address associated with the register rule found. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_info_for_reg3 +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_reg3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar block_ptr , +.Ar fde , +.Ar offset_or_block_len , +.Ar offset_relevant , +.Ar register_num , +.Ar row_pc , +or +.Ar type +was NULL. +.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD +The column number provided in argument +.Ar table_column +was too large. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El +.Sh EXAMPLE +To retrieve the register rules at column 3 from a rule table +associated with a FDE descriptor: +.Bd -literal -offset indent +Dwarf_Fde fde; +Dwarf_Off fde_offset, cie_offset; +Dwarf_Unsigned func_len, fde_length; +Dwarf_Signed cie_index, offset_relevant, register_num; +Dwarf_Signed offset_or_block_len; +Dwarf_Addr low_pc, row_pc; +Dwarf_Ptr fde_addr, block_ptr; +Dwarf_Small type; +Dwarf_Error de; + +/* ... assuming `fde` references a valid FDE descriptor... */ +if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, + &fde_length, &cie_offset, &cie_index, &fde_offset, + &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_get_fde_range failed: %s", + dwarf_errmsg(de)); + +/* Iterate all the table rows. */ +for (pc = low_pc; pc < low_pc + func_len; pc++) { + if (dwarf_get_fde_info_for_reg3(fde, 3, pc, &type, + &offset_relevant, ®ister_num, &offset_or_block_len, + &block_ptr, &row_pc, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_info_for_reg3 failed: %s", + dwarf_errmsg(de)); + continue; + } + /* ... use the retrieved register rule ... */ +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 new file mode 100644 index 0000000..488d566 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 @@ -0,0 +1,113 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_instr_bytes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 23, 2011 +.Os +.Dt DWARF_GET_FDE_INSTR_BYTES 3 +.Sh NAME +.Nm dwarf_get_fde_instr_bytes +.Nd retrieve instructions from FDE descritpor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_instr_bytes +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Ptr *ret_inst" +.Fa "Dwarf_Unsigned *ret_len" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_instr_bytes +retrieves instruction bytes from a given FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Ar ret_inst +should point to a location that will be set to a pointer +to an array of bytes containing the instructions of the +FDE descriptor. +.Pp +Argument +.Ar ret_len +should point to a location that will hold the length in +bytes of the instructions returned in argument +.Ar ret_inst . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +Applications can use the function +.Xr dwarf_expand_frame_instructions 3 +to parse and expand the returned instruction bytes into an array of +.Vt Dwarf_Frame_Op +descriptors. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_instr_bytes +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_instr_bytes +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar fde , +.Ar ret_inst +or +.Ar ret_len +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_expand_frame_instructions 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 new file mode 100644 index 0000000..7164ae6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 @@ -0,0 +1,218 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_list.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_GET_FDE_LIST 3 +.Sh NAME +.Nm dwarf_get_fde_list +.Nd retrieve frame information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_list +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie **cie_list" +.Fa "Dwarf_Signed *cie_count" +.Fa "Dwarf_Fde **fde_list" +.Fa "Dwarf_Signed *fde_count" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_fde_list_eh +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Cie **cie_list" +.Fa "Dwarf_Signed *cie_count" +.Fa "Dwarf_Fde **fde_list" +.Fa "Dwarf_Signed *fde_count" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve frame related information for the specified +DWARF debug context. +.Pp +Function +.Fn dwarf_get_fde_list +retrieves frame information from the DWARF section named +.Dq ".debug_frame" . +For objects containing GNU style C++ exception handling +information, the function +.Fn dwarf_get_fde_list_eh +retrieves frame information from the section named +.Dq ".eh_frame" . +.Pp +Frame information is returned using opaque descriptors +of type +.Vt Dwarf_Cie +and +.Vt Dwarf_Fde . +Applications need to use the other frame related functions in the +DWARF(3) API set to retrieve the information contained in these +descriptors. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar cie_list +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Cie +descriptors. +.Pp +Argument +.Ar cie_count +should point to a location that will be set to the number of +.Vt Dwarf_Cie +descriptors returned. +.Pp +Argument +.Ar fde_list +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Fde +descriptors. +.Pp +Argument +.Ar fde_count +should point to a location that will be set to the number of +.Vt Dwarf_Fde +descriptors returned. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory areas used for the arrays returned in arguments +.Ar cie_list +and +.Ar fde_list +are owned by the +.Lb libdwarf . +Application code should not attempt to directly free these areas. +Portable applications should instead use the +.Xr dwarf_fde_cie_list_dealloc 3 +function to indicate that these memory areas may be freed. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +They return +.Dv DW_DLV_NO_ENTRY +if there is no frame information associated with the given DWARF +debug context. +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va dbg , +.Va cie_list , +.Va cie_count , +.Va fde_list +or +.Va fde_count +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no frame information associated with the giving DWARF debug +context. +.El +.Sh EXAMPLE +To obtain frame information from the +.Dq ".debug_frame" +section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Cie *cie_list, cie; +Dwarf_Fde *fde_list, fde; +Dwarf_Off fde_offset, cie_offset; +Dwarf_Unsigned func_len, fde_length, fde_instlen; +Dwarf_Signed cie_count, fde_count, cie_index; +Dwarf_Addr low_pc; +Dwarf_Ptr fde_addr, fde_inst, cie_inst; +Dwarf_Error de; +int i; + +if (dwarf_get_fde_list(dbg, &cie_list, &cie_count, + &fde_list, &fde_count, &de) != DW_DLV_OK) { + errx(EXIT_FAILURE, "dwarf_get_fde_list failed: %s", + dwarf_errmsg(de)); +} + +for (i = 0; i < fde_count; i++) { + if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_n failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, + &fde_length, &cie_offset, &cie_index, &fde_offset, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_range failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, + &de) != DW_DLV_OK) { + warnx("dwarf_get_fde_instr_bytes failed: %s", + dwarf_errmsg(de)); + continue; + } + + /* ... Use the retrieved frame information ... */ +} + +/* Indicate that the returned arrays may be freed. */ +dwarf_fde_cie_list_dealloc(dbg, cie_list, cie_count, fde_list, + fde_count); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_n 3 , +.Xr dwarf_get_fde_range 3 , +.Xr dwarf_fde_cie_list_dealloc 3 , +.Xr dwarf_set_frame_cfa_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , +.Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_same_value 3 , +.Xr dwarf_set_frame_undefined_value 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 new file mode 100644 index 0000000..dbb6c27 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_n.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 14, 2011 +.Os +.Dt DWARF_GET_FDE_N 3 +.Sh NAME +.Nm dwarf_get_fde_n +.Nd retrieve FDE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_n +.Fa "Dwarf_Fde *fdelist" +.Fa "Dwarf_Unsigned fde_index" +.Fa "Dwarf_Fde *ret_fde" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_n +retrieves an FDE descriptor from an array of FDE descriptors. +.Pp +Argument +.Ar fdelist +should point to an array of FDE descriptors, as returned by the functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Ar fde_index +specifies the 0-based index of the desired FDE descriptor. +.Pp +Argument +.Ar ret_fde +should point to a location that will hold the returned FDE descriptor. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_n +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if the FDE descriptor index specified by argument +.Ar fde_index +is out of range. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_n +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar fdelist +or +.Ar ret_fde +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The FDE descriptor index specified by argument +.Ar fde_index +was out of range. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_of_fde 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_range 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 b/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 new file mode 100644 index 0000000..1ea708c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 @@ -0,0 +1,149 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_fde_range.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd May 22, 2011 +.Os +.Dt DWARF_GET_FDE_RANGE 3 +.Sh NAME +.Nm dwarf_get_fde_range +.Nd retrieve range information from an FDE descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_fde_range +.Fa "Dwarf_Fde fde" +.Fa "Dwarf_Addr *low_pc" +.Fa "Dwarf_Unsigned *func_len" +.Fa "Dwarf_Ptr *fde_bytes" +.Fa "Dwarf_Unsigned *fde_byte_len" +.Fa "Dwarf_Off *cie_offset" +.Fa "Dwarf_Signed *cie_index" +.Fa "Dwarf_Off *fde_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_fde_range +retrieves range and offset information from a given FDE descriptor. +.Pp +Argument +.Ar fde +should reference a valid DWARF FDE descriptor. +.Pp +Argument +.Ar low_pc +should point to a location that will be set to the lowest +program counter address covered by the FDE descriptor. +.Pp +Argument +.Ar func_len +should point to a location that will hold the length in bytes of +the address range covered by the FDE descriptor. +.Pp +Argument +.Ar fde_bytes +should point to a location that will be set to a pointer to the +content of the FDE descriptor itself. +.Pp +Argument +.Ar fde_byte_len +should point to a location that will hold the length in bytes of +the FDE descriptor itself. +.Pp +Argument +.Ar cie_offset +should point to a location that will be set to the offset, relative to +the DWARF +.Dq ".debug_frame" +section, of the CIE descriptor associated with the given FDE +descriptor. +.Pp +Argument +.Ar cie_index +should point to a location that will hold the index of the CIE +descriptor associated with the FDE descriptor. +The returned value is a zero-based index into the array of CIE +descriptors returned by a prior call to functions +.Xr dwarf_get_fde_list 3 +or +.Xr dwarf_get_fde_list_eh 3 . +.Pp +Argument +.Ar fde_offset +should point to a location that will be set to the offset, relative to +the DWARF +.Dq ".debug_frame" +section, of the FDE descriptor. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_fde_range +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_fde_range +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar fde , +.Ar low_pc , +.Ar func_len , +.Ar fde_bytes , +.Ar fde_byte_len , +.Ar cie_offset , +.Ar cie_index +or +.Ar fde_offset +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_instr_bytes 3 , +.Xr dwarf_get_fde_list 3 , +.Xr dwarf_get_fde_list_eh 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 b/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 new file mode 100644 index 0000000..82cbe1a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_form_class.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd June 26, 2011 +.Os +.Dt DWARF_GET_FORM_CLASS 3 +.Sh NAME +.Nm dwarf_get_form_class +.Nd retrieve the form class of an attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft enum Dwarf_Form_Class +.Fo dwarf_get_form_class +.Fa "Dwarf_Half dwversion" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Half offset_size" +.Fa "Dwarf_Half form" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_form_class +returns the class of the form of a DWARF attribute. +.Pp +Argument +.Ar dwversion +should specify the version number of DWARF specification +to use: 2 for DWARF2, 3 for DWARF3 and 4 for DWARF4. +.Pp +Argument +.Ar attr +should hold the attribute code of the attribute, i.e., one of the +.Li DW_AT_* +values defined in +.In libdwarf.h . +.Pp +Argument +.Ar offset_size +should hold the size of a DWARF offset for the relevant compilation +unit. +.Pp +Argument +.Ar form +should hold the form code of the attribute. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_form_class +returns the form class code, which is one of the +.Dv DW_FORM_CLASS_* +contants defined in header file +.In libdwarf.h . +If the function was not able to determine the form class of the +attribute, it returns the special form class code +.Dv DW_FORM_CLASS_UNKNOWN . +.Sh ERRORS +Function +.Fn dwarf_get_form_class +does not return an error. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_whatattr 3 , +.Xr dwarf_whatform 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 b/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 new file mode 100644 index 0000000..4abc1d9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 @@ -0,0 +1,215 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_funcs.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 10, 2011 +.Os +.Dt DWARF_GET_FUNCS 3 +.Sh NAME +.Nm dwarf_get_funcs , +.Nm dwarf_func_cu_offset , +.Nm dwarf_func_die_offset , +.Nm dwarf_func_name_offsets , +.Nm dwarf_funcname +.Nd retrieve information about static functions +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_funcs +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Func **funcs" +.Fa "Dwarf_Signed *nfuncs" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_cu_offset +.Fa "Dwarf_Func func" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_die_offset +.Fa "Dwarf_Func func" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_func_name_offsets +.Fa "Dwarf_Func func" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_funcname +.Fa "Dwarf_Func func" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about static functions from the +lookup tables in the (SGI-specific) +.Dq ".debug_funcnames" +section. +Information about these functions is returned using opaque descriptors +of type +.Vt Dwarf_Func . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_funcs +retrieves descriptors for all the static functions associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar funcs +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Func +descriptors. +The argument +.Ar nfuncs +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_func_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Ar func . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_func_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Ar func , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_func_name_offsets +retrieves the name and offsets for the debugging information entry for +argument +.Ar func . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Ar func . +.Pp +Function +.Fn dwarf_funcname +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar func . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Func +descriptors returned in argument +.Ar funcs +by function +.Fn dwarf_get_funcs +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_funcs_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_func_name_offsets +and +.Fn dwarf_funcname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va func , +.Va funcs , +.Va name , +or +.Va nfuncs +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Ar dbg +did not contain information about static functions. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_funcs_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 b/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 new file mode 100644 index 0000000..b5f976e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 @@ -0,0 +1,211 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_globals.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 2, 2011 +.Os +.Dt DWARF_GET_GLOBALS 3 +.Sh NAME +.Nm dwarf_get_globals , +.Nm dwarf_global_cu_offset , +.Nm dwarf_global_die_offset , +.Nm dwarf_global_name_offsets , +.Nm dwarf_globname +.Nd retrieve information about global objects +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_globals +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Global **globals" +.Fa "Dwarf_Signed *nglobals" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_cu_offset +.Fa "Dwarf_Global global" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_die_offset +.Fa "Dwarf_Global global" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_global_name_offsets +.Fa "Dwarf_Global global" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_globname +.Fa "Dwarf_Global global" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about global symbols from the +lookup tables in the +.Dq ".debug_pubnames" +DWARF section. +Information about these global symbols is returned using opaque descriptors +of type +.Vt Dwarf_Global . +Applications need to use the functions described below to retrieve the +name and the offsets for these descriptors. +.Pp +Function +.Fn dwarf_get_globals +retrieves descriptors for all the global symbols associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar globals +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Global +descriptors. +The argument +.Ar nglobals +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_global_cu_offset +returns the section-relative offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Ar global . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_global_die_offset +retrieves the section-relative offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Ar global , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_global_name_offsets +retrieves the name and the offsets for the debugging information +entry for argument +.Ar global . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to a section-relative +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to a +section-relative offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in +the compilation unit associated with argument +.Ar global . +.Pp +Function +.Fn dwarf_globname +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar global . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Global +descriptors returned in argument +.Ar globals +by function +.Fn dwarf_get_globals +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_globals_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_globname +and +.Fn dwarf_global_name_offsets +is owned by the +.Lb libdwarf . +Portable code should use the +.Xr dwarf_dealloc 3 +function to indicate that the memory area may be freed. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va global , +.Va globals , +.Va name , +or +.Va nglobals +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_globals_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 b/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 new file mode 100644 index 0000000..50c3455 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 @@ -0,0 +1,156 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_loclist_entry.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd July 6, 2011 +.Os +.Dt DWARF_GET_LOCLIST_ENTRY 3 +.Sh NAME +.Nm dwarf_get_loclist_entry +.Nd retrieve DWARF location list entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_loclist_entry +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned offset" +.Fa "Dwarf_Addr *hipc" +.Fa "Dwarf_Addr *lopc" +.Fa "Dwarf_Ptr *data" +.Fa "Dwarf_Unsigned *entry_len" +.Fa "Dwarf_Unsigned *next_entry" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_loclist_entry +retrieves a location list entry from the DWARF section +.Dq ".debug_loc" . +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar offset +is an offset, relative to the +.Dq ".debug_loc" +section, to the start of the desired location list entry. +.Pp +Argument +.Ar hipc +should point to a location which will hold the offset, relative to the +base address of the location list entry, of the highest program +counter value for the entry. +.Pp +Argument +.Ar lowpc +should point to a location which will hold the offset, relative to the +base address of the location list entry, of the lowest program counter +value for the entry. +.Pp +Argument +.Ar data +should point to a location which will be set to a pointer to the location +list data. +.Pp +Argument +.Ar entry_len +should point to a location which will hold the length in bytes of the +location list data returned in argument +.Ar data . +.Pp +Argument +.Ar next_entry +should point to a location which will hold the offset of the next +location list entry. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_loclist_entry +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no location list at the specified offset +.Ar offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_loclist_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar hipc , +.Ar lopc , +.Ar data , +.Ar entry_len +or +.Ar next_entry +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no location list at the specified offset +.Ar offset . +.El +.Sh EXAMPLE +To iterate through all the location list entries in the +.Dq ".debug_loc" +section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Unsigned off, len, next; +Dwarf_Addr hipc, lopc; +Dwarf_Ptr data; +Dwarf_Error de; +int ret; + +off = 0; +while ((ret = dwarf_get_loclist_entry(dbg, off, &hipc, &lopc, &data, + &len, &next, &de)) == DW_DLV_OK) { + /* ... use loclist entry ... */ + off = next; +} +if (ret == DW_DLV_ERROR) + warnx("dwarf_get_loclist_entry failed: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_loclist 3 , +.Xr dwarf_loclist_n 3 , +.Xr dwarf_loclist_from_expr 3 , +.Xr dwarf_loclist_from_expr_a 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 b/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 new file mode 100644 index 0000000..71e4914 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 @@ -0,0 +1,192 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_macro_details.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd March 20, 2011 +.Os +.Dt DWARF_GET_MACRO_DETAILS 3 +.Sh NAME +.Nm dwarf_get_macro_details +.Nd retrieve macro information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_macro_details +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Unsigned max_count" +.Fa "Dwarf_Signed *entry_cnt" +.Fa "Dwarf_Macro_Details **details" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_macro_details +retrieves information about macros associated with a DWARF debug +context. +Information about macro entries are returned as an array of +descriptors of type +.Vt Dwarf_Macro_Details , +with each +.Vt Dwarf_Macro_Details +descriptor describing one macro information entry. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Ar offset +is an offset, relative to the +.Dq ".debug_macinfo" +section, to the start of the desired macro information. +Argument +.Ar max_count +specifies the maximum number of macro information entries +to be returned, or 0 if all entries are to be returned. +Argument +.Ar entry_cnt +should point to a location that will be set to the number +of entries actually returned. +Argument +.Ar details +should point to a location that will be set to a pointer to +an array of +.Vt Dwarf_Macro_Details +descriptors. +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +.Vt Dwarf_Macro_Details +descriptors are defined in the header file +.In libdwarf.h , +and consist of the following fields: +.Bl -tag -width ".Va dmd_fileindex" -compact +.It Va dmd_offset +The section-relative offset within the +.Dq ".debug_macinfo" +section of the macro information entry being described. +.It Va dmd_type +The type code of this macro information entry; one of the +.Dv DW_MACINFO_* +constants defined by the DWARF specification. +.It Va dmd_lineno +The line number associated with the macro information +entry, or 0 if there is no applicable line number. +.It Va dmd_fileindex +The source file index for the macro information entry. +This field is only meaningful when +.Va dmd_type +field is set to +.Dv DW_MACINFO_start_file . +.It Va dmd_macro +The contents of this field is a pointer to a NUL-terminated string +whose meaning depends on the value of the +.Va dmd_type +field: +.Bl -tag -width ".Dv DW_MACINFO_vendor_ext" -compact +.It Dv DW_MACINFO_define +The returned string contains the macro name and value. +.It Dv DW_MACINFO_undef +The string holds the macro name. +.It Dv DW_MACINFO_vendor_ext +The +.Va dmd_macro +field points to a vendor defined string. +.El +The field is NULL for other values of +.Va dmd_type . +.El +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Macro_Details +descriptors returned in argument +.Ar details +is owned by the +.Lb libdwarf . +The application should not attempt to directly free this pointer. +Portable code should instead use +.Fn dwarf_dealloc +with the allocation type +.Dv DW_DLA_STRING +to indicate that the memory may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_get_macro_details +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no more macro information at the specified offset +.Ar offset . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_macro_details +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar entry_cnt +or +.Ar details +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no more macro information at the specified offset +.Ar offset . +.El +.Sh EXAMPLE +To loop through all the macro information entries associated with +a DWARF debug context: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Unsigned offset; +Dwarf_Signed cnt; +Dwarf_Macro_Details *md; +Dwarf_Error de; + +offset = 0; +while (dwarf_get_macro_details(dbg, offset, 0, + &cnt, &md, &de) == DW_DLV_OK) { + for (i = 0; i < cnt; i++) { + /* Access fields of md[i] ... */ + } + offset = md[cnt - 1].dmd_offset + 1; +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_find_macro_value_start 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 new file mode 100644 index 0000000..23ad783 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 @@ -0,0 +1,243 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_pubtypes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 4, 2011 +.Os +.Dt DWARF_GET_PUBTYPES 3 +.Sh NAME +.Nm dwarf_get_pubtypes , +.Nm dwarf_pubtype_cu_offset , +.Nm dwarf_pubtype_die_offset , +.Nm dwarf_pubtype_name_offsets , +.Nm dwarf_pubtypename +.Nd retrieve information about user-defined types +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_pubtypes +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type **types" +.Fa "Dwarf_Signed *ntypes" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_cu_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_die_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtype_name_offsets +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_pubtypename +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about file-scope, user-defined +types recorded in lookup tables in the +.Dq ".debug_pubtypes" +DWARF section. +Information about these types is returned using opaque descriptors +of type +.Vt Dwarf_Type . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_pubtypes +retrieves descriptors for all the user-defined types associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar types +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Type +descriptors. +The argument +.Ar ntypes +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_pubtype_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Ar type . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_pubtype_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Ar type , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_pubtype_name_offsets +retrieves the name and offsets for the debugging information entry for +argument +.Ar type . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Ar type . +.Pp +Function +.Fn dwarf_pubtypename +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar type . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Type +descriptors returned in argument +.Ar types +by function +.Fn dwarf_get_pubtypes +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_types_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_pubtype_name_offsets +and +.Fn dwarf_pubtypename +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh EXAMPLES +To retrieve the list of file scope user-defined types and print +their names, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Signed ntypes; +Dwarf_Type *types; +Dwarf_Error err; +int n, result; +char *typename; + +/* Initialize dbg etc. */; +result = dwarf_get_pubtypes(dbg, &types, &ntypes, &err); +if (result != DW_DLV_OK) /* Handle the error. */ + ; + +/* Iterate over the returned array of descriptors. */ +for (n = 0; n < ntypes; n++) { + result = dwarf_pubtypename(types[n], &typename, &err); + if (result != DW_DLV_OK) /* Handle the error. */ + ; + printf("%s\en", typename); +} + +/* Deallocate the returned array. */ +dwarf_types_dealloc(dbg, types, ntypes); +.Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va type , +.Va types , +.Va name , +or +.Va ntypes +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Ar dbg +did not contain information about user-defined types. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_pubtypes_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 b/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 new file mode 100644 index 0000000..37847a1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 @@ -0,0 +1,258 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_ranges.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_GET_RANGES 3 +.Sh NAME +.Nm dwarf_get_ranges +.Nd retrieve non-contiguous address ranges +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_ranges +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Ranges **ranges" +.Fa "Dwarf_Signed *cnt" +.Fa "Dwarf_Unsigned *byte_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_get_ranges_a +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die die" +.Fa "Dwarf_Ranges **ranges" +.Fa "Dwarf_Signed *cnt" +.Fa "Dwarf_Unsigned *byte_cnt" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_ranges +retrieves information about the non-contiguous address ranges associated +with a DWARF debugging information entry. +Information about address ranges is returned as an array of +descriptors of type +.Vt Dwarf_Ranges , +with each +.Vt Dwarf_Ranges +descriptor describing one address range entry. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar offset +is an offset, relative to the +.Dq ".debug_ranges" +section, to the start of the desired list of address ranges. +The offset of an address ranges list is indicated by the +.Dv DW_AT_ranges +attribute of a debugging information entry. +.Pp +Argument +.Ar die +(function +.Fn dwarf_get_ranges_a +only) is ignored in this implementation; see the section +.Sx "Compatibility Notes" +below. +.Pp +Argument +.Ar ranges +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Ranges +descriptors. +.Pp +Argument +.Ar cnt +should point to a location that will be set to the number of entries +returned. +If argument +.Ar byte_cnt +is not NULL, it will be set to the number of bytes occupied by the +returned entries in the +.Dq ".debug_ranges" +section. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +.Vt Dwarf_Ranges +descriptors are defined in the header file +.In libdwarf.h , +and consists of the following fields: +.Bl -tag -width ".Va dwr_addr1" +.It Va dwr_addr1 +The first address offset, whose meaning depends on the type of the +entry. +.It Va dwr_addr2 +The second address offset, whose meaning depends on the type of the +entry. +.It Va dwr_type +The type of this address range entry: +.Bl -tag -width ".Dv DW_RANGES_ENTRY" -compact +.It Dv DW_RANGES_ENTRY +A range list entry. +For this type of entry, the fields +.Va dwr_addr1 +and +.Va dwr_addr2 +hold the beginning and ending offsets of the address range, respectively. +.It Dv DW_RANGES_ADDRESS_SELECTION +A base address selection entry. +For this type of entry, the field +.Va dwr_addr1 +is the value of the largest representable address offset, and +.Va dwr_addr2 +is a base address for the begining and ending address offsets of +subsequent address range entries in the list. +.It Dv DW_RANGES_END +An end of list mark. +Both +.Va dwr_addr1 +and +.Va dwr_addr2 +are set to 0. +.El +.El +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Ranges +descriptors returned in argument +.Ar ranges +is owned by the +.Lb libdwarf . +The application should not attempt to directly free this pointer. +Portable code should instead use +.Fn dwarf_ranges_dealloc +to indicate that the memory may be freed. +.Sh COMPATIBILITY +Function +.Fn dwarf_get_ranges_a +is identical to +.Fn dwarf_get_ranges , +except that it requires one additional argument +.Ar die +denoting the debugging information entry associated with +the address range list. +In this implementation of the +.Lb libdwarf , +the argument +.Ar die +is ignored, and function +.Fn dwarf_get_ranges_a +is only provided for compatibility with other implementations of the +DWARF(3) API. +.Sh RETURN VALUES +These functions +return +.Dv DW_DLV_OK +when they succeed. +They return +.Dv DW_DLV_NO_ENTRY +if there is no address range list at the specified offset +.Ar offset . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These function can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ranges +or +.Ar cnt +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no address range list at the specified offset +.Ar offset . +.El +.Sh EXAMPLE +To retrieve the address range list associated with a debugging +information entry, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Die die; +Dwarf_Error de; +Dwarf_Addr base; +Dwarf_Attribute *attr_list; +Dwarf_Ranges *ranges; +Dwarf_Signed cnt; +Dwarf_Unsigned off, attr_count, bytecnt; +int i, j; + +if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_attrlist failed: %s", + dwarf_errmsg(de)); + +for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { + if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { + warnx("dwarf_whatattr failed: %s", + dwarf_errmsg(de)); + continue; + } + if (attr != DW_AT_ranges) + continue; + if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + if (dwarf_get_ranges(dbg, (Dwarf_Off) off, &ranges, &cnt, + &bytecnt, &de) != DW_DLV_OK) + continue; + for (j = 0; j < cnt; j++) { + if (ranges[j].dwr_type == DW_RANGES_END) + break; + else if (ranges[j].dwr_type == + DW_RANGES_ADDRESS_SELECTION) + base = ranges[j].dwr_addr2; + else { + /* + * DW_RANGES_ENTRY entry. + * .. Use dwr_addr1 and dwr_addr2 .. + */ + } + } +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_ranges_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 new file mode 100644 index 0000000..96166cf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 @@ -0,0 +1,228 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_relocation_info.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd September 3, 2011 +.Os +.Dt DWARF_GET_RELOCATION_INFO 3 +.Sh NAME +.Nm dwarf_get_relocation_info +.Nd retrieve generated relocation arrays +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_relocation_info +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Signed *elf_section_index" +.Fa "Dwarf_Signed *elf_section_link" +.Fa "Dwarf_Unsigned *reloc_entry_count" +.Fa "Dwarf_Relocation_Data *reloc_buf" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_get_relocation_info +is used to retrieve the relocation arrays generated by a prior call to +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Each call to this function retrieves the next available relocation +array. +Application code should call this function repeatly to retrieve all +the relocation arrays. +The total number of generated relocation arrays retrievable +by this function may be obtained by calling function +.Xr dwarf_get_relocation_info_count 3 . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 in sequence. +or +.Xr dwarf_producer_init_b 3 . +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the DWARF producer instance. +.Pp +Argument +.Ar elf_section_index +should point to a location which will be set to the ELF section index +of the relocation section to which the retrieved relocation array +belongs. +.Pp +Argument +.Ar elf_section_link +should point to a location which will be set to the section index of +the ELF section to which the retrieved relocation array applies. +.Pp +Argument +.Ar reloc_entry_count +should point to a location which will be set to the total number of +relocation entries contained in the relocation array. +.Pp +Argument +.Ar reloc_buf +should point to a location which will be set to a pointer to the +retrieved array of relocation entries. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +The retrieved relocation entries are described using structure +.Vt Dwarf_Relocation_Data_s , +defined in the header file +.In libdwarf.h : +.Bd -literal -offset indent +typedef struct Dwarf_Relocation_Data_s { + unsigned char drd_type; + unsigned char drd_length; + Dwarf_Unsigned drd_offset; + Dwarf_Unsigned drd_symbol_index; +} *Dwarf_Relocation_Data; +.Ed +.Pp +Struct +.Vt Dwarf_Relocation_Data_s +consists of following fields: +.Bl -tag -width ".Va drd_symbol_index" -compact -offset indent +.It Va drd_type +The type code of the relocation entry. +The +.Vt Dwarf_Rel_Type +enumeration defined in the header file +.In libdwarf.h +specifies legal values for this field. +.It Va drd_length +The size in bytes of the field to be relocated. +.It Va drd_offset +The section-relative offset of the field to be relocated. +.It Va drd_symbol_index +The symbol index associated with the relocation entry. +.El +.Ss Memory Management +The memory area used for the relocation arrays is managed by the +.Lb libdwarf . +The function +.Fn dwarf_producer_finish +may be used to release it, along with other resources associated +with the producer instance. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_relocation_info +returns +.Dv DW_DLV_OK . +It returns +.Dv DW_DLV_NO_ENTRY +if there were no more relocation arrays to retrieve, or if the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +In case of an error, function +.Fn dwarf_get_relocation_info +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_relocation_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar elf_section_index , +.Ar elf_section_link , +.Ar reloc_entry_count +or +.Ar reloc_buf +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF relocation arrays to retrieve. +.It Bq Er DW_DLE_NO_ENTRY +The flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.It Bq Er DW_DLE_NO_ENTRY +Function +.Xr dwarf_transform_to_disk_form 3 +was not called prior to calling function +.Fn dwarf_get_relocation_info . +.El +.Sh EXAMPLES +To generate relocation entries and retrieve them, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Relocation_Data buf; +Dwarf_Signed count, index, link; +Dwarf_Unsigned reloc_cnt, entry_cnt; +Dwarf_Error de; +int version, i, j; + +/* + * Assume that dbg refers to a DWARF producer instance created + * created with DW_DLC_SYMBOLIC_RELOCATIONS flag set and that + * application code has added DWARF debugging information + * to the producer instance. + */ +if ((count = dwarf_transform_to_disk_form(dbg, &de)) == + DW_DLV_NOCOUNT) { + warnx("dwarf_transform_to_disk_form failed: %s", + dwarf_errmsg(-1)); + return; +} + +/* ... process generated section byte streams ... */ +if (dwarf_get_relocation_info_count(dbg, &reloc_cnt, &version, &de) != + DW_DLV_OK) { + warnx("dwarf_get_relocation_info_count failed: %s", + dwarf_errmsg(-1)); + return; +} + +for (i = 0; (Dwarf_Unsigned) i < reloc_cnt; i++) { + if (dwarf_get_relocation_info(dbg, &index, &link, &entry_cnt, + &buf, &de) != DW_DLV_OK) { + warnx("dwarf_get_relocation_info failed: %s", + dwarf_errmsg(-1)); + continue; + } + for (j = 0; (Dwarf_Unsigned) j < entry_cnt; j++) { + /* ...use each reloc data in buf[j]... */ + } +} + +dwarf_producer_finish(dbg, &de); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info_count 3 , +.Xr dwarf_reset_section_bytes 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 new file mode 100644 index 0000000..38e1a00 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_relocation_info_count.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd September 3, 2011 +.Os +.Dt DWARF_GET_RELOCATION_INFO_COUNT 3 +.Sh NAME +.Nm dwarf_get_relocation_info_count +.Nd return the number of relocation arrays +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_relocation_info_count +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned *reloc_cnt" +.Fa "int *drd_buffer_version" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_relocation_info_count +retrieves the total number of relocation arrays generated by a prior +call to +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag should have been set on the producer instance. +.Pp +Argument +.Ar reloc_cnt +should point to a location which will be set to the total number of +relocation arrays generated. +.Pp +Argument +.Ar drd_buffer_version +should point to a location which will be set to the version number +of the relocation structures returned (see the symbol +.Dv DWARF_DRD_BUFFER_VERSION , +defined in the header file +.In libdwarf.h ) . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_relocation_info_count +returns +.Dv DW_DLV_OK . +It returns +.Dv DW_DLV_NO_ENTRY +if the +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag is not set on the producer instance. +In case of an error, function +.Fn dwarf_get_relocation_info_count +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_relocation_info_count +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar reloc_cnt +or +.Ar drd_buffer_version +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +flag was not set. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 new file mode 100644 index 0000000..1b0ac9e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 @@ -0,0 +1,157 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_section_bytes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd August 26, 2011 +.Os +.Dt DWARF_GET_SECTION_BYTES 3 +.Sh NAME +.Nm dwarf_get_section_bytes +.Nd retrieve ELF section byte streams +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Ptr +.Fo dwarf_get_section_bytes +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Signed dwarf_section" +.Fa "Dwarf_Signed *elf_section_index" +.Fa "Dwarf_Unsigned *length" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_section_bytes +returns the ELF section byte streams generated by a prior call +to function +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Each call to function +.Fn dwarf_get_section_bytes +will return the byte stream for one ELF section. +The first call to this function will always return the first ELF +section, and the subsequent calls will return the rest of sections +in the order when they were generated, until the last one. +The total number of sections generated is returned by the function +.Xr dwarf_transform_to_disk_form 3 . +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using the +functions +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar dwarf_section +is currently ignored. +.Pp +Argument +.Ar elf_section_index +should point to a location which will be set to the section index value +of the returned ELF section. +.Pp +Argument +.Ar length +should point to a location which will hold the length in bytes of the +returned ELF section. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory areas used for the returned ELF section byte streams should +be freed using the function +.Fn dwarf_producer_finish . +.Sh RETURN VALUES +On success, function +.Fn dwarf_get_section_bytes +returns a pointer to a ELF section byte stream. +In case of an error, function +.Fn dwarf_get_section_bytes +will return NULL and set the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_section_bytes +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar elf_section_index , +or +.Ar length +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF sections to retrieve, or the function was +called before a call to +.Xr dwarf_transform_to_disk_form 3 . +.El +.Sh EXAMPLES +To generate and retrieve ELF section byte streams, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Signed count, i, sec_index; +Dwarf_Unsigned len; +Dwarf_Ptr bytes; +Dwarf_Error de; + +/* ... Assume that `dbg' refers to a DWARF producer instance, + * and that application code has added DWARF debugging + * information to the producer instance. ... + */ +if ((count = dwarf_transform_to_disk_form(dbg, &de)) == + DW_DLV_NOCOUNT) { + warnx("dwarf_transform_to_disk_form failed: %s", + dwarf_errmsg(-1)); + return; +} + +/* Retrieve section data. */ +for (i = 0; i < count; i++) { + bytes = dwarf_get_section_bytes(dbg, i, &sec_index, &len, + &de); + if (bytes == NULL) { + warnx("dwarf_get_section_bytes failed: %s", + dwarf_errmsg(-1)); + continue; + } + /* ... use the returned byte stream ... */ +} + +/* Release resources. */ +dwarf_producer_finish(dbg, &de); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_reset_section_bytes 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_str.3 b/contrib/elftoolchain/libdwarf/dwarf_get_str.3 new file mode 100644 index 0000000..5917c97 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_str.3 @@ -0,0 +1,149 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_str.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 3, 2011 +.Os +.Dt DWARF_GET_STR 3 +.Sh NAME +.Nm dwarf_get_str +.Nd retrieve a string from the DWARF string section +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_str +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "char **string" +.Fa "Dwarf_Signed *len" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_str +retrieves a NUL-terminated string from the DWARF string section +.Dq ".debug_str" . +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar offset +should be an offset, relative to the +.Dq ".debug_str" +section, specifying the start of the desired string. +.Pp +Argument +.Ar string +should point to a location which will hold a returned +pointer to a NUL-terminated string. +.Pp +Argument +.Ar len +should point to a location which will hold the length +of the returned string. +The returned length does not include the space needed for +the NUL-terminator. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +Function +.Fn dwarf_get_str +returns +.Dv DW_DLV_OK +when it succeeds. +It returns +.Dv DW_DLV_NO_ENTRY +if there is no +.Dq ".debug_str" +section associated with the specified debugging context, +or if the provided offset +.Ar offset +is at the very end of +.Dq ".debug_str" +section. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_get_str +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar string +or +.Ar len +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar offset +was out of range. +.It Bq Er DW_DLE_NO_ENTRY +The debugging context +.Ar dbg +did not contain a +.Dq ".debug_str" +string section. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar offset +was at the very end of the +.Dq ".debug_str" +section. +.El +.Sh EXAMPLE +To retrieve all the strings in the DWARF string section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Off offset; +Dwarf_Signed len; +Dwarf_Error de; +char *str; +int ret + +offset = 0; +while ((ret = dwarf_get_str(dbg, offset, &str, &len, &de)) == + DW_DLV_OK) { + /* .. Use the retrieved string. .. */ + offset += len + 1; /* Account for the terminating NUL. */ +} + +if (ret == DW_DLV_ERROR) + warnx("dwarf_get_str: %s", dwarf_errmsg(de)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_types.3 b/contrib/elftoolchain/libdwarf/dwarf_get_types.3 new file mode 100644 index 0000000..59e5868 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_types.3 @@ -0,0 +1,232 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_types.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 10, 2011 +.Os +.Dt DWARF_GET_TYPES 3 +.Sh NAME +.Nm dwarf_get_types , +.Nm dwarf_type_cu_offset , +.Nm dwarf_type_die_offset , +.Nm dwarf_type_name_offsets , +.Nm dwarf_typename +.Nd retrieve information about user-defined types +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_types +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Type **types" +.Fa "Dwarf_Signed *ntypes" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_cu_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_die_offset +.Fa "Dwarf_Type type" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_type_name_offsets +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_typename +.Fa "Dwarf_Type type" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These APIs retrieve information about user-defined types from the +SGI-specific +.Dq ".debug_typenames" +section. +.Pp +Standards-conformant applications should use the functions +.Xr dwarf_get_pubtypes 3 , +.Xr dwarf_pubtype_cu_offset 3 , +.Xr dwarf_pubtype_die_offset 3 , +.Xr dwarf_pubtype_name_offsets 3 +and +.Xr dwarf_pubtypename 3 , +which operate on the equivalent +.Dq ".debug_pubtypes" +section defined by the DWARF3 standard. +.Pp +Information about user-defined types is returned using opaque descriptors +of type +.Vt Dwarf_Type . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_types +retrieves descriptors for all user-defined types associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar types +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Type +descriptors. +The argument +.Ar ntypes +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_type_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Ar type . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_type_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Ar type , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_type_name_offsets +retrieves the name and offsets for the debugging information +entry for argument +.Ar type . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to a offset, relative to +the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Ar type . +.Pp +Function +.Fn dwarf_typename +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar type . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Type +descriptors returned in argument +.Ar types +by function +.Fn dwarf_get_types +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_types_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_type_name_offsets +and +.Fn dwarf_typename +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va type , +.Va types , +.Va name , +or +.Va ntypes +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Ar dbg +did not contain information about user-defined types. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_get_pubtypes 3 , +.Xr dwarf_pubtype_cu_offset 3 , +.Xr dwarf_pubtype_die_offset 3 , +.Xr dwarf_pubtype_name_offsets 3 , +.Xr dwarf_pubtypename 3 , +.Xr dwarf_types_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 b/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 new file mode 100644 index 0000000..d2c3ebd --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 @@ -0,0 +1,210 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_vars.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 2, 2011 +.Os +.Dt DWARF_GET_VARS 3 +.Sh NAME +.Nm dwarf_get_vars , +.Nm dwarf_var_cu_offset , +.Nm dwarf_var_die_offset , +.Nm dwarf_var_name_offsets , +.Nm dwarf_varname +.Nd retrieve information about static variables +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_vars +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Var **vars" +.Fa "Dwarf_Signed *nvars" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_cu_offset +.Fa "Dwarf_Var var" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_die_offset +.Fa "Dwarf_Var var" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_var_name_offsets +.Fa "Dwarf_Var var" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_varname +.Fa "Dwarf_Var var" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about the file scope static +variables associated with a DWARF debug context. +Information about these static variables is returned using opaque +descriptors of type +.Vt Dwarf_Var . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_vars +retrieves descriptors for all the static variables associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar vars +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Var +descriptors. +The argument +.Ar nvars +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_var_cu_offset +returns the section-relative offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that +contains the debugging information entry associated with the argument +.Ar var . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_var_die_offset +retrieves the section-relative offset, relative to the +.Dq ".debug_info" +section, of the debugging information +entry associated with the argument +.Ar var , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_var_name_offsets +retrieves both the name and the associated offsets for the debugging +information entry for argument +.Ar var . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to a section-relative +offset, relative to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to a +section-relative offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in +the compilation unit associated with argument +.Ar var . +.Pp +Function +.Fn dwarf_varname +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar var . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Var +descriptors returned in argument +.Ar vars +by function +.Fn dwarf_get_vars +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_vars_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_var_name_offsets +and +.Fn dwarf_varname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va var , +.Va vars , +.Va name , +or +.Va nvars +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_vars_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 b/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 new file mode 100644 index 0000000..470973e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 @@ -0,0 +1,215 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_get_weaks.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" +.Dd April 10, 2011 +.Os +.Dt DWARF_GET_WEAKS 3 +.Sh NAME +.Nm dwarf_get_weaks , +.Nm dwarf_weak_cu_offset , +.Nm dwarf_weak_die_offset , +.Nm dwarf_weak_name_offsets , +.Nm dwarf_weakname +.Nd retrieve information about weak symbols +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_weaks +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Weak **weaks" +.Fa "Dwarf_Signed *nweaks" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_cu_offset +.Fa "Dwarf_Weak weak" +.Fa "Dwarf_Off *cu_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_die_offset +.Fa "Dwarf_Weak weak" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weak_name_offsets +.Fa "Dwarf_Weak weak" +.Fa "char **name" +.Fa "Dwarf_Off *die_offset" +.Fa "Dwarf_Off *cu_die_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_weakname +.Fa "Dwarf_Weak weak" +.Fa "char **name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve information about weak symbols from the +lookup tables in the (SGI-specific) +.Dq ".debug_weaknames" +section. +Information about weak symbols is returned using opaque descriptors +of type +.Vt Dwarf_Weak . +Applications need to use the functions described below to retrieve +the name and offset information contained in these descriptors. +.Pp +Function +.Fn dwarf_get_weaks +retrieves descriptors for all the weak symbols associated with the +DWARF debug context specified by argument +.Ar dbg . +The argument +.Ar weaks +should point to a location that will be set to a pointer to an array +of +.Vt Dwarf_Weak +descriptors. +The argument +.Ar nweaks +should point to a location that will be set to the number of +descriptors returned. +.Pp +Function +.Fn dwarf_weak_cu_offset +returns the offset, relative to the +.Dq ".debug_info" +section, of the compilation unit that contains the debugging +information entry associated with the argument +.Ar weak . +Argument +.Ar cu_offset +should point to a location that will hold the returned offset. +.Pp +Function +.Fn dwarf_weak_die_offset +retrieves the offset, relative to the +.Dq ".debug_info" +section, of the debugging information entry associated with the +argument +.Ar weak , +and stores it into the location pointed to by the argument +.Ar die_offset . +.Pp +Function +.Fn dwarf_weak_name_offsets +retrieves the name and offsets for the debugging information +entry for argument +.Ar weak . +Argument +.Ar name +should point to a location which will be set to a pointer to a +NUL-terminated string containing the name of the associated debugging +information entry. +Argument +.Ar die_offset +should point to a location which will be set to the offset, relative +to the +.Dq ".debug_info" +section, of the associated debugging information entry. +Argument +.Ar cu_die_offset +should point to a location which will be set to the +offset, relative to the +.Dq ".debug_info" +section, of the first debugging information entry in the compilation +unit associated with argument +.Ar weak . +.Pp +Function +.Fn dwarf_weakname +sets the location pointed to by argument +.Ar name +to a pointer to a NUL-terminated string holding the name of the +debugging information entry associated with the argument +.Ar weak . +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Weak +descriptors returned in argument +.Ar weaks +by function +.Fn dwarf_get_weaks +is owned by the +.Lb libdwarf . +Application code should not attempt to directly free this pointer. +Portable code should instead use the function +.Xr dwarf_weaks_dealloc 3 +to indicate that the memory area may be freed. +.Pp +The memory area used for the string returned in the +.Ar name +argument to functions +.Fn dwarf_weak_name_offsets +and +.Fn dwarf_weakname +is owned by the +.Lb libdwarf . +Portable code should indicate that the memory area can +be freed using the +.Xr dwarf_dealloc 3 +function. +.Ss Error Returns +If argument +.Ar err +is not NULL, these functions will use it to store error information, +in case of an error. +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va cu_die_offset , +.Va cu_offset , +.Va dbg , +.Va die_offset , +.Va weak , +.Va weaks , +.Va name , +or +.Va nweaks +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The DWARF debugging context referenced by argument +.Ar dbg +did not contain information about weak symbols. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_weaks_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 new file mode 100644 index 0000000..5b4699b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 @@ -0,0 +1,91 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_hasattr.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd April 17, 2010 +.Os +.Dt DWARF_HASATTR 3 +.Sh NAME +.Nm dwarf_hasattr +.Nd check for the presence of an attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_hasattr +.Fa "Dwarf_Die die" +.Fa "Dwarf_Half attr" +.Fa "Dwarf_Bool *ret_bool" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_hasattr +tests whether the debugging information entry referenced in argument +.Ar die +contains the attribute named by argument +.Ar attr . +Legal values for argument +.Ar attr +are those denoted by the +.Dv DW_AT_* +constants in the DWARF specification. +.Pp +If the named attribute is present in the debugging information entry, +function +.Fn dwarf_hasattr +returns a non-zero value in the location pointed to by argument +.Ar ret_bool . +If the named attribute is not present, a zero is written instead. +.Pp +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_hasattr +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_hasattr +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of argument +.Va die +or +.Va ret_bool +was NULL. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_whatattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasform.3 b/contrib/elftoolchain/libdwarf/dwarf_hasform.3 new file mode 100644 index 0000000..2cb6fc5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_hasform.3 @@ -0,0 +1,127 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_hasform.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd May 22, 2010 +.Os +.Dt DWARF_HASFORM 3 +.Sh NAME +.Nm dwarf_hasform , +.Nm dwarf_whatform , +.Nm dwarf_whatform_direct +.Nd query attribute forms +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_hasform +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half form" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_whatform +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retform" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_whatform_direct +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retform" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_hasform +indicates whether the DWARF attribute denoted by argument +.Ar attr +has the attribute form specified by argument +.Ar form . +If the attribute has the specified form, then +argument +.Ar ret +is set to a non-zero value, otherwise it is set to zero. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in +case of an error. +.Pp +Function +.Fn dwarf_whatform +sets the location specified by argument +.Ar retform +to the attribute form code for the DWARF attribute referenced +by argument +.Ar attr . +If the attribute referenced by argument +.Ar attr +has an indirect form attribute, this function will return the final +form for the attribute. +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in +case of an error. +.Pp +Function +.Fn dwarf_whatform_direct +sets the location specified by argument +.Ar retform +to the attribute form code for the DWARF attribute referenced +by argument +.Ar attr . +If the form is an indirect form, the function sets the location +specified by argument +.Ar retform +to +.Dv DW_FORM_indirect . +If argument +.Ar err +is non-NULL, it will be used to return an error descriptor in +case of an error. +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK +on success. +In case of an error, these functions return +.Dv DW_DLV_ERR +and set argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Any of the arguments +.Ar attr , +.Ar ret , +or +.Ar retform +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_highpc.3 b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 new file mode 100644 index 0000000..998a3b6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_highpc.3 @@ -0,0 +1,162 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_highpc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" +.Dd April 7, 2010 +.Os +.Dt DWARF_HIGHPC 3 +.Sh NAME +.Nm dwarf_arrayorder , +.Nm dwarf_bitoffset , +.Nm dwarf_bitsize , +.Nm dwarf_bytesize , +.Nm dwarf_highpc , +.Nm dwarf_lowpc , +.Nm dwarf_srclang +.Nd retrieve the value of a DWARF attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_arrayorder +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_order" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bitoffset +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bitsize +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_bytesize +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_size" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_highpc +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_highpc" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lowpc +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_lowpc" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_srclang +.Fa "Dwarf_Die die" +.Fa "Dwarf_Unsigned *ret_lang" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These convenience functions are used to retrieve DWARF attribute +values associated with a Debugging Information Entry (DIE) descriptor +denoted by argument +.Ar die . +These functions store the value of the requested attribute into the +location pointed to by their second argument, provided that the requested +attribute exists in the debugging information entry. +.Pp +The list of functions and the DWARF attribute that they retrieve are: +.Pp +.Bl -tag -width ".Fn dwarf_arrayorder" -compact +.It Fn dwarf_arrayorder +Retrieve the +.Dv DW_AT_ordering +attribute value. +.It Fn dwarf_bitoffset +Retrieve the +.Dv DW_AT_bit_offset +attribute value. +.It Fn dwarf_bitsize +Retrieve the +.Dv DW_AT_bit_size +attribute value. +.It Fn dwarf_bytesize +Retrieve the +.Dv DW_AT_byte_size +attribute value. +.It Fn dwarf_highpc +Retrieve the +.Dv DW_AT_high_pc +attribute value. +.It Fn dwarf_lowpc +Retrieve the +.Dv DW_AT_low_pc +attribute value. +.It Fn dwarf_srclang +Retrieve the +.Dv DW_AT_language +attribute value. +.El +.Sh RETURN VALUES +These functions return +.Dv DW_DLV_OK on success. +.Pp +If the debugging information entry descriptor denoted by argument +.Ar die +does not contain the requested attribute, these functions return +.Dv DW_DLV_NO_ENTRY +and set argument +.Ar err . +For other errors, they return +.Dv DW_DLV_ERROR +and set argument +.Ar err . +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Ar die , +.Ar ret_highpc , +.Ar ret_lowpc , +.Ar ret_size , +.Ar ret_lang +or +.Ar ret_order +were NULL. +.It Bq Er DW_DLE_NO_ENTRY +Argument +.Ar die +had no requested attribute. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_attrlist 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_init.3 b/contrib/elftoolchain/libdwarf/dwarf_init.3 new file mode 100644 index 0000000..36c6449 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_init.3 @@ -0,0 +1,178 @@ +.\" Copyright (c) 2009 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_init.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_INIT 3 +.Sh NAME +.Nm dwarf_init , +.Nm dwarf_elf_init +.Nd allocate a DWARF debug descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_init +.Fa "int fd" +.Fa "int mode" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft in +.Fo dwarf_elf_init +.Fa "Elf *elf" +.Fa "int mode" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions allocate and return a +.Vt Dwarf_Debug +instance for the object denoted by argument +.Ar fd +or +.Ar elf . +This instance would be used for subsequent access to debugging information in the object by other functions in the DWARF(3) library. +.Pp +For function +.Fn dwarf_init , +argument +.Ar fd +denotes an open file descriptor referencing a compilation object. +Function +.Fn dwarf_init +implicitly allocates an +.Vt Elf +descriptor for argument +.Ar fd . +.Pp +For function +.Fn dwarf_elf_init , +argument +.Ar elf +denotes a descriptor returned by +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +.Pp +Argument +.Ar mode +specifies the access mode desired. +It should be at least as permissive as the mode with which +the file descriptor +.Ar fd +or the ELF descriptor +.Ar elf +was created with. +Legal values for argument +.Ar mode +are: +.Pp +.Bl -tag -width "DW_DLC_WRITE" -compact +.It DW_DLC_RDWR +Permit reading and writing of DWARF information. +.It DW_DLC_READ +Operate in read-only mode. +.It DW_DLC_WRITE +Permit writing of DWARF information. +.El +.Pp +Argument +.Ar errhand +denotes a function to be called in case of an error. +If this argument is +.Dv NULL +then a default error handling scheme is used. +See +.Xr dwarf 3 +for a description of the error handling scheme used by the +DWARF(3) library. +.Pp +Argument +.Ar errarg +is passed to the error handler function denoted by argument +.Ar errhand +when it is invoked. +.Pp +Argument +.Ar ret +points to the memory location that will hold a +.Vt Dwarf_Debug +reference on a successful call these functions. +.Pp +Argument +.Ar err +references a memory location that would hold a +.Vt Dwarf_Error +descriptor in case of an error. +.Ss Memory Management +The +.Vt Dwarf_Debug +instance returned by these functions should be freed using +.Fn dwarf_finish . +.Sh RETURN VALUES +These functions return the following values: +.Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" +.It Bq Er DW_DLV_OK +This return value indicates a successful return. +.It Bq Er DW_DLV_ERROR +The operation failed. +.It Bq Er DW_DLV_NO_ENTRY +The object specified by arguments +.Ar "fd" +or +.Ar "elf" +did not contain debug information. +.El +.Sh IMPLEMENTATION NOTES +The current implementation does not support access modes +.Dv DW_DLC_RDWR +and +.Dv DW_DLC_WRITE . +.Sh EXAMPLES +To initialize a +.Vt Dwarf_Debug +instance from a open file descriptor referencing an ELF object, and +with the default error handler, use: +.Bd -literal -offset indent +Dwarf_Error err; +Dwarf_Debug dbg; + +if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &err) != + DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(err)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_finish 3 , +.Xr dwarf_get_elf 3 , +.Xr elf_begin 3 , +.Xr elf_memory 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_init.c b/contrib/elftoolchain/libdwarf/dwarf_init.c new file mode 100644 index 0000000..16ec53c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_init.c @@ -0,0 +1,163 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_init.c 2073 2011-10-27 03:30:47Z jkoshy $"); + +int +dwarf_elf_init(Elf *elf, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg, + Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int ret; + + if (elf == NULL || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (mode != DW_DLC_READ) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) != + DW_DLE_NONE) { + _dwarf_elf_deinit(dbg); + free(dbg); + if (ret == DW_DLE_DEBUG_INFO_NULL) + return (DW_DLV_NO_ENTRY); + else + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} + +int +dwarf_get_elf(Dwarf_Debug dbg, Elf **elf, Dwarf_Error *error) +{ + Dwarf_Elf_Object *e; + + if (dbg == NULL || elf == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + e = dbg->dbg_iface->object; + *elf = e->eo_elf; + + return (DW_DLV_OK); +} + +int +dwarf_init(int fd, int mode, Dwarf_Handler errhand, Dwarf_Ptr errarg, + Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Elf *elf; + int ret; + + if (fd < 0 || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (mode != DW_DLC_READ) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (elf_version(EV_CURRENT) == EV_NONE) { + DWARF_SET_ELF_ERROR(NULL, error); + return (DW_DLV_ERROR); + } + + if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + DWARF_SET_ELF_ERROR(NULL, error); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, mode, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + if (_dwarf_elf_init(dbg, elf, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + if ((ret = _dwarf_init(dbg, 0, errhand, errarg, error)) != + DW_DLE_NONE) { + _dwarf_elf_deinit(dbg); + free(dbg); + if (ret == DW_DLE_DEBUG_INFO_NULL) + return (DW_DLV_NO_ENTRY); + else + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} + +int +dwarf_object_init(Dwarf_Obj_Access_Interface *iface, Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Debug *ret_dbg, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + if (iface == NULL || ret_dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_READ, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + + dbg->dbg_iface = iface; + + if (_dwarf_init(dbg, 0, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_ERROR); + } + + *ret_dbg = dbg; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_lineno.3 b/contrib/elftoolchain/libdwarf/dwarf_lineno.3 new file mode 100644 index 0000000..0a0362f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lineno.3 @@ -0,0 +1,202 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_lineno.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd February 5, 2011 +.Os +.Dt DWARF_LINENO 3 +.Sh NAME +.Nm dwarf_lineaddr , +.Nm dwarf_linebeginstatement , +.Nm dwarf_lineblock , +.Nm dwarf_lineendsequence , +.Nm dwarf_lineno , +.Nm dwarf_lineoff , +.Nm dwarf_linesrc , +.Nm dwarf_line_srcfileno +.Nd retrieve information associated with a DWARF line descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_lineaddr +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Addr *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_linebeginstatement +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineblock +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineendsequence +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Bool *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineno +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_lineoff +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Signed *ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_linesrc +.Fa "Dwarf_Line ln" +.Fa "char **ret" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_line_srcfileno +.Fa "Dwarf_Line ln" +.Fa "Dwarf_Unsigned *ret" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions retrieve specific line information associated with +the line descriptor specified by argument +.Ar ln , +and stores it in the location pointed to by argument +.Ar ret . +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +Function +.Fn dwarf_lineaddr +stores the program address corresponding to the source line specified +in argument +.Ar ln +into the location pointed to by argument +.Ar ret . +.Pp +Function +.Fn dwarf_linebeginstatement +sets the location pointed to by argument +.Ar ret +to 1 if the source line specified by the line descriptor +.Ar ln +is the beginning of a statement, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineblock +sets the location pointed to by argument +.Ar ret +to 1 if the source line specified by the line descriptor +.Ar ln +is the beginning of a basic block, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineendsequence +sets the location pointed to by argument +.Ar ret +to 1 if the program address associated with the line descriptor +.Ar ln +is the address immediately following the end of a sequence of target +machine instructions, or to 0 otherwise. +.Pp +Function +.Fn dwarf_lineno +stores the line number of the source line associated with the line +descriptor +.Ar ln +into the location pointed to by argument +.Ar ret . +.Pp +Function +.Fn dwarf_lineoff +stores the column number within a line associated with descriptor +.Ar ln +into the location pointed to by argument +.Ar ret . +The retrieved column numbers are 1-based, with the value -1 indicating +that column number information was not available. +.Pp +Function +.Fn dwarf_linesrc +stores a pointer to a NUL-terminated string containing the source file +name associated with line descriptor +.Ar ln +into the location pointed to by argument +.Ar ret . +The full path of the source file is returned if possible. +The memory used for the source file name string is managed by the DWARF(3) +library and should not be directly freed by application code. +Instead, portable code should use +.Xr dwarf_dealloc 3 +to indicate that the string should be freed. +.Pp +Function +.Fn dwarf_line_srcfileno +stores the index of the source file associated with the line descriptor +.Ar ln +in the location pointed to by argument +.Ar ret . +The returned value is 1-based index into the array of source file +names returned by +.Xr dwarf_srcfiles 3 . +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_LINE_FILE_NUM_BAD" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Va ln +or +.Va ret +was NULL. +.It Bq Er DW_DLE_LINE_FILE_NUM_BAD +The source file name associated with the line descriptor +.Ar ln +could not be retrieved by function +.Fn dwarf_linesrc . +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_srcfiles 3 , +.Xr dwarf_srclines 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_lineno.c b/contrib/elftoolchain/libdwarf/dwarf_lineno.c new file mode 100644 index 0000000..d0c24b1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lineno.c @@ -0,0 +1,294 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +int +dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Debug dbg; + Dwarf_Line ln; + Dwarf_CU cu; + Dwarf_Attribute at; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || linebuf == NULL || linecount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + cu = die->die_cu; + if (cu->cu_lineinfo == NULL) { + if (_dwarf_lineno_init(die, at->u[0].u64, error) != + DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (cu->cu_lineinfo == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + li = cu->cu_lineinfo; + *linecount = (Dwarf_Signed) li->li_lnlen; + + if (*linecount == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (li->li_lnarray != NULL) { + *linebuf = li->li_lnarray; + return (DW_DLV_OK); + } + + if ((li->li_lnarray = malloc(*linecount * + sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist); + i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next)) + li->li_lnarray[i] = ln; + + *linebuf = li->li_lnarray; + + return (DW_DLV_OK); +} + +int +dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + Dwarf_Debug dbg; + Dwarf_CU cu; + Dwarf_Attribute at; + int i; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL || srcfiles == NULL || srccount == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + cu = die->die_cu; + if (cu->cu_lineinfo == NULL) { + if (_dwarf_lineno_init(die, at->u[0].u64, error) != + DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (cu->cu_lineinfo == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + li = cu->cu_lineinfo; + *srccount = (Dwarf_Signed) li->li_lflen; + + if (*srccount == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (li->li_lfnarray != NULL) { + *srcfiles = li->li_lfnarray; + return (DW_DLV_OK); + } + + if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + for (i = 0, lf = STAILQ_FIRST(&li->li_lflist); + i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) { + if (lf->lf_fullpath) + li->li_lfnarray[i] = lf->lf_fullpath; + else + li->li_lfnarray[i] = lf->lf_fname; + } + + *srcfiles = li->li_lfnarray; + + return (DW_DLV_OK); +} + +int +dwarf_linebeginstatement(Dwarf_Line ln, Dwarf_Bool *ret_bool, + Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_stmt; + + return (DW_DLV_OK); +} + +int +dwarf_lineendsequence(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_endseq; + + return (DW_DLV_OK); +} + +int +dwarf_lineno(Dwarf_Line ln, Dwarf_Unsigned *ret_lineno, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineno == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_lineno = ln->ln_lineno; + + return (DW_DLV_OK); +} + +int +dwarf_line_srcfileno(Dwarf_Line ln, Dwarf_Unsigned *ret_fileno, + Dwarf_Error *error) +{ + + if (ln == NULL || ret_fileno == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_fileno = ln->ln_fileno; + + return (DW_DLV_OK); +} + +int +dwarf_lineaddr(Dwarf_Line ln, Dwarf_Addr *ret_lineaddr, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineaddr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_lineaddr = ln->ln_addr; + + return (DW_DLV_OK); +} + +int +dwarf_lineoff(Dwarf_Line ln, Dwarf_Signed *ret_lineoff, Dwarf_Error *error) +{ + + if (ln == NULL || ret_lineoff == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (ln->ln_column == 0) + *ret_lineoff = -1; + else + *ret_lineoff = (Dwarf_Signed) ln->ln_column; + + return (DW_DLV_OK); +} + +int +dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + int i; + + if (ln == NULL || ret_linesrc == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + li = ln->ln_li; + assert(li != NULL); + + for (i = 1, lf = STAILQ_FIRST(&li->li_lflist); + (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL; + i++, lf = STAILQ_NEXT(lf, lf_next)) + ; + + if (lf == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD); + return (DW_DLV_ERROR); + } + + if (lf->lf_fullpath) { + *ret_linesrc = (char *) lf->lf_fullpath; + return (DW_DLV_OK); + } + + *ret_linesrc = lf->lf_fname; + + return (DW_DLV_OK); +} + +int +dwarf_lineblock(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) +{ + + if (ln == NULL || ret_bool == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_bool = ln->ln_bblock; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 b/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 new file mode 100644 index 0000000..a826acb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 @@ -0,0 +1,100 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_lne_end_sequence.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 15, 2011 +.Os +.Dt DWARF_LNE_END_SEQUENCE 3 +.Sh NAME +.Nm dwarf_lne_end_sequence +.Nd set the end of instruction sequence +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_lne_end_sequence +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr addr" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_lne_end_sequence +sets the address that indicates the end of a sequence of target machine +instructions. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar addr +specifies an address value which is the first byte after the end of a +instruction sequence. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_lne_end_sequence +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_lne_end_sequence +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_lne_end_sequence +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The value in argument +.Ar addr +overlapped an existing line information entry. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_set_address 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 b/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 new file mode 100644 index 0000000..8a46b7b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_lne_set_address.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 14, 2011 +.Os +.Dt DWARF_LNE_SET_ADDRESS 3 +.Sh NAME +.Nm dwarf_lne_set_address +.Nd set the base address for line number information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_Unsigned" +.Fo dwarf_lne_set_address +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Addr off" +.Fa "Dwarf_Unsigned symndx" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_lne_set_address +sets the base address used by subsequent invocations of the +.Xr dwarf_add_line_entry 3 +function. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar off +specifies a relocatable program address. +.Pp +Argument +.Ar symndx +specifies the index of the ELF symbol to be used for relocation. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_lne_set_address +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_lne_set_address +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_lne_set_address +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The argument +.Ar symndx +had an illegal value. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_directory_decl 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_add_line_entry 3 , +.Xr dwarf_lne_end_sequence 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist.3 b/contrib/elftoolchain/libdwarf/dwarf_loclist.3 new file mode 100644 index 0000000..2e95d74 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist.3 @@ -0,0 +1,230 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_loclist.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_LOCLIST 3 +.Sh NAME +.Nm dwarf_loclist , +.Nm dwarf_loclist_n +.Nd retrieve DWARF location expression information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_loclist +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc +.Ft int +.Fo dwarf_loclist_n +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Locdesc ***llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +These functions retrieve the location expressions +associated with a DWARF attribute. +.Pp +Note: function +.Fn dwarf_loclist +is deprecated. +New application code should instead use function +.Fn dwarf_loclist_n +.Pp +Function +.Fn dwarf_loclist_n +retrieves the list of location expressions associated with a DWARF +attribute. +Argument +.Ar at +should reference a valid DWARF attribute. +Argument +.Ar llbuf +should point to a location which will hold a returned array of +pointers to +.Vt Dwarf_Locdesc +descriptors. +Argument +.Ar listlen +should point to a location which will be set to the number of +elements contained in the returned array. +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +Function +.Fn dwarf_loclist +retrieves the first location expression associated with an attribute. +Argument +.Ar at +should reference a valid DWARF attribute. +Argument +.Ar llbuf +should point to a location which will hold the returned pointer +to a +.Vt Dwarf_Locdesc +descriptor. +Argument +.Ar listlen +should point to a location which will be always set to 1. +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +.Vt Dwarf_Locdesc +descriptors are defined in the header file +.In libdwarf.h , +and consist of following fields: +.Pp +.Bl -tag -width ".Va ld_cents" -compact +.It Va ld_lopc +The lowest program counter address covered by the descriptor. +This field will be set to 0 if the descriptor is not associated with +an address range. +.It Va ld_hipc +The highest program counter address covered by the descriptor. +This field will be set to 0 if the descriptor is not associated with +an address range. +.It Va ld_cents +The number of entries returned in +.Va ld_s +field. +.It Va ld_s +Pointer to an array of +.Vt Dwarf_Loc +descriptors. +.El +.Pp +Each +.Vt Dwarf_Loc +descriptor represents one operation of a location expression. +These descriptors are defined in the header file +.In libdwarf.h , +and consist of following fields: +.Pp +.Bl -tag -width ".Va lr_number2" -compact +.It Va lr_atom +The operator name, one of the +.Dv DW_OP_* +constants defined in the header file +.In dwarf.h . +.It Va lr_number +The first operand of this operation. +.It Va lr_number2 +The second operand of this operation. +.It Va lr_offset +The byte offset of this operation within the containing location +expression. +.El +.Ss Memory Management +The memory area used for the descriptor array returned in argument +.Ar llbuf +is allocated by the +.Lb libdwarf . +When the descriptor array is no longer needed, application code should +use function +.Xr dwarf_dealloc 3 +to free the memory area in the following manner: +.Bl -enum +.It +First, the +.Ar ld_s +field of each +.Vt Dwarf_Locdesc +descriptor should be deallocated using the allocation type +.Dv DW_DLA_LOC_BLOCK . +.It +Then, the application should free each +.Vt Dwarf_Locdesc +descriptor using the allocation type +.Dv DW_DLA_LOCDESC . +.It +Finally, the +.Va llbuf +pointer should be deallocated using the allocation type +.Dv DW_DLA_LIST . +.El +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar at , +.Ar llbuf +or +.Ar listlen +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The attribute provided by argument +.Ar at +does not contain a location expression or is not associated with a +location expression list. +.El +.Sh EXAMPLE +To retrieve the location list associated with an attribute, use: +.Bd -literal -offset indent +Dwarf_Attribute at; +Dwarf_Locdesc **llbuf; +Dwarf_Signed lcnt; +Dwarf_Loc *lr; +Dwarf_Error de; +int i; + +if (dwarf_loclist_n(at, &llbuf, &lcnt, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_loclist_n failed: %s", + dwarf_errmsg(de)); + +for (i = 0; i < lcnt; i++) { + /* ... Use llbuf[i] ... */ + for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { + lr = &llbuf[i]->ld_s[j]; + /* ... Use each Dwarf_Loc descriptor ... */ + } + dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); +} +dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_loclist_from_expr 3 , +.Xr dwarf_loclist_from_expr_a 3 , +.Xr dwarf_get_loclist_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist.c b/contrib/elftoolchain/libdwarf/dwarf_loclist.c new file mode 100644 index 0000000..cf6fa9d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist.c @@ -0,0 +1,262 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_loclist.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +int +dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Loclist ll; + Dwarf_Debug dbg; + int ret; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_attrib) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + switch (at->at_form) { + case DW_FORM_data4: + case DW_FORM_data8: + ret = _dwarf_loclist_find(at->at_die->die_dbg, + at->at_die->die_cu, at->u[0].u64, &ll, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, ret); + return (DW_DLV_NO_ENTRY); + } + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + *llbuf = ll->ll_ldlist; + *listlen = ll->ll_ldlen; + return (DW_DLV_OK); + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (at->at_ld == NULL) { + ret = _dwarf_loc_add(at->at_die, at, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + *llbuf = &at->at_ld; + *listlen = 1; + return (DW_DLV_OK); + default: + /* Malformed Attr? */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_NO_ENTRY); + } + default: + /* Wrong attr supplied. */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } +} + +int +dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Loclist ll; + Dwarf_Debug dbg; + int ret; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + switch (at->at_attrib) { + case DW_AT_location: + case DW_AT_string_length: + case DW_AT_return_addr: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + switch (at->at_form) { + case DW_FORM_data4: + case DW_FORM_data8: + ret = _dwarf_loclist_find(at->at_die->die_dbg, + at->at_die->die_cu, at->u[0].u64, &ll, error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + *llbuf = ll->ll_ldlist[0]; + *listlen = 1; + return (DW_DLV_OK); + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (at->at_ld == NULL) { + ret = _dwarf_loc_add(at->at_die, at, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + *llbuf = at->at_ld; + *listlen = 1; + return (DW_DLV_OK); + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + return (DW_DLV_ERROR); + } + default: + /* Wrong attr supplied. */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } +} + +int +dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, + Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data, + Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, + Dwarf_Error *error) +{ + Dwarf_Loclist ll, next_ll; + Dwarf_Locdesc *ld; + Dwarf_Section *ds; + int i, ret; + + if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL || + entry_len == NULL || next_entry == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll, + error); + if (ret == DW_DLE_NO_ENTRY) { + DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } else if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *hipc = *lopc = 0; + for (i = 0; i < ll->ll_ldlen; i++) { + ld = ll->ll_ldlist[i]; + if (i == 0) { + *hipc = ld->ld_hipc; + *lopc = ld->ld_lopc; + } else { + if (ld->ld_lopc < *lopc) + *lopc = ld->ld_lopc; + if (ld->ld_hipc > *hipc) + *hipc = ld->ld_hipc; + } + } + + ds = _dwarf_find_section(dbg, ".debug_loc"); + assert(ds != NULL); + *data = (uint8_t *) ds->ds_data + ll->ll_offset; + *entry_len = ll->ll_length; + + next_ll = TAILQ_NEXT(ll, ll_next); + if (next_ll != NULL) + *next_entry = next_ll->ll_offset; + else + *next_entry = ds->ds_size; + + return (DW_DLV_OK); +} + +int +dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, + Dwarf_Error *error) +{ + Dwarf_Locdesc *ld; + int ret; + + if (dbg == NULL || bytes_in == NULL || bytes_len == 0 || + llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, + dbg->dbg_pointer_size, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *llbuf = ld; + *listlen = 1; + + return (DW_DLV_OK); +} + +int +dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf, + Dwarf_Signed *listlen, Dwarf_Error *error) +{ + Dwarf_Locdesc *ld; + int ret; + + if (dbg == NULL || bytes_in == NULL || bytes_len == 0 || + llbuf == NULL || listlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (addr_size != 4 && addr_size != 8) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + + *llbuf = ld; + *listlen = 1; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 new file mode 100644 index 0000000..d317f7e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 @@ -0,0 +1,173 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_loclist_from_expr.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd July 6, 2011 +.Os +.Dt DWARF_LOCLIST_FROM_EXPR 3 +.Sh NAME +.Nm dwarf_loclist_from_expr , +.Nm dwarf_loclist_from_expr_a +.Nd translate DWARF location expression bytes +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_loclist_from_expr +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_loclist_from_expr_a +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Half addr_size" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_loclist_from_expr +translates DWARF location expression bytes into a +.Vt Dwarf_Locdesc +descriptor. +The size for address related data is taken to be the default address +size for the object being read. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar bytes_in +should point to an array of DWARF location expression bytes. +.Pp +Argument +.Ar bytes_len +should specify the number of the location expression bytes to be +translated. +.Pp +Argument +.Ar llbuf +should point to a location which will be set to a pointer +to a returned +.Vt Dwarf_Locdesc +descriptor. +.Pp +Argument +.Ar listlen +should point to a location which will hold the number of the +.Vt Dwarf_Locdesc +descriptors returned. +In this case it is always set to 1. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +Function +.Fn dwarf_loclist_from_expr_a +is identical to function +.Fn dwarf_loclist_from_expr , +except that it requires one additional argument +.Ar addr_size , +which specifies the address size to use when translating the location +expression bytes. +.Ss Memory Management +The memory area used for the descriptor returned in argument +.Ar llbuf +is allocated by +.Lb libdwarf . +When the descriptor is no longer needed, application code should use +function +.Xr dwarf_dealloc 3 +to free the memory area in two steps: +.Bl -enum -compact +.It +First, the array of +.Vt Dwarf_Loc +descriptors pointed to by the +.Ar ld_s +field of the +.Vt Dwarf_Locdesc +descriptor should be deallocated using the allocation type +.Dv DW_DLA_LOC_BLOCK . +.It +Next, the application should free the +.Ar llbuf +pointer using the allocation type +.Dv DW_DLA_LOCDESC . +.El +.Sh RETURN VALUES +On success, these functions returns +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set the argument +.Ar err . +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va dbg , +.Va bytes_in , +.Va llbuf +or +.Va listlen +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar bytes_len +was 0. +.It Bq Er DW_DLE_ARGUMENT +The value of argument +.Ar addr_size +was invalid. +.It Bq Er DW_DLE_LOC_EXPR_BAD +An unknown or invalid operation was found in the location expression +bytes provided in argument +.Ar bytes_in . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_loclist_n 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_loclist_entry 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_macinfo.c b/contrib/elftoolchain/libdwarf/dwarf_macinfo.c new file mode 100644 index 0000000..325c653 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_macinfo.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_macinfo.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +char * +dwarf_find_macro_value_start(char *macro_string) +{ + char *p; + + if (macro_string == NULL) + return (NULL); + + p = macro_string; + while (*p != '\0' && *p != ' ') + p++; + if (*p == ' ') + p++; + + return (p); +} + +int +dwarf_get_macro_details(Dwarf_Debug dbg, Dwarf_Off offset, + Dwarf_Unsigned max_count, Dwarf_Signed *entry_cnt, + Dwarf_Macro_Details **details, Dwarf_Error *error) +{ + Dwarf_MacroSet ms; + Dwarf_Unsigned cnt; + int i; + + if (dbg == NULL || entry_cnt == NULL || details == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (STAILQ_EMPTY(&dbg->dbg_mslist)) { + if (_dwarf_macinfo_init(dbg, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + if (STAILQ_EMPTY(&dbg->dbg_mslist)) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + STAILQ_FOREACH(ms, &dbg->dbg_mslist, ms_next) { + for (i = 0; (Dwarf_Unsigned) i < ms->ms_cnt; i++) + if (ms->ms_mdlist[i].dmd_offset == offset) { + cnt = ms->ms_cnt - i; + if (max_count != 0 && cnt > max_count) + cnt = max_count; + + *details = &ms->ms_mdlist[i]; + *entry_cnt = cnt; + + return (DW_DLV_OK); + } + } + + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + + return (DW_DLV_NO_ENTRY); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 b/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 new file mode 100644 index 0000000..34ec280 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_nametbl.m4 @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: dwarf_nametbl.m4 2074 2011-10-27 03:34:33Z jkoshy $ + */ + +define(`MAKE_NAMETBL_API',` +int +dwarf_get_$1s(Dwarf_Debug dbg, Dwarf_$2 **$1s, + Dwarf_Signed *ret_count, Dwarf_Error *error) +{ + Dwarf_Section *ds; + int ret; + + if (dbg == NULL || $1s == NULL || ret_count == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (dbg->dbg_$1s == NULL) { + if ((ds = _dwarf_find_section(dbg, ".debug_$4")) != NULL) { + ret = _dwarf_nametbl_init(dbg, &dbg->dbg_$1s, ds, + error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + if (dbg->dbg_$1s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + } + + *$1s = dbg->dbg_$1s->ns_array; + *ret_count = dbg->dbg_$1s->ns_len; + + return (DW_DLV_OK); +} + +int +dwarf_$3name(Dwarf_$2 $1, char **ret_name, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_name = $1->np_name; + + return (DW_DLV_OK); +} + +int +dwarf_$1_die_offset(Dwarf_$2 $1, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + *ret_offset = nt->nt_cu_offset + $1->np_offset; + + return (DW_DLV_OK); +} + +int +dwarf_$1_cu_offset(Dwarf_$2 $1, Dwarf_Off *ret_offset, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_Debug dbg; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + *ret_offset = nt->nt_cu_offset; + + return (DW_DLV_OK); +} + +int +dwarf_$1_name_offsets(Dwarf_$2 $1, char **ret_name, Dwarf_Off *die_offset, + Dwarf_Off *cu_offset, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Debug dbg; + Dwarf_NameTbl nt; + + dbg = $1 != NULL ? $1->np_nt->nt_cu->cu_dbg : NULL; + + if ($1 == NULL || ret_name == NULL || die_offset == NULL || + cu_offset == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + nt = $1->np_nt; + assert(nt != NULL); + + cu = nt->nt_cu; + assert(cu != NULL); + + *ret_name = $1->np_name; + *die_offset = nt->nt_cu_offset + $1->np_offset; + *cu_offset = cu->cu_1st_offset; + + return (DW_DLV_OK); +} + +void +dwarf_$1s_dealloc(Dwarf_Debug dbg, Dwarf_$2 *$1s, Dwarf_Signed count) +{ + + (void) dbg; + (void) $1s; + (void) count; +} +') diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_die.3 b/contrib/elftoolchain/libdwarf/dwarf_new_die.3 new file mode 100644 index 0000000..1c463d3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_die.3 @@ -0,0 +1,164 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_new_die.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 4, 2011 +.Os +.Dt DWARF_NEW_DIE 3 +.Sh NAME +.Nm dwarf_new_die +.Nd allocate a new debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Die +.Fo dwarf_new_die +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Tag tag" +.Fa "Dwarf_P_Die parent" +.Fa "Dwarf_P_Die child" +.Fa "Dwarf_P_Die left" +.Fa "Dwarf_P_Die right" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_die +allocates a new DWARF debugging information entry and links it +to another debugging information entry. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar tag +should specify the tag of the newly created debugging information entry. +Valid values for this argument are those for the +.Dv DW_TAG_ Ns * +symbols defined in +.In libdwarf.h . +.Pp +Argument +.Ar parent +specifies the parent link of the debugging information entry. +.Pp +Argument +.Ar child +specifies the first child link of the debugging information entry. +.Pp +Argument +.Ar left +specifies the left sibling link of the debugging information entry. +.Pp +Argument +.Ar right +specifies the right sibling link of the debugging information entry. +.Pp +Only one of arguments +.Ar parent , +.Ar child , +.Ar left +and +.Ar right +is allowed to be non-NULL. +Application code can subsequently call the function +.Xr dwarf_die_link 3 +to change the links for the created debugging information entry. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_die +returns the newly created debugging information entry. +In case of an error, function +.Fn dwarf_new_die +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_new_die +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +More than one of the arguments +.Ar parent , +.Ar child , +.Ar left +and +.Ar right +were non-NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh EXAMPLES +To create debugging information entries and add them to the producer +instance, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_P_Die die1, die2; +Dwarf_Error de; + +/* ... assume dbg refers to a DWARF producer instance ... */ + +die1 = dwarf_new_die(dbg, DW_TAG_compilation_unit, NULL, NULL, NULL, + NULL, &de); +if (die1 == NULL) { + warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); + return; +} + +die2 = dwarf_new_die(dbg, DW_TAG_base_type, die1, NULL, NULL, + NULL, &de); +if (die1 == NULL) { + warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); + return; +} + +if (dwarf_add_die_to_debug(dbg, die1, &de) != DW_DLV_OK) { + warnx("dwarf_add_die_to_debug failed: %s", dwarf_errmsg(-1)); + return; +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_die_to_debug 3 , +.Xr dwarf_die_link 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 b/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 new file mode 100644 index 0000000..d8f4c8a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 @@ -0,0 +1,135 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_new_expr.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 8, 2011 +.Os +.Dt DWARF_NEW_EXPR 3 +.Sh NAME +.Nm dwarf_new_expr +.Nd create a location expression descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Expr" +.Fo dwarf_new_expr +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_expr +allocates a DWARF location expression descriptor used to build up a +location expression stream. +.Pp +The application can use the functions +.Xr dwarf_add_expr_gen 3 +and +.Xr dwarf_add_expr_addr_b 3 +to add location expression operators to the created descriptor. +When done, the application can call the function +.Xr dwarf_expr_into_block 3 +to retrieve the generated byte stream for the location expression, +or call the function +.Xr dwarf_add_AT_location_expr 3 +to create an attribute with the location expression stream as its +value. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_expr +returns the created location expression descriptor. +In case of an error, function +.Fn dwarf_new_expr +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_new_expr +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El +.Sh EXAMPLES +To create a location expression descriptor, add location expression +operators to it and to retrieve the generated byte stream, +use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; +Dwarf_P_Expr pe; +Dwarf_Addr buf; +Dwarf_Unsigned len; + +/* ...Assume that `dbg' refers to a DWARF producer instance... */ + +if ((pe = dwarf_new_expr(dbg, &de)) == DW_DLV_BADADDR) { + warnx("dwarf_new_expr failed: %s", dwarf_errmsg(-1)); + return; +} + +if (dwarf_add_expr_gen(pe, DW_OP_regx, 55, 0, &de) == + DW_DLV_NOCOUNT) { + warnx("dwarf_add_expr_gen failed: %s", dwarf_errmsg(-1)); + return; +} + +if ((buf = dwarf_expr_into_block(pe, &len, &de)) == + DW_DLV_BADADDR) { + warnx("dwarf_expr_into_block failed: %s", + dwarf_errmsg(-1)); + return; +} +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_AT_location_expr 3 , +.Xr dwarf_add_expr_gen 3 , +.Xr dwarf_add_expr_addr 3 , +.Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_expr_current_offset 3 , +.Xr dwarf_expr_into_block 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 b/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 new file mode 100644 index 0000000..1ca19a8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_new_fde.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 24, 2011 +.Os +.Dt DWARF_NEW_FDE 3 +.Sh NAME +.Nm dwarf_new_fde +.Nd allocate a DWARF frame descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "Dwarf_P_Fde" +.Fo dwarf_new_fde +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_new_fde +allocates a new DWARF frame descriptor. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_new_fde +returns the newly created frame descriptor. +In case of an error, function +.Fn dwarf_new_fde +returns +.Dv DW_DLV_BADADDR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_new_fde +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_fde 3 , +.Xr dwarf_add_frame_fde_b 3 , +.Xr dwarf_add_frame_cie 3 , +.Xr dwarf_fde_cfa_offset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 new file mode 100644 index 0000000..5be00b8 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 @@ -0,0 +1,203 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_next_cu_header.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd July 24, 2010 +.Os +.Dt DWARF_NEXT_CU_HEADER 3 +.Sh NAME +.Nm dwarf_next_cu_header , +.Nm dwarf_next_cu_header_b +.Nd step through compilation units in a DWARF debug context +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_next_cu_header +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_next_cu_header_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *cu_length" +.Fa "Dwarf_Half *cu_version" +.Fa "Dwarf_Off *cu_abbrev_offset" +.Fa "Dwarf_Half *cu_pointer_size" +.Fa "Dwarf_Half *cu_offset_size" +.Fa "Dwarf_Half *cu_extension_size" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +These functions are used to step through compilation unit contexts +associated with a DWARF debug context, optionally returning information +about the unit. +.Pp +Function +.Fn dwarf_next_cu_header_b +is the API recommended for new application code. +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Ar cu_length +should point to a location that will be set to the +length of the compilation unit. +Argument +.Ar cu_version +should point to a location that will be set to the +version number for the compilation unit. +Argument +.Ar cu_abbrev_offset +should point to a location that will be set to the +starting offset (in the +.Dq .debug_abbrev +section) of the set of debugging information entry abbreviations +associated with this compilation unit. +Argument +.Ar cu_pointer_size +should point to a location that will be set to the +size in bytes of an address for the machine architecture of the +underlying object being debugged. +Argument +.Ar cu_offset_size +should point to a location that will be set to the +size in bytes for a DWARF offset in the compilation unit. +Argument +.Ar cu_extension_size +is only needed for processing MIPS/IRIX objects that use +a non-standard DWARF format. +It should point to a location that will be set to 4 for normal +objects and to 0 for non-standard ones. +Argument +.Ar cu_next_offset +should point to a location that will be set to the +offset of the next compilation unit header in the +.Dq \&.debug_info +section. +Argument +.Ar err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +Function +.Fn dwarf_next_cu_header +is less general than +.Fn dwarf_next_cu_header_b , +and is deprecated for use by new application code. +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Ar cu_length +should point to a location that will be set to the +length of the compilation unit. +Argument +.Ar cu_version +should point to a location that will be set to the +version number for the compilation unit. +Argument +.Ar cu_abbrev_offset +should point to a location that will be set to the +starting offset in the +.Dq .debug_abbrev +section of the set of debugging information entry abbreviations +associated with this compilation unit. +Argument +.Ar cu_pointer_size +should point to a location that will be set to the +size of an address in bytes for the machine architecture of the +underlying debugging object. +Argument +.Ar cu_next_offset +should point to a location that will be set to the +offset of the next compilation unit. +Argument +.Ar err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +A value of NULL may be used for any of the arguments +.Ar cu_length , +.Ar cu_version , +.Ar cu_abbrev_offset , +.Ar cu_pointer_size , +.Ar cu_offset_size , +.Ar cu_extension_size , +.Ar cu_next_offset +and +.Ar err +if the caller is not interested in the respective value. +.Ss Iterating Through Compilation Units in a Debug Context +.Pp +The first call to functions +.Fn dwarf_next_cu_header_b +and +.Fn dwarf_next_cu_header +for a given debug context will return information about the first +compilation unit in the debug context. +Subsequent calls to these functions will iterate through the remaining +compilation units in the debug context. +On stepping past the last compilation unit in the debug context, +functions +.Fn dwarf_next_cu_header +and +.Fn dwarf_next_cu_header_b +return +.Dv DW_DLV_NO_ENTRY +and reset their internal state. +The next call to these functions will restart from the first compilation +unit in the debug context. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +In case of an error, they return +.Dv DW_DLV_ERROR +and set argument +.Ar err . +When there are no more compilation units left to traverse, they return +.Dv DW_DLV_NO_ENTRY . +.Sh ERRORS +These functions can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , +.Xr dwarf_init 3 , +.Xr dwarf_siblingof 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_object_init.3 b/contrib/elftoolchain/libdwarf/dwarf_object_init.3 new file mode 100644 index 0000000..2915669 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_object_init.3 @@ -0,0 +1,227 @@ +.\" Copyright (c) 2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_object_init.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 29, 2011 +.Os +.Dt DWARF_OBJECT_INIT 3 +.Sh NAME +.Nm dwarf_object_init +.Nd allocate a DWARF debug descriptor with application-specific file \ +access methods +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_object_init +.Fa "Dwarf_Obj_Access_Interface *iface" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Debug *dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +.Pp +The +.Fn dwarf_object_init +function allocates and returns a +.Vt Dwarf_Debug +instance that uses application-supplied access methods to read file +content. +.Pp +The argument +.Ar iface +should point to a populated +.Vt Dwarf_Obj_Access_Interface +structure. +The contents of the +.Vt Dwarf_Obj_Access_Interface +structure are described in the section +.Sx "Object Access Functions" +below. +.Pp +The argument +.Ar errhand +should point to a function to be called in case of an error. +If this argument is +.Dv NULL +then a default error handling scheme is used. +See +.Xr dwarf 3 +for a description of the error handling schemes available. +.Pp +The argument +.Ar errarg +will be passed to the error handler function pointed to by argument +.Ar errhand . +.Pp +The argument +.Ar dbg +should point to a memory location that will be set to a reference to +the returned +.Vt Dwarf_Debug +descriptor. +.Pp +The argument +.Ar err +will be used to return a +.Vt Dwarf_Error +descriptor in case of an error. +.Ss Object Access Functions +The data structures used to specify object access methods are defined +in +.In libdwarf.h . +.Bl -tag -width indent +.It Vt "Dwarf_Obj_Access_Interface" +This structure bundles together a set of file access methods along +with a pointer to application-private state. +.Bd -literal -offset indent +typedef struct { + void *object; + const Dwarf_Obj_Access_Methods *methods; +} Dwarf_Obj_Access_Interface; +.Ed +.Pp +.Bl -tag -width ".Ar methods" -compact +.It Ar object +This field points to application-specific state that will be passed as +the first parameter to the actual access object methods. +.It Ar methods +This structure contains pointers to the functions implementing the +access methods, as described below. +.El +.It Vt Dwarf_Obj_Access_Methods +This structure specifies the functions implementing low-level access. +.Bd -literal -offset indent +typedef struct { + int (*get_section_info)(void *obj, Dwarf_Half index, + Dwarf_Obj_Access_Section *ret, int *error); + Dwarf_Endianness (*get_byte_order)(void *obj); + Dwarf_Small (*get_length_size)(void *obj); + Dwarf_Small (*get_pointer_size)(void *obj); + Dwarf_Unsigned (*get_section_count)(void *obj); + int (*load_section)(void *obj, Dwarf_Half ndx, + Dwarf_Small **ret_data, int *error); +} Dwarf_Obj_Access_Methods; +.Ed +.Pp +.Bl -tag -width ".Ar get_section_count" -compact +.It Ar get_byte_order +This function should return the endianness of the DWARF object by +returning one of the constants +.Dv DW_OBJECT_MSB +or +.Dv DW_OBJECT_LSB . +.It Ar get_length_size +This function should return the number of bytes needed to represent a +DWARF offset in the object being debugged. +.It Ar get_pointer_size +This function should return the size in bytes, in the object being +debugged, of a memory address. +.It Ar get_section_count +This function should return the number of sections in the object being +debugged. +.It Ar get_section_info +This function should return information about the section at the +index +.Ar ndx +by filling in the structure of type +.Vt Dwarf_Obj_Access_Section +pointed to by argument +.Ar ret . +The +.Vt Dwarf_Obj_Access_Section +structure is described below. +.It Ar load_section +This function should load the section specified by argument +.Ar ndx +into memory and place a pointer to the section's data into +the location pointed to by argument +.Ar ret_data . +.El +.Pp +The argument +.Ar obj +passed to these functions will be set to the pointer value in the +.Ar object +field of the associated +.Vt Dwarf_Obj_Access_Interface +structure. +.Pp +The argument +.Ar error +is used to return an error code in case of an error. +.It Vt Dwarf_Obj_Access_Section +This structure describes the layout of a section in the DWARF object. +.Bd -literal -offset indent +typedef struct { + Dwarf_Addr addr; + Dwarf_Unsigned size; + const char *name; +} Dwarf_Obj_Access_Section; +.Ed +.Pp +.Bl -tag -width ".Ar name" -compact +.It Ar addr +A pointer to the start of the section's data. +.It Ar size +The size of the section in bytes. +.It Ar name +A pointer to a NUL-terminated string containing the name of the +section. +.El +.El +.Sh RETURN VALUES +On success, the +.Fn dwarf_object_init +function returns +.Dv DW_DLV_OK . +In case of an error, the function returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err. +.Sh ERRORS +The +.Fn dwarf_object_init +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_DEBUG_INFO_NULL" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar iface +or +.Ar dbg +was NULL. +.It Bq Er DW_DLE_DEBUG_INFO_NULL +The underlying object did not contain debugging information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_init_elf 3 , +.Xr dwarf_object_finish 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c b/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c new file mode 100644 index 0000000..61e14db --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_arange.c @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_arange.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_add_arange(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length, + Dwarf_Signed symbol_index, Dwarf_Error *error) +{ + + return (dwarf_add_arange_b(dbg, start, length, symbol_index, 0, 0, + error)); +} + +Dwarf_Unsigned +dwarf_add_arange_b(Dwarf_P_Debug dbg, Dwarf_Addr start, Dwarf_Unsigned length, + Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_symbol, Dwarf_Error *error) +{ + Dwarf_ArangeSet as; + Dwarf_Arange ar; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + as = dbg->dbgp_as; + + if (end_symbol_index > 0 && + (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + + if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + ar->ar_as = as; + ar->ar_address = start; + ar->ar_range = length; + ar->ar_symndx = symbol_index; + ar->ar_esymndx = end_symbol_index; + ar->ar_eoff = offset_from_end_symbol; + STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next); + + return (1); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c b/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c new file mode 100644 index 0000000..f46672b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c @@ -0,0 +1,384 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_attr.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_P_Attribute +dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_P_Expr loc_expr, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL || loc_expr == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_expr = loc_expr; + + if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + at->u[0].u64 = loc_expr->pe_length; + at->u[1].u8p = loc_expr->pe_block; + if (loc_expr->pe_length <= UCHAR_MAX) + at->at_form = DW_FORM_block1; + else if (loc_expr->pe_length <= USHRT_MAX) + at->at_form = DW_FORM_block2; + else if (loc_expr->pe_length <= UINT_MAX) + at->at_form = DW_FORM_block4; + else + at->at_form = DW_FORM_block; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = DW_AT_const_value; + at->at_form = DW_FORM_sdata; + at->u[0].s64 = value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + + dbg = die != NULL ? die->die_dbg : NULL; + + if (die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = DW_AT_const_value; + at->at_form = DW_FORM_udata; + at->u[0].u64 = value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, + error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) +{ + + return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, + error)); +} + +Dwarf_P_Attribute +dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_addr; + at->at_relsym = sym_index; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, + NULL, &at, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); + +} + +Dwarf_P_Attribute +dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_ref_addr; + at->at_relsym = sym_index; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned value, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->u[0].u64 = value; + + if (value <= UCHAR_MAX) + at->at_form = DW_FORM_data1; + else if (value <= USHRT_MAX) + at->at_form = DW_FORM_data2; + else if (value <= UINT_MAX) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Signed value, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->u[0].u64 = value; + + if (value >= SCHAR_MIN && value <= SCHAR_MAX) + at->at_form = DW_FORM_data1; + else if (value >= SHRT_MIN && value <= SHRT_MAX) + at->at_form = DW_FORM_data2; + else if (value >= INT_MIN && value <= INT_MAX) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_P_Die ref_die, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + if (dbg->dbg_offset_size == 4) + at->at_form = DW_FORM_ref4; + else + at->at_form = DW_FORM_ref8; + + at->at_refdie = ref_die; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Small flag, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_flag; + at->u[0].u64 = flag ? 1 : 0; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (at); +} + +Dwarf_P_Attribute +dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + char *string, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + if (dbg == NULL || die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + /* XXX Add DW_FORM_string style string instead? */ + + if (_dwarf_add_string_attr(die, &at, attr, string, error) != + DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (at); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_die.c b/contrib/elftoolchain/libdwarf/dwarf_pro_die.c new file mode 100644 index 0000000..3d28236 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_die.c @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_die.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_add_die_to_debug(Dwarf_P_Debug dbg, Dwarf_P_Die first_die, + Dwarf_Error *error) +{ + + if (dbg == NULL || first_die == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + dbg->dbgp_root_die = first_die; + + return (DW_DLV_OK); +} + +Dwarf_P_Die +dwarf_new_die(Dwarf_P_Debug dbg, Dwarf_Tag new_tag, + Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, + Dwarf_P_Die right_sibling, Dwarf_Error *error) +{ + Dwarf_P_Die die; + int count; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + count = _dwarf_die_count_links(parent, child, left_sibling, + right_sibling); + + if (count > 1) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_die_alloc(dbg, &die, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + die->die_dbg = dbg; + die->die_tag = new_tag; + + STAILQ_INSERT_TAIL(&dbg->dbgp_dielist, die, die_pro_next); + + if (count == 0) + return (die); + + _dwarf_die_link(die, parent, child, left_sibling, right_sibling); + + return (die); +} + +Dwarf_P_Die +dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, + Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + int count; + + + if (die == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + dbg = die->die_dbg; + count = _dwarf_die_count_links(parent, child, left_sibling, + right_sibling); + + if (count > 1) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } else if (count == 0) + return (die); + + _dwarf_die_link(die, parent, child, left_sibling, right_sibling); + + return (die); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c b/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c new file mode 100644 index 0000000..eb1f59c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_expr.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +static struct _Dwarf_P_Expr_Entry * +_dwarf_add_expr(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + Dwarf_Debug dbg; + int len; + + dbg = expr != NULL ? expr->pe_dbg : NULL; + + if (_dwarf_loc_expr_add_atom(expr->pe_dbg, NULL, NULL, opcode, val1, + val2, &len, error) != DW_DLE_NONE) + return (NULL); + assert(len > 0); + + if ((ee = calloc(1, sizeof(*ee))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (NULL); + } + + STAILQ_INSERT_TAIL(&expr->pe_eelist, ee, ee_next); + + ee->ee_loc.lr_atom = opcode; + ee->ee_loc.lr_number = val1; + ee->ee_loc.lr_number2 = val2; + ee->ee_loc.lr_offset = expr->pe_length; + expr->pe_length += len; + expr->pe_invalid = 1; + + return (ee); +} + +int +_dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + Dwarf_Debug dbg; + int len, pos, ret; + + dbg = expr != NULL ? expr->pe_dbg : NULL; + + if (expr->pe_block != NULL) { + free(expr->pe_block); + expr->pe_block = NULL; + } + + if (expr->pe_length <= 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_EXPR_LENGTH_BAD); + return (DW_DLE_EXPR_LENGTH_BAD); + } + + + if ((expr->pe_block = calloc((size_t) expr->pe_length, 1)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + pos = 0; + STAILQ_FOREACH(ee, &expr->pe_eelist, ee_next) { + assert((Dwarf_Unsigned) pos < expr->pe_length); + ret = _dwarf_loc_expr_add_atom(expr->pe_dbg, + &expr->pe_block[pos], &expr->pe_block[expr->pe_length], + ee->ee_loc.lr_atom, ee->ee_loc.lr_number, + ee->ee_loc.lr_number2, &len, error); + assert(ret == DW_DLE_NONE); + assert(len > 0); + pos += len; + } + + expr->pe_invalid = 0; + + return (DW_DLE_NONE); +} + +void +_dwarf_expr_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Expr pe, tpe; + struct _Dwarf_P_Expr_Entry *ee, *tee; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(pe, &dbg->dbgp_pelist, pe_next, tpe) { + STAILQ_REMOVE(&dbg->dbgp_pelist, pe, _Dwarf_P_Expr, pe_next); + STAILQ_FOREACH_SAFE(ee, &pe->pe_eelist, ee_next, tee) { + STAILQ_REMOVE(&pe->pe_eelist, ee, _Dwarf_P_Expr_Entry, + ee_next); + free(ee); + } + if (pe->pe_block) + free(pe->pe_block); + free(pe); + } +} + +Dwarf_P_Expr +dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Expr pe; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if ((pe = calloc(1, sizeof(struct _Dwarf_P_Expr))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_BADADDR); + } + STAILQ_INIT(&pe->pe_eelist); + + STAILQ_INSERT_TAIL(&dbg->dbgp_pelist, pe, pe_next); + pe->pe_dbg = dbg; + + return (pe); +} + +Dwarf_Unsigned +dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (_dwarf_add_expr(expr, opcode, val1, val2, error) == NULL) + return (DW_DLV_NOCOUNT); + + return (expr->pe_length); +} + +Dwarf_Unsigned +dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned address, + Dwarf_Signed sym_index, Dwarf_Error *error) +{ + + return (dwarf_add_expr_addr_b(expr, address, sym_index, error)); +} + +Dwarf_Unsigned +dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned address, + Dwarf_Unsigned sym_index, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ee = _dwarf_add_expr(expr, DW_OP_addr, address, 0, error)) == NULL) + return (DW_DLV_NOCOUNT); + + ee->ee_sym = sym_index; + + return (expr->pe_length); +} + +Dwarf_Unsigned +dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error *error) +{ + + if (expr == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + return (expr->pe_length); +} + +Dwarf_Addr +dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Unsigned *length, + Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = expr != NULL ? expr->pe_dbg : NULL; + + if (expr == NULL || length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); + } + + if (expr->pe_block == NULL || expr->pe_invalid) + if (_dwarf_expr_into_block(expr, error) != DW_DLE_NONE) + return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); + + *length = expr->pe_length; + + return ((Dwarf_Addr) (uintptr_t) expr->pe_block); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c b/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c new file mode 100644 index 0000000..8e1dc4a --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_finish.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_finish.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Unsigned +dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL || dbg->dbg_mode != DW_DLC_WRITE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + _dwarf_deinit(dbg); + + free(dbg); + + return (1); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c b/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c new file mode 100644 index 0000000..fac390e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_frame.c @@ -0,0 +1,195 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_frame.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_P_Fde +dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Fde fde; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_BADADDR); + } + + fde->fde_dbg = dbg; + + return (fde); +} + +Dwarf_Unsigned +dwarf_add_frame_cie(Dwarf_P_Debug dbg, char *augmenter, Dwarf_Small caf, + Dwarf_Small daf, Dwarf_Small ra, Dwarf_Ptr initinst, + Dwarf_Unsigned inst_len, Dwarf_Error *error) +{ + Dwarf_P_Cie cie; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { + DWARF_SET_ERROR(dbg, error,DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + STAILQ_INSERT_TAIL(&dbg->dbgp_cielist, cie, cie_next); + + cie->cie_index = dbg->dbgp_cielen++; + + if (augmenter != NULL) { + cie->cie_augment = (uint8_t *) strdup(augmenter); + if (cie->cie_augment == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + } + + cie->cie_caf = caf; + cie->cie_daf = (int8_t) daf; /* daf is signed. */ + cie->cie_ra = ra; + if (initinst != NULL && inst_len > 0) { + cie->cie_initinst = malloc((size_t) inst_len); + if (cie->cie_initinst == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + memcpy(cie->cie_initinst, initinst, inst_len); + cie->cie_instlen = inst_len; + } + + return (cie->cie_index); +} + +Dwarf_Unsigned +dwarf_add_frame_fde(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, + Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, + Dwarf_Unsigned symbol_index, Dwarf_Error *error) +{ + + return (dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, code_len, + symbol_index, 0, 0, error)); +} + +Dwarf_Unsigned +dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, Dwarf_P_Fde fde, Dwarf_P_Die die, + Dwarf_Unsigned cie, Dwarf_Addr virt_addr, Dwarf_Unsigned code_len, + Dwarf_Unsigned symbol_index, Dwarf_Unsigned end_symbol_index, + Dwarf_Addr offset_from_end_sym, Dwarf_Error *error) +{ + Dwarf_P_Cie ciep; + int i; + + /* + * XXX SGI libdwarf need the DIE arg because later it will insert a + * DW_AT_MIPS_fde attribute, which points to the offset the + * correspoding FDE, into this DIE. Do we need this? + */ + (void) die; + + if (dbg == NULL || fde == NULL || fde->fde_dbg != dbg) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + ciep = STAILQ_FIRST(&dbg->dbgp_cielist); + for (i = 0; (Dwarf_Unsigned) i < cie; i++) { + ciep = STAILQ_NEXT(ciep, cie_next); + if (ciep == NULL) + break; + } + if (ciep == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (end_symbol_index > 0 && + (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + fde->fde_cie = ciep; + fde->fde_initloc = virt_addr; + fde->fde_adrange = code_len; + fde->fde_symndx = symbol_index; + fde->fde_esymndx = end_symbol_index; + fde->fde_eoff = offset_from_end_sym; + + STAILQ_INSERT_TAIL(&dbg->dbgp_fdelist, fde, fde_next); + + return (dbg->dbgp_fdelen++); +} + +Dwarf_P_Fde +dwarf_fde_cfa_offset(Dwarf_P_Fde fde, Dwarf_Unsigned reg, Dwarf_Signed offset, + Dwarf_Error *error) +{ + int ret; + Dwarf_Debug dbg; + + dbg = fde != NULL ? fde->fde_dbg : NULL; + + if (fde == NULL || reg > 0x3f) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_frame_fde_add_inst(fde, DW_CFA_offset | (reg & 0x3f), + offset, 0, error); + + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (fde); +} + +Dwarf_P_Fde +dwarf_add_fde_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + int ret; + + if (fde == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + ret = _dwarf_frame_fde_add_inst(fde, op, val1, val2, error); + + if (ret != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + return (fde); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 new file mode 100644 index 0000000..6e8bee1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_funcs.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_funcs.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(func) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_init.c b/contrib/elftoolchain/libdwarf/dwarf_pro_init.c new file mode 100644 index 0000000..de7a2d5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_init.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_init.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_P_Debug +dwarf_producer_init(Dwarf_Unsigned flags, Dwarf_Callback_Func func, + Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + int mode; + + if (flags & DW_DLC_READ || flags & DW_DLC_RDWR) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (flags & DW_DLC_WRITE) + mode = DW_DLC_WRITE; + else { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (func == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_WRITE, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + dbg->dbg_mode = mode; + + if (_dwarf_init(dbg, flags, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_BADADDR); + } + + dbg->dbgp_func = func; + + return (dbg); +} + +Dwarf_P_Debug +dwarf_producer_init_b(Dwarf_Unsigned flags, Dwarf_Callback_Func_b func, + Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + int mode; + + if (flags & DW_DLC_READ || flags & DW_DLC_RDWR) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (flags & DW_DLC_WRITE) + mode = DW_DLC_WRITE; + else { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (func == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_BADADDR); + } + + if (_dwarf_alloc(&dbg, DW_DLC_WRITE, error) != DW_DLE_NONE) + return (DW_DLV_BADADDR); + + dbg->dbg_mode = mode; + + if (_dwarf_init(dbg, flags, errhand, errarg, error) != DW_DLE_NONE) { + free(dbg); + return (DW_DLV_BADADDR); + } + + dbg->dbgp_func_b = func; + + return (dbg); +} + +int +dwarf_producer_set_isa(Dwarf_P_Debug dbg, enum Dwarf_ISA isa, + Dwarf_Error *error) +{ + + if (dbg == NULL || isa >= DW_ISA_MAX) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + dbg->dbgp_isa = isa; + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c b/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c new file mode 100644 index 0000000..91e40ee --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_lineno.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_lineno.c 2973 2013-12-23 06:46:16Z kaiwang27 $"); + +Dwarf_Unsigned +dwarf_add_line_entry(Dwarf_P_Debug dbg, Dwarf_Unsigned file, + Dwarf_Addr off, Dwarf_Unsigned lineno, Dwarf_Signed column, + Dwarf_Bool is_stmt, Dwarf_Bool basic_block, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next); + + if (ln == NULL || ln->ln_addr > off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = off; + ln->ln_symndx = 0; + ln->ln_fileno = file; + ln->ln_lineno = lineno; + ln->ln_column = column; + ln->ln_bblock = basic_block != 0; + ln->ln_stmt = is_stmt != 0; + ln->ln_endseq = 0; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_lne_set_address(Dwarf_P_Debug dbg, Dwarf_Addr offs, Dwarf_Unsigned symndx, + Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL || symndx == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = offs; + ln->ln_symndx = symndx; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_lne_end_sequence(Dwarf_P_Debug dbg, Dwarf_Addr addr, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + ln = STAILQ_LAST(&li->li_lnlist, _Dwarf_Line, ln_next); + if (ln && ln->ln_addr >= addr) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if ((ln = calloc(1, sizeof(struct _Dwarf_Line))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + ln->ln_li = li; + ln->ln_addr = addr; + ln->ln_endseq = 1; + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next); + li->li_lnlen++; + + return (DW_DLV_OK); +} + +Dwarf_Unsigned +dwarf_add_directory_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + + if (dbg == NULL || name == NULL || strlen(name) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + li->li_incdirs = realloc(li->li_incdirs, (li->li_inclen + 1) * + sizeof(char *)); + if (li->li_incdirs == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + if ((li->li_incdirs[li->li_inclen] = strdup(name)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_NOCOUNT); + } + + return (++li->li_inclen); +} + +Dwarf_Unsigned +dwarf_add_file_decl(Dwarf_P_Debug dbg, char *name, Dwarf_Unsigned dirndx, + Dwarf_Unsigned mtime, Dwarf_Unsigned size, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + + if (dbg == NULL || name == NULL || strlen(name) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + li = dbg->dbgp_lineinfo; + + if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((lf->lf_fname = strdup(name)) == NULL) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + lf->lf_dirndx = dirndx; + lf->lf_mtime = mtime; + lf->lf_size = size; + STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); + + return (++li->li_lflen); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c b/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c new file mode 100644 index 0000000..2119b5b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_macinfo.c @@ -0,0 +1,142 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_macinfo.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +static int +_dwarf_add_macro(Dwarf_P_Debug dbg, int type, Dwarf_Unsigned lineno, + Dwarf_Signed fileindex, char *str1, char *str2, Dwarf_Error *error) +{ + Dwarf_Macro_Details *md; + int len; + + dbg->dbgp_mdlist = realloc(dbg->dbgp_mdlist, + (size_t) dbg->dbgp_mdcnt + 1); + if (dbg->dbgp_mdlist == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + + md = &dbg->dbgp_mdlist[dbg->dbgp_mdcnt]; + dbg->dbgp_mdcnt++; + + md->dmd_offset = 0; + md->dmd_type = type; + md->dmd_lineno = lineno; + md->dmd_fileindex = fileindex; + md->dmd_macro = NULL; + + if (str1 == NULL) + return (DW_DLV_OK); + else if (str2 == NULL) { + if ((md->dmd_macro = strdup(str1)) == NULL) { + dbg->dbgp_mdcnt--; + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + return (DW_DLV_OK); + } else { + len = strlen(str1) + strlen(str2) + 2; + if ((md->dmd_macro = malloc(len)) == NULL) { + dbg->dbgp_mdcnt--; + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + snprintf(md->dmd_macro, len, "%s %s", str1, str2); + return (DW_DLV_OK); + } +} + +int +dwarf_def_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, + char *value, Dwarf_Error *error) +{ + + if (dbg == NULL || name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_define, lineno, -1, name, + value, error)); +} + +int +dwarf_undef_macro(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, char *name, + Dwarf_Error *error) +{ + + if (dbg == NULL || name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_undef, lineno, -1, name, + NULL, error)); +} + +int +dwarf_start_macro_file(Dwarf_P_Debug dbg, Dwarf_Unsigned lineno, + Dwarf_Unsigned fileindex, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_start_file, lineno, fileindex, + NULL, NULL, error)); +} + +int +dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_end_file, 0, -1, + NULL, NULL, error)); +} + +int +dwarf_vendor_ext(Dwarf_P_Debug dbg, Dwarf_Unsigned constant, char *string, + Dwarf_Error *error) +{ + + if (dbg == NULL || string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_add_macro(dbg, DW_MACINFO_vendor_ext, constant, -1, + string, NULL, error)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 new file mode 100644 index 0000000..df57688 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_nametbl.m4 @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: dwarf_pro_nametbl.m4 2074 2011-10-27 03:34:33Z jkoshy $ + */ + +define(`MAKE_NAMETBL_PRO_API',` +Dwarf_Unsigned +dwarf_add_$1name(Dwarf_P_Debug dbg, Dwarf_P_Die die, char *$1_name, + Dwarf_Error *error) +{ + Dwarf_NameTbl nt; + Dwarf_NamePair np; + + if (dbg == NULL || die == NULL || $1_name == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (0); + } + + if (dbg->dbgp_$1s == NULL) { + dbg->dbgp_$1s = calloc(1, sizeof(struct _Dwarf_NameTbl)); + if (dbg->dbgp_$1s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + STAILQ_INIT(&dbg->dbgp_$1s->nt_nplist); + } + + nt = dbg->dbgp_$1s; + + if ((np = calloc(1, sizeof(struct _Dwarf_NamePair))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + + np->np_nt = nt; + np->np_die = die; + if ((np->np_name = strdup($1_name)) == NULL) { + free(np); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (0); + } + + STAILQ_INSERT_TAIL(&nt->nt_nplist, np, np_next); + + return (1); +} +') diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 new file mode 100644 index 0000000..2ceafd5 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_pubnames.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_pubnames.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(pub) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c b/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c new file mode 100644 index 0000000..6b0b2e2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_reloc.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_reloc.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +int +dwarf_get_relocation_info_count(Dwarf_P_Debug dbg, Dwarf_Unsigned *reloc_cnt, + int *drd_buffer_version, Dwarf_Error *error) +{ + + if (dbg == NULL || reloc_cnt == NULL || drd_buffer_version == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *reloc_cnt = dbg->dbgp_drscnt; + *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; + + return (DW_DLV_OK); +} + +int +dwarf_get_relocation_info(Dwarf_P_Debug dbg, Dwarf_Signed *elf_section_index, + Dwarf_Signed *elf_section_link, Dwarf_Unsigned *reloc_entry_count, + Dwarf_Relocation_Data *reloc_buffer, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + Dwarf_Rel_Entry dre; + int i; + + if (dbg == NULL || elf_section_index == NULL || + elf_section_link == NULL || reloc_entry_count == NULL || + reloc_buffer == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (dbg->dbgp_drscnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if (dbg->dbgp_drspos == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + drs = dbg->dbgp_drspos; + assert(drs->drs_ds != NULL && drs->drs_ref != NULL); + assert(drs->drs_drecnt > 0); + + *elf_section_index = drs->drs_ds->ds_ndx; + *elf_section_link = drs->drs_ref->ds_ndx; + *reloc_entry_count = drs->drs_drecnt; + + if (drs->drs_drd == NULL) { + drs->drs_drd = calloc(*reloc_entry_count, + sizeof(struct Dwarf_Relocation_Data_s)); + if (drs->drs_drd == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + for (i = 0, dre = STAILQ_FIRST(&drs->drs_dre); + (Dwarf_Unsigned) i < *reloc_entry_count && dre != NULL; + i++, dre = STAILQ_NEXT(dre, dre_next)) { + drs->drs_drd[i].drd_type = dre->dre_type; + drs->drs_drd[i].drd_length = dre->dre_length; + drs->drs_drd[i].drd_offset = dre->dre_offset; + drs->drs_drd[i].drd_symbol_index = dre->dre_symndx; + } + assert((Dwarf_Unsigned) i == *reloc_entry_count && dre == NULL); + } + + *reloc_buffer = drs->drs_drd; + + dbg->dbgp_drspos = STAILQ_NEXT(dbg->dbgp_drspos, drs_next); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c b/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c new file mode 100644 index 0000000..42aa516 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_sections.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_sections.c 2074 2011-10-27 03:34:33Z jkoshy $"); + +Dwarf_Signed +dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + + if (dbg == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_NOCOUNT); + } + + if (_dwarf_generate_sections(dbg, error) != DW_DLE_NONE) + return (DW_DLV_NOCOUNT); + + return (dbg->dbgp_seccnt); +} + +Dwarf_Ptr +dwarf_get_section_bytes(Dwarf_P_Debug dbg, Dwarf_Signed dwarf_section, + Dwarf_Signed *elf_section_index, Dwarf_Unsigned *length, Dwarf_Error *error) +{ + Dwarf_Ptr data; + + (void) dwarf_section; /* ignored. */ + + if (dbg == NULL || elf_section_index == NULL || length == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (NULL); + } + + if (dbg->dbgp_secpos == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (NULL); + } + + *elf_section_index = dbg->dbgp_secpos->ds_ndx; + *length = dbg->dbgp_secpos->ds_size; + data = dbg->dbgp_secpos->ds_data; + + dbg->dbgp_secpos = STAILQ_NEXT(dbg->dbgp_secpos, ds_next); + + return (data); +} + +void +dwarf_reset_section_bytes(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL); + + dbg->dbgp_secpos = STAILQ_FIRST(&dbg->dbgp_seclist); + dbg->dbgp_drspos = STAILQ_FIRST(&dbg->dbgp_drslist); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 new file mode 100644 index 0000000..eab6cc6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_types.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_types.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(type) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 new file mode 100644 index 0000000..ac7424d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_vars.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_vars.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(var) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 b/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 new file mode 100644 index 0000000..60984fd --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pro_weaks.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pro_weaks.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_pro_nametbl.m4') +divert(0) +MAKE_NAMETBL_PRO_API(weak) diff --git a/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 b/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 new file mode 100644 index 0000000..717335e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 @@ -0,0 +1,297 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_producer_init.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd August 20, 2011 +.Os +.Dt DWARF_PRODUCER_INIT 3 +.Sh NAME +.Nm dwarf_producer_init +.Nm dwarf_producer_init_b +.Nd allocate a DWARF producer descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_P_Debug +.Fo dwarf_producer_init +.Fa "Dwarf_Unsigned flags" +.Fa "Dwarf_Callback_Func func" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Error *err" +.Fc +.Ft Dwarf_P_Debug +.Fo dwarf_producer_init_b +.Fa "Dwarf_Unsigned flags" +.Fa "Dwarf_Callback_Func_b func" +.Fa "Dwarf_Handler errhand" +.Fa "Dwarf_Ptr errarg" +.Fa "Dwarf_Error *error" +.Fc +.Sh DESCRIPTION +These functions allocate and return a +.Vt Dwarf_P_Debug +descriptor representing a DWARF producer instance. +.Pp +The argument +.Ar errhand +should contain the adddress of a function to be called in case of an +error. +If this argument is +.Dv NULL , +the default error handling scheme is used, see +.Xr dwarf 3 . +.Pp +The argument +.Ar errarg +will be passed to the error handler function when it is invoked. +.Pp +The argument +.Ar err +references a memory location that would hold a +.Vt Dwarf_Error +descriptor in case of an error. +.Pp +The argument +.Ar flags +specifies additional characteristics of the DWARF producer instance. +The following flags are recognized: +.Pp +.Bl -tag -width "Dv DW_DLC_ISA_MIPS" +.It Dv DW_DLC_ISA_IA64 +.Pq Deprecated +The target instruction set architecture is IA64. +This flag is deprecated. +Application code should use the +.Xr dwarf_producer_set_isa 3 +function to specify target instruction set architecture. +.It Dv DW_DLC_ISA_MIPS +.Pq Deprecated +The target instruction set architecture is MIPS. +This flag is deprecated. +Application code should use the +.Xr dwarf_producer_set_isa 3 +function to specify target instruction set architecture. +.It Dv DW_DLC_SIZE_32 +.Pq Default +The target address size is 32-bit. +.It Dv DW_DLC_SIZE_64 +The target address size is 64-bit. +.It Dv DW_DLC_STREAM_RELOCATIONS +.Pq Default +Generate stream relocations. +.It Dv DW_DLC_SYMBOLIC_RELOCATIONS +Generate symbolic relocations. +.It Dv DW_DLC_TARGET_BIGENDIAN +The target is big endian. +.It Dv DW_DLC_TARGET_LITTLEENDIAN +The target is little endian. +.It Dv DW_DLC_WRITE +.Pq Required +Permit writing of DWARF information. +.El +.Pp +The following flags are mutually exclusive. +.Bl -bullet -compact +.It +Flags +.Dv DW_DLC_ISA_IA64 +and +.Dv DW_DLC_ISA_MIPS . +.It +Flags +.Dv DW_DLC_SIZE_32 +and +.Dv DW_DLC_SIZE_64 . +.It +Flags +.Dv DW_DLC_STREAM_RELOCATIONS +and +.Dv DW_DLC_SYMBOLIC_RELOCATIONS . +.It +Flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN . +.El +If neither of the flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN +is set, the target's endianness is assumed to be the same as the host's +endianness. +.Pp +Argument +.Ar func +should point to an application-provided callback function of type +.Vt Dwarf_Callback_Func_b . +The type +.Vt Dwarf_Callback_Func_b +is defined in the header file +.In libdwarf.h +as: +.Bd -literal -offset indent +typedef int (*Dwarf_Callback_Func_b)(char *name, int size, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Unsigned *index, int *error); +.Ed +.Pp +This function is called by the +.Lb libdwarf +once for each section in the object file that the library needs to +create. +The arguments to this callback function specify the values in the ELF +section header for the section being created: +.Pp +.Bl -tag -width indent -compact -offset indent +.It Ar name +The name of the section being created. +.It Ar size +The +.Va sh_size +value in the section header. +.It Ar type +The +.Va sh_type +value in the section header. +.It Ar flags +The +.Va sh_flags +value in the section header. +.It Ar link +The +.Va sh_link +value in the section header. +.It Ar info +The +.Va sh_info +value in the section header. +.El +.Pp +On success, the callback function should return the section index +value of the created section, and set the location pointed to by +argument +.Ar index +to the symbol table index of the symbol that associated with the newly +created section. +This symbol table index will be used in relocation entries +referring to the created section. +.Pp +In case of failure, the callback function should return -1 and set the +location pointed to by argument +.Ar error +to an application-defined error code. +This application returned error code is currently ignored by the +library. +.Pp +Function +.Fn dwarf_producer_init +is deprecated. +Function +.Fn dwarf_producer_init +is identical to function +.Fn dwarf_producer_init_b +except that the callback function it expects can not properly handle +arbitrary section symbol index values. +.Ss Memory Management +The +.Vt Dwarf_P_Debug +instance returned by these functions should be freed using the +function +.Fn dwarf_producer_finish . +.Sh RETURN VALUES +On success, these functions return the created DWARF producer +descriptor. +In case of an error, they return +.Dv DW_DLV_BADADDR +and set the argument +.Ar err . +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar func +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The flag +.Dv DW_DLC_WRITE +was not set in argument +.Ar flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_SIZE_32 +and +.Dv DW_DLC_SIZE_64 +were both set in argument +.Ar flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_ISA_IA64 +and +.Dv DW_DLC_ISA_MIPS +were both set in argument +.Ar flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_TARGET_BIGENDIAN +and +.Dv DW_DLC_TARGET_LITTLEENDIAN +were both set in argument +.Ar flags . +.It Bq Er DW_DLE_ARGUMENT +The flags +.Dv DW_DLC_STREAM_RELOCATIONS +and +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +were both set in argument +.Ar flags . +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered. +.El +.Sh EXAMPLES +To initialize a +.Vt Dwarf_P_Debug +instance for a MIPS32 big endian object, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Unsigned flags; +Dwarf_Error de; + +/* ... assume cb_func points to the callback function ... */ + +flags = DW_DLC_WRITE | DW_DLC_SIZE_32 | DW_DLC_ISA_MIPS | + DW_DLC_STREAM_RELOCATIONS | DW_DLC_TARGET_BIGENDIAN; +if ((dbg = dwarf_producer_init(flags, cb_func, NULL, NULL, &de)) == + DW_DLV_BADADDR) + warnx("dwarf_producer_init failed: %s", dwarf_errmsg(-1)); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_errmsg 3 , +.Xr dwarf_producer_finish 3 , +.Xr dwarf_producer_set_isa 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 b/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 new file mode 100644 index 0000000..fc8a31f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 @@ -0,0 +1,98 @@ +.\" Copyright (c) 2011 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_producer_set_isa.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" +.Dd September 29, 2011 +.Os +.Dt DWARF_PRODUCER_SET_ISA 3 +.Sh NAME +.Nm dwarf_producer_set_isa +.Nd specify the instruction set architecture for a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_producer_set_isa +.Fa "Dwarf_P_Debug dbg" +.Fa "enum Dwarf_ISA isa" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +The function +.Fn dwarf_producer_set_isa +sets the instruction set architecture for a DWARF producer instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using one of +the functions +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar isa +specifies the desired instruction set architecture. +Legal values for this argument are those defined by the +.Vt "enum Dwarf_ISA" +enumeration defined in the header file +.In libdwarf.h . +.Pp +If the argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh COMPATIBILITY +The +.Fn dwarf_producer_set_isa +function is a local extension. +.Sh RETURN VALUES +On success, the function +.Fn dwarf_producer_set_isa +returns +.Dv DW_DLV_OK . +In case of an error, this function returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +The +.Fn dwarf_producer_set_isa +function can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +The argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The argument +.Ar isa +was invalid. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 b/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 new file mode 100644 index 0000000..c397106 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pubnames.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pubnames.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(global,Global,glob,pubnames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 b/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 new file mode 100644 index 0000000..5188ea7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_pubtypes.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_pubtypes.m4 2074 2011-10-27 03:34:33Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(pubtype,Type,pubtype,pubtypes) diff --git a/contrib/elftoolchain/libdwarf/dwarf_ranges.c b/contrib/elftoolchain/libdwarf/dwarf_ranges.c new file mode 100644 index 0000000..9ad6083 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_ranges.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_ranges.c 2075 2011-10-27 03:47:28Z jkoshy $"); + +static int +_dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off off, + Dwarf_Ranges **ranges, Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, + Dwarf_Error *error) +{ + Dwarf_Rangelist rl; + int ret; + + assert(cu != NULL); + if (_dwarf_ranges_find(dbg, off, &rl) == DW_DLE_NO_ENTRY) { + ret = _dwarf_ranges_add(dbg, cu, off, &rl, error); + if (ret != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + *ranges = rl->rl_rgarray; + *ret_cnt = rl->rl_rglen; + + if (ret_byte_cnt != NULL) + *ret_byte_cnt = cu->cu_pointer_size * rl->rl_rglen * 2; + + return (DW_DLV_OK); +} + +int +dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Ranges **ranges, + Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, Dwarf_Error *error) +{ + + if (dbg == NULL || ranges == NULL || ret_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if (!dbg->dbg_info_loaded) { + if (_dwarf_info_load(dbg, 1, error) != DW_DLE_NONE) + return (DW_DLV_ERROR); + } + + return (_dwarf_get_ranges(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, + ranges, ret_cnt, ret_byte_cnt, error)); +} + +int +dwarf_get_ranges_a(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die die, + Dwarf_Ranges **ranges, Dwarf_Signed *ret_cnt, Dwarf_Unsigned *ret_byte_cnt, + Dwarf_Error *error) +{ + + if (dbg == NULL || die == NULL || ranges == NULL || ret_cnt == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + return (_dwarf_get_ranges(dbg, die->die_cu, offset, ranges, ret_cnt, + ret_byte_cnt, error)); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_reloc.c b/contrib/elftoolchain/libdwarf/dwarf_reloc.c new file mode 100644 index 0000000..5e96db3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_reloc.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_reloc.c 2075 2011-10-27 03:47:28Z jkoshy $"); + +int +dwarf_set_reloc_application(int apply) +{ + int oldapply; + + oldapply = _libdwarf.applyrela; + _libdwarf.applyrela = apply; + + return (oldapply); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 b/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 new file mode 100644 index 0000000..702d568 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 @@ -0,0 +1,69 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_reset_section_bytes.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd September 3, 2011 +.Os +.Dt DWARF_RESET_SECTION_BYTES 3 +.Sh NAME +.Nm dwarf_reset_section_bytes +.Nd reset the internal state of a producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft void +.Fo dwarf_reset_section_bytes +.Fa "Dwarf_P_Debug dbg" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_reset_section_bytes +resets the internal state of a DWARF producer instance, so that the +next call to the function +.Xr dwarf_get_section_bytes 3 +will return the byte stream for the first generated section, and +the next call to the function +.Xr dwarf_get_relocation_info 3 +will return the first relocation array for the DWARF producer +instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_reset_section_bytes +has no return value. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_get_section_bytes 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_transform_to_disk_form 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 b/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 new file mode 100644 index 0000000..c3d9c48 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 @@ -0,0 +1,140 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_set_frame_cfa_value.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd June 18, 2011 +.Os +.Dt DWARF_SET_FRAME_CFA_VALUE 3 +.Sh NAME +.Nm dwarf_set_frame_cfa_value , +.Nm dwarf_set_frame_rule_initial_value , +.Nm dwarf_set_frame_rule_table_size , +.Nm dwarf_set_frame_same_value , +.Nm dwarf_set_frame_undefined_value +.Nd set internal register rule table parameters +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Half +.Fo dwarf_set_frame_cfa_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_rule_initial_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_rule_table_size +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_same_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Ft Dwarf_Half +.Fo dwarf_set_frame_undefined_value +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Half value" +.Fc +.Sh DESCRIPTION +These functions set the parameters of the internal register +rule table. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +.Pp +Argument +.Ar value +should hold the parameter value to set. +.Pp +Function +.Fn dwarf_set_frame_cfa_value +sets the column number for the CFA register rule in the internal +register rule table. +The constant +.Dv DW_FRAME_CFA_COL +is the default CFA register column number for DWARF2-only +interfaces, and the constant +.Dv DW_FRAME_CFA_COL3 +is the default CFA column number for DWARF3-compatible interfaces. +.Pp +Function +.Fn dwarf_set_frame_rule_initial_value +sets the initial value of the register rules in the internal register +rule table. +The default initial value is the constant +.Dv DW_FRAME_REG_INITIAL_VALUE , +defined in the header file +.In libdwarf.h . +.Pp +Function +.Fn dwarf_set_frame_rule_table_size +sets the maxmium number of columns of the internal register rule table. +Argument +.Ar value +should be at least as large as the number of real registers in the ABI. +.Pp +Function +.Fn dwarf_set_frame_same_value +sets the register number representing the +.Dq "same value" +register rule. +The default register number for the +.Dq "same value" +rule is the constant +.Dv DW_FRAME_SAME_VAL , +defined in the header file +.In libdwarf.h . +.Pp +Function +.Fn dwarf_set_frame_undefined_value +sets the register number representing the +.Dq undefined +register rule. +The default register number for the +.Dq undefined +rule is the constant +.Dv DW_FRAME_UNDEFINED_VAL , +defined in the header file +.In libdwarf.h . +.Sh RETURN VALUES +These functions return the previous value of the parameter being +set. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_fde_at_pc 3 , +.Xr dwarf_get_fde_info_for_all_regs 3 , +.Xr dwarf_get_fde_info_for_all_regs3 3 , +.Xr dwarf_get_fde_info_for_cfa_reg3 3 , +.Xr dwarf_get_fde_info_for_reg 3 , +.Xr dwarf_get_fde_info_for_reg3 3 , +.Xr dwarf_get_fde_n 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 new file mode 100644 index 0000000..d53c746 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 @@ -0,0 +1,80 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_set_reloc_application.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd June 26, 2011 +.Os +.Dt DWARF_SET_RELOC_APPLICATION 3 +.Sh NAME +.Nm dwarf_set_reloc_application +.Nd set a library-wide relocation flag +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_set_reloc_application +.Fa "int apply" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_set_reloc_application +allows applications to specify how relocation information is to be +handled by the DWARF(3) library. +.Pp +If the argument +.Ar apply +holds a non-zero value, the library will process all the relevant +.Dq ".rela" +relocation sections and will apply the relocation records found to +their corresponding DWARF sections. +.Pp +If the argument +.Ar apply +is zero, the library will not attempt to apply any relocations. +.Pp +The default behaviour of the library is to process relocation records. +.Sh NOTES +Function +.Fn dwarf_set_reloc_application +should be called before initialising a dwarf debugging context, i.e, +it should be called by the application before calling either of the +functions +.Xr dwarf_init 3 +or +.Xr dwarf_elf_init 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_set_reloc_application +returns the previous value of the library-wide relocation application +flag. +.Sh ERRORS +Function +.Fn dwarf_set_reloc_application +does not return an error. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_elf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 b/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 new file mode 100644 index 0000000..55d78d9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_seterrarg.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd May 01, 2010 +.Os +.Dt DWARF_SETERRARG 3 +.Sh NAME +.Nm dwarf_seterrarg , +.Nm dwarf_seterrhand +.Nd configure error handling +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Ptr +.Fn dwarf_seterrarg "Dwarf_Debug dbg" "Dwarf_Ptr arg" +.Ft Dwarf_Handler +.Fn dwarf_seterrhand "Dwarf_Debug dbg" "Dwarf_Handler handler" +.Sh DESCRIPTION +These functions may be used by applications to configure error handling +callbacks. +The error handling scheme used by the library is described in +.Xr dwarf 3 . +.Pp +Function +.Fn dwarf_seterrarg +may be used to set the callback argument passed to a configured +error handler at the time it is invoked. +Argument +.Ar arg +is the callback argument being set. +Argument +.Ar dbg +can be a debug context allocated by a prior call to +.Xr dwarf_init 3 , +or can be NULL to indicate that the library-wide callback argument +is to be set. +.Pp +Function +.Fn dwarf_seterrhand +may be used to associate an error handler denoted by argument +.Ar handler +with the DWARF debug context descriptor denoted by argument +.Ar dbg . +Argument +.Ar dbg +should be a debug context allocated by a prior call to +.Xr dwarf_init 3 , +or may be NULL to indicate that the library-wide error handler +is to be set. +.Sh RETURN VALUES +Function +.Fn dwarf_seterrhand +returns the previous error handler associated with argument +.Ar dbg . +If argument +.Ar dbg +is NULL, function +.Fn dwarf_seterrhand +returns the previous library-wide error handler. +.Pp +Function +.Fn dwarf_seterrarg +returns the previous callback argument associated with argument +.Ar dbg . +If argument +.Ar dbg +is NULL, function +.Fn dwarf_seterrarg +returns the previous library-wide callback argument. +.Pp +.Sh COMPATIBILITY +The behavior of these functions when argument +.Ar dbg +is NULL is a local extension. +.Sh ERRORS +These functions do not set an error code. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_seterror.c b/contrib/elftoolchain/libdwarf/dwarf_seterror.c new file mode 100644 index 0000000..da23cdb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_seterror.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_seterror.c 2075 2011-10-27 03:47:28Z jkoshy $"); + +#define _SET_FIELD(R, F, V) \ + do { \ + (R) = (F); \ + (F) = (V); \ + } while (0) + +#define SET_FIELD(D, R, F) \ + do { \ + if (D) \ + _SET_FIELD(R, (D)->dbg_##F, F); \ + else \ + _SET_FIELD(R, _libdwarf.F, F); \ + } while (0) + +Dwarf_Handler +dwarf_seterrhand(Dwarf_Debug dbg, Dwarf_Handler errhand) +{ + Dwarf_Handler oldhandler; + + SET_FIELD(dbg, oldhandler, errhand); + + return (oldhandler); +} + +Dwarf_Ptr +dwarf_seterrarg(Dwarf_Debug dbg, Dwarf_Ptr errarg) +{ + Dwarf_Ptr oldarg; + + SET_FIELD(dbg, oldarg, errarg); + + return (oldarg); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 b/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 new file mode 100644 index 0000000..906bb92 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 @@ -0,0 +1,105 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_srcfiles.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd April 28, 2010 +.Os +.Dt DWARF_SRCFILES 3 +.Sh NAME +.Nm dwarf_srcfiles +.Nd retrieve source file information +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_srcfiles +.Fa "Dwarf_Die die" +.Fa "char ***filenames" +.Fa "Dwarf_Signed *filenamecount" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_srcfiles +returns the source file names associated with a compilation unit. +Source file names are returned as an array of NUL-terminated strings. +.Pp +Argument +.Ar die +should reference a DWARF debugging information entry descriptor with +source file information, see +.Xr dwarf 3 . +Argument +.Ar filenames +should point to a location that will hold a pointer to the returned array +of file names. +Argument +.Ar filenamecount +should point to a location that will hold the number of file names returned. +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Ss Memory Management +The memory areas used for the file names and for array of pointers +being returned are managed by the DWARF(3) library. +The application should not attempt to directly free these memory areas. +Portable code should indicate that the memory areas are to be freed +by using +.Xr dwarf_dealloc 3 . +.Sh RETURN VALUES +Function +.Fn dwarf_srcfiles +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_srcfiles +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar die , +.Ar filenames +or +.Ar filenamecount +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The compilation unit referenced by argument +.Ar die +does not have associated source file information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_dealloc 3 , +.Xr dwarf_srclines 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_srclines.3 b/contrib/elftoolchain/libdwarf/dwarf_srclines.3 new file mode 100644 index 0000000..0f8d830 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_srclines.3 @@ -0,0 +1,163 @@ +.\" Copyright (c) 2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: dwarf_srclines.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_SRCLINES 3 +.Sh NAME +.Nm dwarf_srclines +.Nd retrieve line number information for a debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_srclines +.Fa "Dwarf_Die die" +.Fa "Dwarf_Line **lines" +.Fa "Dwarf_Signed *nlines" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_srclines +returns line number information associated with a compilation unit. +Line number information is returned as an array of +.Vt Dwarf_Line +descriptors. +.Pp +Argument +.Ar die +should reference a DWARF debugging information entry descriptor +with line number information, see +.Xr dwarf 3 . +Argument +.Ar lines +should point to a location that will hold a pointer to the returned array +of +.Vt Dwarf_Line +descriptors. +Argument +.Ar nlines +should point to a location that will hold the number of descriptors +returned. +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +The returned +.Vt Dwarf_Line +descriptors may be passed to the other line number functions in the +API set to retrieve specific information about each source line. +.Ss Memory Management +The memory area used for the array of +.Vt Dwarf_Line +descriptors returned in argument +.Ar lines +is owned by the +.Lb libdwarf . +The application should not attempt to free this pointer. +Portable code should instead use +.Fn dwarf_srclines_dealloc +to indicate that the memory may be freed. +.Sh RETURN VALUES +Function +.Fn dwarf_srclines +returns +.Dv DW_DLV_OK +when it succeeds. +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_srclines +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar die , +.Ar lines +or +.Ar nlines +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The compilation unit referenced by argument +.Ar die +does not have associated line number information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El +.Sh EXAMPLE +To obtain an array of +.Vt Dwarf_Line +descriptors and to retrieve the source file, line number, and virtual address +associated with each descriptor: +.Bd -literal -offset indent +int n; +Dwarf_Die die; +Dwarf_Error de; +char *filename; +Dwarf_Line *lines; +Dwarf_Signed nlines; +Dwarf_Addr lineaddr; +Dwarf_Unsigned lineno; + +/* variable "die" should reference a DIE for a compilation unit */ + +if (dwarf_srclines(die, &lines, &nlines, &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_srclines: %s", dwarf_errmsg(de)); + +for (n = 0; n < nlines; n++) { + /* Retrieve the file name for this descriptor. */ + if (dwarf_linesrc(lines[n], &filename, &de)) + errx(EXIT_FAILURE, "dwarf_linesrc: %s", + dwarf_errmsg(de)); + + /* Retrieve the line number in the source file. */ + if (dwarf_lineno(lines[n], &lineno, &de)) + errx(EXIT_FAILURE, "dwarf_lineno: %s", + dwarf_errmsg(de)); + /* Retrieve the virtual address for this line. */ + if (dwarf_lineaddr(lines[n], &lineaddr, &de)) + errx(EXIT_FAILURE, "dwarf_lineaddr: %s", + dwarf_errmsg(de)); + } +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_line_srcfileno 3 , +.Xr dwarf_lineaddr 3 , +.Xr dwarf_linebeginstatement 3 , +.Xr dwarf_lineblock 3 , +.Xr dwarf_lineendsequence 3 , +.Xr dwarf_lineno 3 , +.Xr dwarf_lineoff 3 , +.Xr dwarf_linesrc 3 , +.Xr dwarf_srcfiles 3 , +.Xr dwarf_srclines_dealloc 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 b/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 new file mode 100644 index 0000000..1e821d7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 @@ -0,0 +1,106 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_start_macro_file.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd September 25, 2011 +.Os +.Dt DWARF_START_MACRO_FILE 3 +.Sh NAME +.Nm dwarf_start_macro_file +.Nd mark the start of a source file inclusion +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_start_macro_file +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "Dwarf_Unsigned fileindex" +.Fa "Dwarf_Error *err" +.Fa +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_start_macro_file +marks the start of a new source file inclusion. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar lineno +specifies the line number of the source line where the source +file inclusion occurs. +A value of zero is used to indicate the file for the compilation unit +source itself. +.Pp +Argument +.Ar fileindex +specifies the index of the source file that is being included. +Valid source file indices are those returned by +.Xr dwarf_add_file_decl 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_start_macro_file +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_start_macro_file +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_start_macro_file +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_add_file_decl 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_undef_macro 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_str.c b/contrib/elftoolchain/libdwarf/dwarf_str.c new file mode 100644 index 0000000..71a7f75 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_str.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_str.c 2075 2011-10-27 03:47:28Z jkoshy $"); + +int +dwarf_get_str(Dwarf_Debug dbg, Dwarf_Off offset, char **string, + Dwarf_Signed *ret_strlen, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if (dbg == NULL || offset < 0 || string == NULL || ret_strlen == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + ds = _dwarf_find_section(dbg, ".debug_str"); + if (ds == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + if ((Dwarf_Unsigned) offset > ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + if ((Dwarf_Unsigned) offset == ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + *string = (char *) ds->ds_data + offset; + *ret_strlen = strlen(*string); + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/dwarf_tag.3 b/contrib/elftoolchain/libdwarf/dwarf_tag.3 new file mode 100644 index 0000000..bb49a49 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_tag.3 @@ -0,0 +1,77 @@ +.\" Copyright (c) 2010 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_tag.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd April 14, 2010 +.Os +.Dt DWARF_TAG 3 +.Sh NAME +.Nm dwarf_tag +.Nd retrieve the tag associated with a DWARF debugging information entry +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fn dwarf_tag "Dwarf_Die die" "Dwarf_Half *tag" "Dwarf_Error *err" +.Sh DESCRIPTION +Function +.Fn dwarf_tag +retrieves the tag associated with the debugging information entry +referenced by argument +.Ar die , +and stores it into the location pointed to by argument +.Ar tag . +.Pp +If argument +.Ar err +if non-NULL, it will be used to return an error descriptor in case of +an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_tag +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_tag +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va die +or +.Va tag +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_die_abbrev_code 3 , +.Xr dwarf_diename 3 , +.Xr dwarf_dieoffset 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 b/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 new file mode 100644 index 0000000..54896ca --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 @@ -0,0 +1,99 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_transform_to_disk_form.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd August 25, 2011 +.Os +.Dt DWARF_TRANSFORM_TO_DISK_FORM 3 +.Sh NAME +.Nm dwarf_transform_to_disk_form +.Nd transform DWARF information into byte streams +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Signed +.Fo dwarf_transform_to_disk_form +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_transform_to_disk_form +transforms the DWARF information gathered by the producer into +byte streams for the application to write out as ELF sections. +If the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +is set on the producer, the function will also generate the associated +relocation arrays. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case +of an error. +.Pp +After a call to this function, the application can call the function +.Xr dwarf_get_section_bytes 3 +to retrieve the byte streams for each ELF section. +If the flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was set on the descriptor, the application can also call the function +.Xr dwarf_get_relocation_info 3 +to retrieve the generated relocation arrays. +.Sh RETURN VALUES +On success, function +.Fn dwarf_transform_to_disk_form +returns the total number of ELF sections generated. +In case of an error, function +.Fn dwarf_transform_to_disk_form +returns +.Dv DW_DLV_NOCOUNT +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_transform_to_disk_form +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during execution. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_get_relocation_info 3 , +.Xr dwarf_get_section_bytes 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_types.m4 b/contrib/elftoolchain/libdwarf/dwarf_types.m4 new file mode 100644 index 0000000..ddab7f1 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_types.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_types.m4 2697 2012-11-24 17:12:36Z kaiwang27 $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(type,Type,type,typenames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 b/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 new file mode 100644 index 0000000..b787289 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 @@ -0,0 +1,119 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_undef_macro.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt DWARF_UNDEF_MACRO 3 +.Sh NAME +.Nm dwarf_undef_macro +.Nd record the removal of a macro definition +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_undef_macro +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned lineno" +.Fa "char *name" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_undef_macro +records the removal of a macro definition in a DWARF producer +instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar lineno +specifies the line number of the source line where the macro +definition was removed. +A value of zero indicates that the macro definition was removed before +any source files were read. +.Pp +Argument +.Ar name +should point to a NUL-terminated string containing the name +of the macro. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_undef_macro +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_undef_macro +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh EXAMPLE +To record the fact that the macro named +.Dv _STDIO_H_ +was removed at line 220 of the current macro file, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Error de; + +/* ... Assume 'dbg' refers to a DWARF producer instance... */ +if (dwarf_undef_macro(dbg, 220, "_STDIO_H_", &de) != DW_DLV_OK) + errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", + dwarf_errmsg(-1)); +.Ed +.Sh ERRORS +Function +.Fn dwarf_undef_macro +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Ar dbg +or +.Ar name +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_vendor_ext 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_vars.m4 b/contrib/elftoolchain/libdwarf/dwarf_vars.m4 new file mode 100644 index 0000000..b512fdf --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_vars.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_vars.m4 2075 2011-10-27 03:47:28Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(var,Var,var,static_vars) diff --git a/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 b/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 new file mode 100644 index 0000000..c7ae56f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 @@ -0,0 +1,110 @@ +.\" Copyright (c) 2011 Kai Wang +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_vendor_ext.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd September 25, 2011 +.Os +.Dt DWARF_VENDOR_EXT 3 +.Sh NAME +.Nm dwarf_vendor_ext +.Nd add vendor-specific macro information to a DWARF producer instance +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft "int" +.Fo dwarf_vendor_ext +.Fa "Dwarf_P_Debug dbg" +.Fa "Dwarf_Unsigned constant" +.Fa "char *string" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_vendor_ext +adds a vendor-specific macro information entry to a DWARF producer +instance. +.Pp +Argument +.Ar dbg +should reference a DWARF producer instance allocated using +.Xr dwarf_producer_init 3 +or +.Xr dwarf_producer_init_b 3 . +.Pp +Argument +.Ar constant +specifies a constant value for the macro information entry. +.Pp +Argument +.Ar string +point to a NUL-terminated string containing the string value +for the macro information entry. +.Pp +If argument +.Ar err +is not NULL, it will be used to store error information in case of an +error. +.Pp +The meaning of the arguments +.Ar constant +and +.Ar string +are not defined by the DWARF specification, but are instead governed +by application and vendor conventions. +.Sh RETURN VALUES +On success, function +.Fn dwarf_vendor_ext +returns +.Dv DW_DLV_OK . +In case of an error, function +.Fn dwarf_vendor_ext +returns +.Dv DW_DLV_ERROR +and sets the argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_vendor_ext +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either arguments +.Ar dbg +or +.Ar string +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_def_macro 3 , +.Xr dwarf_end_macro_file 3 , +.Xr dwarf_producer_init 3 , +.Xr dwarf_producer_init_b 3 , +.Xr dwarf_start_macro_file 3 , +.Xr dwarf_undef_macro 3 diff --git a/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 b/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 new file mode 100644 index 0000000..7ae335e --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_weaks.m4 @@ -0,0 +1,36 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: dwarf_weaks.m4 2075 2011-10-27 03:47:28Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) +include(SRCDIR`/dwarf_nametbl.m4') +divert(0) +MAKE_NAMETBL_API(weak,Weak,weak,weaknames) diff --git a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 new file mode 100644 index 0000000..7c9a6d0 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 @@ -0,0 +1,78 @@ +.\" Copyright (c) 2010 Joseph Koshy +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: dwarf_whatattr.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" +.Dd May 22, 2010 +.Os +.Dt DWARF_WHATATTR 3 +.Sh NAME +.Nm dwarf_whatattr +.Nd retrieve the attribute code for a DWARF attribute +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_whatattr +.Fa "Dwarf_Attribute attr" +.Fa "Dwarf_Half *retcode" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_whatattr +retrieves the attribute code for the DWARF attribute referenced +by argument +.Ar attr , +and writes it to the location pointed to by argument +.Ar retcode . +If argument +.Ar err +is not NULL, it will be used to return an error descriptor in case +of an error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_whatattr +returns +.Dv DW_DLV_OK . +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh ERRORS +Function +.Fn dwarf_whatattr +can fail with the following error: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of argument +.Va attr +or +.Va retcode +was NULL. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 , +.Xr dwarf_hasattr 3 diff --git a/contrib/elftoolchain/libdwarf/libdwarf.c b/contrib/elftoolchain/libdwarf/libdwarf.c new file mode 100644 index 0000000..5f48762 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +struct _libdwarf_globals _libdwarf = { + .errhand = NULL, + .errarg = NULL, + .applyrela = 1 +}; diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h new file mode 100644 index 0000000..105a0e7 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf.h @@ -0,0 +1,808 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: libdwarf.h 2576 2012-09-13 09:16:11Z jkoshy $ + */ + +#ifndef _LIBDWARF_H_ +#define _LIBDWARF_H_ + +#include <libelf.h> + +typedef int Dwarf_Bool; +typedef off_t Dwarf_Off; +typedef uint64_t Dwarf_Unsigned; +typedef uint16_t Dwarf_Half; +typedef uint8_t Dwarf_Small; +typedef int64_t Dwarf_Signed; +typedef uint64_t Dwarf_Addr; +typedef void *Dwarf_Ptr; + +typedef struct _Dwarf_Abbrev *Dwarf_Abbrev; +typedef struct _Dwarf_Arange *Dwarf_Arange; +typedef struct _Dwarf_ArangeSet *Dwarf_ArangeSet; +typedef struct _Dwarf_Attribute *Dwarf_Attribute; +typedef struct _Dwarf_Attribute *Dwarf_P_Attribute; +typedef struct _Dwarf_AttrDef *Dwarf_AttrDef; +typedef struct _Dwarf_CU *Dwarf_CU; +typedef struct _Dwarf_Cie *Dwarf_Cie; +typedef struct _Dwarf_Cie *Dwarf_P_Cie; +typedef struct _Dwarf_Debug *Dwarf_Debug; +typedef struct _Dwarf_Debug *Dwarf_P_Debug; +typedef struct _Dwarf_Die *Dwarf_Die; +typedef struct _Dwarf_Die *Dwarf_P_Die; +typedef struct _Dwarf_Fde *Dwarf_Fde; +typedef struct _Dwarf_Fde *Dwarf_P_Fde; +typedef struct _Dwarf_FrameSec *Dwarf_FrameSec; +typedef struct _Dwarf_Line *Dwarf_Line; +typedef struct _Dwarf_LineFile *Dwarf_LineFile; +typedef struct _Dwarf_LineInfo *Dwarf_LineInfo; +typedef struct _Dwarf_Loclist *Dwarf_Loclist; +typedef struct _Dwarf_MacroSet *Dwarf_MacroSet; +typedef struct _Dwarf_NamePair *Dwarf_NamePair; +typedef struct _Dwarf_NamePair *Dwarf_Func; +typedef struct _Dwarf_NamePair *Dwarf_Global; +typedef struct _Dwarf_NamePair *Dwarf_Type; +typedef struct _Dwarf_NamePair *Dwarf_Var; +typedef struct _Dwarf_NamePair *Dwarf_Weak; +typedef struct _Dwarf_NameTbl *Dwarf_NameTbl; +typedef struct _Dwarf_NameSec *Dwarf_NameSec; +typedef struct _Dwarf_P_Expr *Dwarf_P_Expr; +typedef struct _Dwarf_Rangelist *Dwarf_Rangelist; + +typedef enum { + DW_OBJECT_MSB, + DW_OBJECT_LSB +} Dwarf_Endianness; + +typedef struct { + Dwarf_Addr addr; + Dwarf_Unsigned size; + const char *name; +} Dwarf_Obj_Access_Section; + +typedef struct { + int (*get_section_info)(void *_obj, Dwarf_Half _index, + Dwarf_Obj_Access_Section *_ret_section, int *_error); + Dwarf_Endianness (*get_byte_order)(void *_obj); + Dwarf_Small (*get_length_size)(void *_obj); + Dwarf_Small (*get_pointer_size)(void *_obj); + Dwarf_Unsigned (*get_section_count)(void *_obj); + int (*load_section)(void *_obj, Dwarf_Half _index, + Dwarf_Small **_ret_data, int *_error); +} Dwarf_Obj_Access_Methods; + +typedef struct { + void *object; + const Dwarf_Obj_Access_Methods *methods; +} Dwarf_Obj_Access_Interface; + +typedef int (*Dwarf_Callback_Func)(char *_name, int _size, + Dwarf_Unsigned _type, Dwarf_Unsigned _flags, Dwarf_Unsigned _link, + Dwarf_Unsigned _info, int *_index, int *_error); + +typedef int (*Dwarf_Callback_Func_b)(char *_name, int _size, + Dwarf_Unsigned _type, Dwarf_Unsigned _flags, Dwarf_Unsigned _link, + Dwarf_Unsigned _info, Dwarf_Unsigned *_index, int *_error); + +typedef Dwarf_Unsigned Dwarf_Tag; + +typedef struct { + Dwarf_Small lr_atom; + Dwarf_Unsigned lr_number; + Dwarf_Unsigned lr_number2; + Dwarf_Unsigned lr_offset; +} Dwarf_Loc; + +typedef struct { + Dwarf_Addr ld_lopc; + Dwarf_Addr ld_hipc; + Dwarf_Half ld_cents; + Dwarf_Loc *ld_s; +} Dwarf_Locdesc; + +typedef struct { + char signature[8]; +} Dwarf_Sig8; + +typedef struct { + Dwarf_Unsigned bl_len; + Dwarf_Ptr bl_data; +} Dwarf_Block; + +enum Dwarf_Ranges_Entry_Type { + DW_RANGES_ENTRY, + DW_RANGES_ADDRESS_SELECTION, + DW_RANGES_END +}; + +typedef struct { + Dwarf_Unsigned dwr_addr1; + Dwarf_Unsigned dwr_addr2; + enum Dwarf_Ranges_Entry_Type dwr_type; +} Dwarf_Ranges; + +enum Dwarf_Form_Class { + DW_FORM_CLASS_UNKNOWN, + DW_FORM_CLASS_ADDRESS, + DW_FORM_CLASS_BLOCK, + DW_FORM_CLASS_CONSTANT, + DW_FORM_CLASS_EXPRLOC, + DW_FORM_CLASS_FLAG, + DW_FORM_CLASS_LINEPTR, + DW_FORM_CLASS_LOCLISTPTR, + DW_FORM_CLASS_MACPTR, + DW_FORM_CLASS_RANGELISTPTR, + DW_FORM_CLASS_REFERENCE, + DW_FORM_CLASS_STRING +}; + +#ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER +#define DW_FRAME_HIGHEST_NORMAL_REGISTER 63 +#endif + +#define DW_FRAME_RA_COL (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1) +#define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2) + +#ifndef DW_FRAME_LAST_REG_NUM +#define DW_FRAME_LAST_REG_NUM (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3) +#endif + +#ifndef DW_FRAME_REG_INITIAL_VALUE +#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL +#endif + +#define DW_FRAME_UNDEFINED_VAL 1034 +#define DW_FRAME_SAME_VAL 1035 +#define DW_FRAME_CFA_COL3 1436 + +#define DW_EXPR_OFFSET 0 +#define DW_EXPR_VAL_OFFSET 1 +#define DW_EXPR_EXPRESSION 2 +#define DW_EXPR_VAL_EXPRESSION 3 + +/* + * Frame operation only for DWARF 2. + */ + +#define DW_FRAME_CFA_COL 0 + +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Signed fp_offset; + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op; + +#ifndef DW_REG_TABLE_SIZE +#define DW_REG_TABLE_SIZE 66 +#endif + +typedef struct { + struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Half dw_regnum; + Dwarf_Addr dw_offset; + } rules[DW_REG_TABLE_SIZE]; +} Dwarf_Regtable; + +/* + * Frame operation for DWARF 3 and DWARF 2. + */ + +typedef struct { + Dwarf_Small fp_base_op; + Dwarf_Small fp_extended_op; + Dwarf_Half fp_register; + Dwarf_Unsigned fp_offset_or_block_len; + Dwarf_Small *fp_expr_block; + Dwarf_Off fp_instr_offset; +} Dwarf_Frame_Op3; + +typedef struct { + Dwarf_Small dw_offset_relevant; + Dwarf_Small dw_value_type; + Dwarf_Half dw_regnum; + Dwarf_Unsigned dw_offset_or_block_len; + Dwarf_Ptr dw_block_ptr; +} Dwarf_Regtable_Entry3; + +typedef struct { + Dwarf_Regtable_Entry3 rt3_cfa_rule; + Dwarf_Half rt3_reg_table_size; + Dwarf_Regtable_Entry3 *rt3_rules; +} Dwarf_Regtable3; + +typedef struct { + Dwarf_Off dmd_offset; + Dwarf_Small dmd_type; + Dwarf_Signed dmd_lineno; + Dwarf_Signed dmd_fileindex; + char *dmd_macro; +} Dwarf_Macro_Details; + +/* + * Symbols denoting allocation types, for use with dwarf_dealloc(3). + */ + +enum Dwarf_Allocation_Type { + DW_DLA_ABBREV, + DW_DLA_ADDR, + DW_DLA_ARANGE, + DW_DLA_ATTR, + DW_DLA_BLOCK, + DW_DLA_BOUNDS, + DW_DLA_CIE, + DW_DLA_DEBUG, + DW_DLA_DIE, + DW_DLA_ELLIST, + DW_DLA_ERROR, + DW_DLA_FDE, + DW_DLA_FRAME_BLOCK, + DW_DLA_FRAME_OP, + DW_DLA_FUNC, + DW_DLA_GLOBAL, + DW_DLA_LINE, + DW_DLA_LINEBUF, + DW_DLA_LIST, + DW_DLA_LOC, + DW_DLA_LOCDESC, + DW_DLA_LOC_BLOCK, + DW_DLA_RANGES, + DW_DLA_STRING, + DW_DLA_SUBSCR, + DW_DLA_TYPE, + DW_DLA_TYPENAME, + DW_DLA_VAR, + DW_DLA_WEAK +}; + +/* + * Relocation Type. + */ +enum Dwarf_Rel_Type { + dwarf_drt_none = 0, + dwarf_drt_data_reloc, + dwarf_drt_segment_rel, + dwarf_drt_first_of_length_pair, + dwarf_drt_second_of_length_pair +}; + +/* + * Relocation Entry. + */ +typedef struct Dwarf_Relocation_Data_s { + unsigned char drd_type; + unsigned char drd_length; + Dwarf_Unsigned drd_offset; + Dwarf_Unsigned drd_symbol_index; +} *Dwarf_Relocation_Data; + +#define DWARF_DRD_BUFFER_VERSION 2 + +/* + * Error numbers which are specific to this implementation. + */ +enum { + DW_DLE_NONE, /* No error. */ + DW_DLE_ERROR, /* An error! */ + DW_DLE_ARGUMENT, /* Invalid argument. */ + DW_DLE_DEBUG_INFO_NULL, /* Debug info NULL. */ + DW_DLE_NO_ENTRY, /* No entry. */ + DW_DLE_MEMORY, /* Insufficient memory. */ + DW_DLE_ELF, /* ELF error. */ + DW_DLE_CU_LENGTH_ERROR, /* Invalid compilation unit data. */ + DW_DLE_VERSION_STAMP_ERROR, /* Invalid version. */ + DW_DLE_DEBUG_ABBREV_NULL, /* Abbrev not found. */ + DW_DLE_DIE_NO_CU_CONTEXT, /* No current compilation unit. */ + DW_DLE_LOC_EXPR_BAD, /* Invalid location expression. */ + DW_DLE_EXPR_LENGTH_BAD, /* Invalid DWARF expression. */ + DW_DLE_DEBUG_LOC_SECTION_SHORT, /* Loclist section too short. */ + DW_DLE_ATTR_FORM_BAD, /* Invalid attribute form. */ + DW_DLE_DEBUG_LINE_LENGTH_BAD, /* Line info section too short. */ + DW_DLE_LINE_FILE_NUM_BAD, /* Invalid file number. */ + DW_DLE_DIR_INDEX_BAD, /* Invalid dir index. */ + DW_DLE_DEBUG_FRAME_LENGTH_BAD, /* Frame section too short. */ + DW_DLE_NO_CIE_FOR_FDE, /* CIE not found for certain FDE. */ + DW_DLE_FRAME_AUGMENTATION_UNKNOWN, /* Unknown CIE augmentation. */ + DW_DLE_FRAME_INSTR_EXEC_ERROR, /* Frame instruction exec error. */ + DW_DLE_FRAME_VERSION_BAD, /* Invalid frame section version. */ + DW_DLE_FRAME_TABLE_COL_BAD, /* Invalid table column. */ + DW_DLE_DF_REG_NUM_TOO_HIGH, /* Insufficient regtable space. */ + DW_DLE_PC_NOT_IN_FDE_RANGE, /* PC requested not in the FDE range. */ + DW_DLE_ARANGE_OFFSET_BAD, /* Invalid arange offset. */ + DW_DLE_DEBUG_MACRO_INCONSISTENT,/* Invalid macinfo data. */ + DW_DLE_ELF_SECT_ERR, /* Application callback failed. */ + DW_DLE_NUM /* Max error number. */ +}; + +/* + * Mapping of SGI libdwarf error codes for comptibility. + */ +#define DW_DLE_DBG_ALLOC DW_DLE_MEMORY +#define DW_DLE_ALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_SECT_ALLOC DW_DLE_MEMORY +#define DW_DLE_FILE_ENTRY_ALLOC DW_DLE_MEMORY +#define DW_DLE_LINE_ALLOC DW_DLE_MEMORY +#define DW_DLE_FPGM_ALLOC DW_DLE_MEMORY +#define DW_DLE_INCDIR_ALLOC DW_DLE_MEMORY +#define DW_DLE_STRING_ALLOC DW_DLE_MEMORY +#define DW_DLE_CHUNK_ALLOC DW_DLE_MEMORY +#define DW_DLE_CIE_ALLOC DW_DLE_MEMORY +#define DW_DLE_FDE_ALLOC DW_DLE_MEMORY +#define DW_DLE_CIE_OFFS_ALLOC DW_DLE_MEMORY +#define DW_DLE_DIE_ALLOC DW_DLE_MEMORY +#define DW_DLE_ATTR_ALLOC DW_DLE_MEMORY +#define DW_DLE_ABBREV_ALLOC DW_DLE_MEMORY +#define DW_DLE_ADDR_ALLOC DW_DLE_MEMORY +#define DW_DLE_REL_ALLOC DW_DLE_MEMORY +#define DW_DLE_MACINFO_MALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE DW_DLE_MEMORY +#define DW_DLE_DF_ALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_RELOC_SECTION_MALLOC_FAIL DW_DLE_MEMORY +#define DW_DLE_DBG_NULL DW_DLE_ARGUMENT +#define DW_DLE_DIE_NULL DW_DLE_ARGUMENT +#define DW_DLE_FDE_NULL DW_DLE_ARGUMENT +#define DW_DLE_CIE_NULL DW_DLE_ARGUMENT +#define DW_DLE_ATTR_NULL DW_DLE_ARGUMENT +#define DW_DLE_GLOBAL_NULL DW_DLE_ARGUMENT +#define DW_DLE_ARANGES_NULL DW_DLE_ARGUMENT +#define DW_DLE_ARANGE_NULL DW_DLE_ARGUMENT +#define DW_DLE_EXPR_NULL DW_DLE_ARGUMENT +#define DW_DLE_FUNC_NULL DW_DLE_ARGUMENT +#define DW_DLE_TYPE_NULL DW_DLE_ARGUMENT +#define DW_DLE_VAR_NULL DW_DLE_ARGUMENT +#define DW_DLE_WEAK_NULL DW_DLE_ARGUMENT +#define DW_DLE_ELF_BEGIN_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETEHDR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETSHDR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_STRPTR_ERROR DW_DLE_ELF +#define DW_DLE_ELF_SECT_ERROR DW_DLE_ELF +#define DW_DLE_ELF_GETIDENT_ERROR DW_DLE_ELF + +typedef struct _Dwarf_Error { + int err_error; /* DWARF error. */ + int err_elferror; /* ELF error. */ + const char *err_func; /* Function name where error occurred. */ + int err_line; /* Line number where error occurred. */ + char err_msg[1024]; /* Formatted error message. */ +} Dwarf_Error; + +/* + * Dwarf error handler. + */ +typedef void (*Dwarf_Handler)(Dwarf_Error, Dwarf_Ptr); + +#define dwarf_errno(error) error.err_error +#define dwarf_errmsg(error) dwarf_errmsg_(&error) + +/* + * Return values which have to be compatible with other + * implementations of libdwarf. + */ +#define DW_DLV_NO_ENTRY -1 +#define DW_DLV_OK 0 +#define DW_DLV_ERROR 1 +#define DW_DLV_BADADDR NULL +#define DW_DLV_NOCOUNT ((Dwarf_Signed) -1) + +/* + * Access modes. + */ +#define DW_DLC_READ 0x0001 +#define DW_DLC_WRITE 0x0002 +#define DW_DLC_RDWR 0x0004 + +/* + * Flags used by libdwarf producer. + */ +#define DW_DLC_SIZE_64 0x40000000 +#define DW_DLC_SIZE_32 0x20000000 +#define DW_DLC_OFFSET_SIZE_64 0x10000000 +#define DW_DLC_ISA_MIPS 0x80000000 +#define DW_DLC_ISA_IA64 0x01000000 +#define DW_DLC_STREAM_RELOCATIONS 0x02000000 +#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 +#define DW_DLC_TARGET_BIGENDIAN 0x08000000 +#define DW_DLC_TARGET_LITTLEENDIAN 0x00100000 + +/* + * Instruction set architectures supported by this implementation. + */ +enum Dwarf_ISA { + DW_ISA_ARM, + DW_ISA_IA64, + DW_ISA_MIPS, + DW_ISA_PPC, + DW_ISA_SPARC, + DW_ISA_X86, + DW_ISA_X86_64, + DW_ISA_MAX +}; + +/* Function prototype definitions. */ +__BEGIN_DECLS +Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die, Dwarf_Signed, + Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_dataref(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_Small, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_P_Expr, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die, char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + Dwarf_P_Die, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Signed, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug, Dwarf_P_Die, Dwarf_Half, + char *, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Signed, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Half, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Signed, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_arange_b(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_die_to_debug(Dwarf_P_Debug, Dwarf_P_Die, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug, char *, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr, Dwarf_Unsigned, + Dwarf_Signed, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr, Dwarf_Small, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_P_Fde dwarf_add_fde_inst(Dwarf_P_Fde, Dwarf_Small, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug, char *, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug, char *, Dwarf_Small, + Dwarf_Small, Dwarf_Small, Dwarf_Ptr, Dwarf_Unsigned, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_fde(Dwarf_P_Debug, Dwarf_P_Fde, Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_frame_fde_b(Dwarf_P_Debug, Dwarf_P_Fde, Dwarf_P_Die, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_funcname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug, Dwarf_Unsigned, + Dwarf_Addr, Dwarf_Unsigned, Dwarf_Signed, Dwarf_Bool, + Dwarf_Bool, Dwarf_Error *); +Dwarf_Unsigned dwarf_add_pubname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_typename(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_varname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_add_weakname(Dwarf_P_Debug, Dwarf_P_Die, char *, + Dwarf_Error *); +int dwarf_arrayorder(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *, + Dwarf_Error *); +int dwarf_attrlist(Dwarf_Die, Dwarf_Attribute **, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_attrval_flag(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_attrval_signed(Dwarf_Die, Dwarf_Half, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_attrval_string(Dwarf_Die, Dwarf_Half, const char **, + Dwarf_Error *); +int dwarf_attrval_unsigned(Dwarf_Die, Dwarf_Half, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_bitoffset(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_bitsize(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_bytesize(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_child(Dwarf_Die, Dwarf_Die *, Dwarf_Error *); +void dwarf_dealloc(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned); +int dwarf_def_macro(Dwarf_P_Debug, Dwarf_Unsigned, char *, char *, + Dwarf_Error *); +int dwarf_die_CU_offset(Dwarf_Die, Dwarf_Off *, Dwarf_Error *); +int dwarf_die_CU_offset_range(Dwarf_Die, Dwarf_Off *, Dwarf_Off *, + Dwarf_Error *); +int dwarf_die_abbrev_code(Dwarf_Die); +Dwarf_P_Die dwarf_die_link(Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die, Dwarf_Error *); +int dwarf_diename(Dwarf_Die, char **, Dwarf_Error *); +int dwarf_dieoffset(Dwarf_Die, Dwarf_Off *, Dwarf_Error *); +int dwarf_elf_init(Elf *, int, Dwarf_Handler, Dwarf_Ptr, + Dwarf_Debug *, Dwarf_Error *); +int dwarf_end_macro_file(Dwarf_P_Debug, Dwarf_Error *); +const char *dwarf_errmsg_(Dwarf_Error *); +int dwarf_expand_frame_instructions(Dwarf_Cie, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Frame_Op **, Dwarf_Signed *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr, Dwarf_Error *); +Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Unsigned *, + Dwarf_Error *); +Dwarf_P_Fde dwarf_fde_cfa_offset(Dwarf_P_Fde, Dwarf_Unsigned, Dwarf_Signed, + Dwarf_Error *); +void dwarf_fde_cie_list_dealloc(Dwarf_Debug, Dwarf_Cie *, + Dwarf_Signed, Dwarf_Fde *, Dwarf_Signed); +char *dwarf_find_macro_value_start(char *); +int dwarf_finish(Dwarf_Debug, Dwarf_Error *); +int dwarf_formaddr(Dwarf_Attribute, Dwarf_Addr *, Dwarf_Error *); +int dwarf_formblock(Dwarf_Attribute, Dwarf_Block **, Dwarf_Error *); +int dwarf_formexprloc(Dwarf_Attribute, Dwarf_Unsigned *, + Dwarf_Ptr *, Dwarf_Error *); +int dwarf_formflag(Dwarf_Attribute, Dwarf_Bool *, Dwarf_Error *); +int dwarf_formref(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *); +int dwarf_formsdata(Dwarf_Attribute, Dwarf_Signed *, Dwarf_Error *); +int dwarf_formsig8(Dwarf_Attribute, Dwarf_Sig8 *, Dwarf_Error *); +int dwarf_formstring(Dwarf_Attribute, char **, Dwarf_Error *); +int dwarf_formudata(Dwarf_Attribute, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_func_cu_offset(Dwarf_Func, Dwarf_Off *, Dwarf_Error *); +int dwarf_func_die_offset(Dwarf_Func, Dwarf_Off *, + Dwarf_Error *); +int dwarf_func_name_offsets(Dwarf_Func, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_funcname(Dwarf_Func, char **, Dwarf_Error *); +void dwarf_funcs_dealloc(Dwarf_Debug, Dwarf_Func *, Dwarf_Signed); +int dwarf_get_ACCESS_name(unsigned, const char **); +int dwarf_get_ATE_name(unsigned, const char **); +int dwarf_get_AT_name(unsigned, const char **); +int dwarf_get_CC_name(unsigned, const char **); +int dwarf_get_CFA_name(unsigned, const char **); +int dwarf_get_CHILDREN_name(unsigned, const char **); +int dwarf_get_DSC_name(unsigned, const char **); +int dwarf_get_DS_name(unsigned, const char **); +int dwarf_get_EH_name(unsigned, const char **); +int dwarf_get_END_name(unsigned, const char **); +int dwarf_get_FORM_name(unsigned, const char **); +int dwarf_get_ID_name(unsigned, const char **); +int dwarf_get_INL_name(unsigned, const char **); +int dwarf_get_LANG_name(unsigned, const char **); +int dwarf_get_LNE_name(unsigned, const char **); +int dwarf_get_LNS_name(unsigned, const char **); +int dwarf_get_MACINFO_name(unsigned, const char **); +int dwarf_get_OP_name(unsigned, const char **); +int dwarf_get_ORD_name(unsigned, const char **); +int dwarf_get_TAG_name(unsigned, const char **); +int dwarf_get_VIRTUALITY_name(unsigned, const char **); +int dwarf_get_VIS_name(unsigned, const char **); +int dwarf_get_abbrev(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Abbrev *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_abbrev_children_flag(Dwarf_Abbrev, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_abbrev_code(Dwarf_Abbrev, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_get_abbrev_entry(Dwarf_Abbrev, Dwarf_Signed, Dwarf_Half *, + Dwarf_Signed *, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_abbrev_tag(Dwarf_Abbrev, Dwarf_Half *, Dwarf_Error *); +int dwarf_get_address_size(Dwarf_Debug, Dwarf_Half *, + Dwarf_Error *); +int dwarf_get_arange(Dwarf_Arange *, Dwarf_Unsigned, Dwarf_Addr, + Dwarf_Arange *, Dwarf_Error *); +int dwarf_get_arange_cu_header_offset(Dwarf_Arange, Dwarf_Off *, + Dwarf_Error *); +int dwarf_get_arange_info(Dwarf_Arange, Dwarf_Addr *, + Dwarf_Unsigned *, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_aranges(Dwarf_Debug, Dwarf_Arange **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_cie_index(Dwarf_Cie, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_cie_info(Dwarf_Cie, Dwarf_Unsigned *, Dwarf_Small *, + char **, Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Half *, + Dwarf_Ptr *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_cie_of_fde(Dwarf_Fde, Dwarf_Cie *, Dwarf_Error *); +int dwarf_get_cu_die_offset(Dwarf_Arange, Dwarf_Off *, + Dwarf_Error *); +int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug, + Dwarf_Off, Dwarf_Off *, Dwarf_Error *); +int dwarf_get_elf(Dwarf_Debug, Elf **, Dwarf_Error *); +int dwarf_get_fde_at_pc(Dwarf_Fde *, Dwarf_Addr, Dwarf_Fde *, + Dwarf_Addr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_all_regs(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde, Dwarf_Addr, + Dwarf_Regtable3 *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde, Dwarf_Addr, + Dwarf_Small *, Dwarf_Signed *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Ptr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_reg(Dwarf_Fde, Dwarf_Half, Dwarf_Addr, + Dwarf_Signed *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_info_for_reg3(Dwarf_Fde, Dwarf_Half, Dwarf_Addr, + Dwarf_Small *, Dwarf_Signed *, Dwarf_Signed *, + Dwarf_Signed *, Dwarf_Ptr *, Dwarf_Addr *, Dwarf_Error *); +int dwarf_get_fde_instr_bytes(Dwarf_Fde, Dwarf_Ptr *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_fde_list(Dwarf_Debug, Dwarf_Cie **, Dwarf_Signed *, + Dwarf_Fde **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_fde_list_eh(Dwarf_Debug, Dwarf_Cie **, Dwarf_Signed *, + Dwarf_Fde **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_get_fde_n(Dwarf_Fde *, Dwarf_Unsigned, Dwarf_Fde *, + Dwarf_Error *); +int dwarf_get_fde_range(Dwarf_Fde, Dwarf_Addr *, Dwarf_Unsigned *, + Dwarf_Ptr *, Dwarf_Unsigned *, Dwarf_Off *, Dwarf_Signed *, + Dwarf_Off *, Dwarf_Error *); +enum Dwarf_Form_Class dwarf_get_form_class(Dwarf_Half, Dwarf_Half, Dwarf_Half, + Dwarf_Half); +int dwarf_get_funcs(Dwarf_Debug, Dwarf_Func **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_globals(Dwarf_Debug, Dwarf_Global **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_loclist_entry(Dwarf_Debug, Dwarf_Unsigned, + Dwarf_Addr *, Dwarf_Addr *, Dwarf_Ptr *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_macro_details(Dwarf_Debug, Dwarf_Off, Dwarf_Unsigned, + Dwarf_Signed *, Dwarf_Macro_Details **, Dwarf_Error *); +int dwarf_get_pubtypes(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_ranges(Dwarf_Debug, Dwarf_Off, Dwarf_Ranges **, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_ranges_a(Dwarf_Debug, Dwarf_Off, Dwarf_Die, + Dwarf_Ranges **, Dwarf_Signed *, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_get_relocation_info(Dwarf_P_Debug, Dwarf_Signed *, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Relocation_Data *, + Dwarf_Error *); +int dwarf_get_relocation_info_count(Dwarf_P_Debug, Dwarf_Unsigned *, + int *, Dwarf_Error *); +Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug, Dwarf_Signed, + Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_get_str(Dwarf_Debug, Dwarf_Off, char **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_types(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_vars(Dwarf_Debug, Dwarf_Var **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_get_weaks(Dwarf_Debug, Dwarf_Weak **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_global_cu_offset(Dwarf_Global, Dwarf_Off *, Dwarf_Error *); +int dwarf_global_die_offset(Dwarf_Global, Dwarf_Off *, + Dwarf_Error *); +int dwarf_global_formref(Dwarf_Attribute, Dwarf_Off *, + Dwarf_Error *); +int dwarf_global_name_offsets(Dwarf_Global, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +void dwarf_globals_dealloc(Dwarf_Debug, Dwarf_Global *, Dwarf_Signed); +int dwarf_globname(Dwarf_Global, char **, Dwarf_Error *); +int dwarf_hasattr(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_hasform(Dwarf_Attribute, Dwarf_Half, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_highpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +int dwarf_init(int, int, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *, + Dwarf_Error *); +int dwarf_line_srcfileno(Dwarf_Line, Dwarf_Unsigned *, + Dwarf_Error *); +int dwarf_lineaddr(Dwarf_Line, Dwarf_Addr *, Dwarf_Error *); +int dwarf_linebeginstatement(Dwarf_Line, Dwarf_Bool *, + Dwarf_Error *); +int dwarf_lineblock(Dwarf_Line, Dwarf_Bool *, Dwarf_Error *); +int dwarf_lineendsequence(Dwarf_Line, Dwarf_Bool *, Dwarf_Error *); +int dwarf_lineno(Dwarf_Line, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_lineoff(Dwarf_Line, Dwarf_Signed *, Dwarf_Error *); +int dwarf_linesrc(Dwarf_Line, char **, Dwarf_Error *); +Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Error *); +Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug, Dwarf_Addr, Dwarf_Unsigned, + Dwarf_Error *); +int dwarf_loclist(Dwarf_Attribute, Dwarf_Locdesc **, Dwarf_Signed *, + Dwarf_Error *); +int dwarf_loclist_from_expr(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, + Dwarf_Locdesc **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_from_expr_a(Dwarf_Debug, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Half, Dwarf_Locdesc **, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_n(Dwarf_Attribute, Dwarf_Locdesc ***, + Dwarf_Signed *, Dwarf_Error *); +int dwarf_lowpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +Dwarf_P_Die dwarf_new_die(Dwarf_P_Debug, Dwarf_Tag, Dwarf_P_Die, + Dwarf_P_Die, Dwarf_P_Die, Dwarf_P_Die, Dwarf_Error *); +Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug, Dwarf_Error *); +int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_cu_header_b(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_object_finish(Dwarf_Debug, Dwarf_Error *); +int dwarf_object_init(Dwarf_Obj_Access_Interface *, Dwarf_Handler, + Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *); +int dwarf_offdie(Dwarf_Debug, Dwarf_Off, Dwarf_Die *, + Dwarf_Error *); +Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug, Dwarf_Error *); +Dwarf_P_Debug dwarf_producer_init(Dwarf_Unsigned, Dwarf_Callback_Func, + Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); +Dwarf_P_Debug dwarf_producer_init_b(Dwarf_Unsigned, Dwarf_Callback_Func_b, + Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *); +int dwarf_producer_set_isa(Dwarf_P_Debug, enum Dwarf_ISA, + Dwarf_Error *); +int dwarf_pubtype_cu_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_pubtype_die_offset(Dwarf_Type, Dwarf_Off *, + Dwarf_Error *); +int dwarf_pubtype_name_offsets(Dwarf_Type, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_pubtypename(Dwarf_Type, char **, Dwarf_Error *); +void dwarf_pubtypes_dealloc(Dwarf_Debug, Dwarf_Type *, Dwarf_Signed); +void dwarf_ranges_dealloc(Dwarf_Debug, Dwarf_Ranges *, Dwarf_Signed); +void dwarf_reset_section_bytes(Dwarf_P_Debug); +Dwarf_Half dwarf_set_frame_cfa_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_rule_initial_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_rule_table_size(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_same_value(Dwarf_Debug, Dwarf_Half); +Dwarf_Half dwarf_set_frame_undefined_value(Dwarf_Debug, Dwarf_Half); +int dwarf_set_reloc_application(int); +Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug, Dwarf_Ptr); +Dwarf_Handler dwarf_seterrhand(Dwarf_Debug, Dwarf_Handler); +int dwarf_siblingof(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Error *); +int dwarf_srcfiles(Dwarf_Die, char ***, Dwarf_Signed *, Dwarf_Error *); +int dwarf_srclang(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_srclines(Dwarf_Die, Dwarf_Line **, Dwarf_Signed *, + Dwarf_Error *); +void dwarf_srclines_dealloc(Dwarf_Debug, Dwarf_Line *, + Dwarf_Signed); +int dwarf_start_macro_file(Dwarf_P_Debug, Dwarf_Unsigned, + Dwarf_Unsigned, Dwarf_Error *); +int dwarf_tag(Dwarf_Die, Dwarf_Half *, Dwarf_Error *); +Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug, Dwarf_Error *); +int dwarf_type_cu_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_type_die_offset(Dwarf_Type, Dwarf_Off *, Dwarf_Error *); +int dwarf_type_name_offsets(Dwarf_Type, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_typename(Dwarf_Type, char **, Dwarf_Error *); +void dwarf_types_dealloc(Dwarf_Debug, Dwarf_Type *, Dwarf_Signed); +int dwarf_undef_macro(Dwarf_P_Debug, Dwarf_Unsigned, char *, + Dwarf_Error *); +int dwarf_var_cu_offset(Dwarf_Var, Dwarf_Off *, Dwarf_Error *); +int dwarf_var_die_offset(Dwarf_Var, Dwarf_Off *, + Dwarf_Error *); +int dwarf_var_name_offsets(Dwarf_Var, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_varname(Dwarf_Var, char **, Dwarf_Error *); +void dwarf_vars_dealloc(Dwarf_Debug, Dwarf_Var *, Dwarf_Signed); +int dwarf_vendor_ext(Dwarf_P_Debug, Dwarf_Unsigned, char *, + Dwarf_Error *); +int dwarf_weak_cu_offset(Dwarf_Weak, Dwarf_Off *, Dwarf_Error *); +int dwarf_weak_die_offset(Dwarf_Weak, Dwarf_Off *, + Dwarf_Error *); +int dwarf_weak_name_offsets(Dwarf_Weak, char **, + Dwarf_Off *, Dwarf_Off *, Dwarf_Error *); +int dwarf_weakname(Dwarf_Weak, char **, Dwarf_Error *); +void dwarf_weaks_dealloc(Dwarf_Debug, Dwarf_Weak *, Dwarf_Signed); +int dwarf_whatattr(Dwarf_Attribute, Dwarf_Half *, Dwarf_Error *); +int dwarf_whatform(Dwarf_Attribute, Dwarf_Half *, Dwarf_Error *); +int dwarf_whatform_direct(Dwarf_Attribute, Dwarf_Half *, + Dwarf_Error *); +__END_DECLS + +#endif /* !_LIBDWARF_H_ */ diff --git a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c new file mode 100644 index 0000000..f4a395d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c @@ -0,0 +1,266 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_abbrev.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +int +_dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, + uint64_t aboff, Dwarf_Abbrev *abp, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_Debug dbg; + + dbg = cu != NULL ? cu->cu_dbg : NULL; + + if ((ab = malloc(sizeof(struct _Dwarf_Abbrev))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* Initialise the abbrev structure. */ + ab->ab_entry = entry; + ab->ab_tag = tag; + ab->ab_children = children; + ab->ab_offset = aboff; + ab->ab_length = 0; /* fill in later. */ + ab->ab_atnum = 0; /* fill in later. */ + + /* Initialise the list of attribute definitions. */ + STAILQ_INIT(&ab->ab_attrdef); + + /* Add the abbrev to the hash table of the compilation unit. */ + if (cu != NULL) + HASH_ADD(ab_hh, cu->cu_abbrev_hash, ab_entry, + sizeof(ab->ab_entry), ab); + + if (abp != NULL) + *abp = ab; + + return (DW_DLE_NONE); +} + +int +_dwarf_attrdef_add(Dwarf_Debug dbg, Dwarf_Abbrev ab, uint64_t attr, + uint64_t form, uint64_t adoff, Dwarf_AttrDef *adp, Dwarf_Error *error) +{ + Dwarf_AttrDef ad; + + if (ab == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((ad = malloc(sizeof(struct _Dwarf_AttrDef))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* Initialise the attribute definition structure. */ + ad->ad_attrib = attr; + ad->ad_form = form; + ad->ad_offset = adoff; + + /* Add the attribute definition to the list in the abbrev. */ + STAILQ_INSERT_TAIL(&ab->ab_attrdef, ad, ad_next); + + /* Increase number of attribute counter. */ + ab->ab_atnum++; + + if (adp != NULL) + *adp = ad; + + return (DW_DLE_NONE); +} + +int +_dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, + Dwarf_Abbrev *abp, Dwarf_Error *error) +{ + Dwarf_Section *ds; + uint64_t attr; + uint64_t entry; + uint64_t form; + uint64_t aboff; + uint64_t adoff; + uint64_t tag; + uint8_t children; + int ret; + + assert(abp != NULL); + + ds = _dwarf_find_section(dbg, ".debug_abbrev"); + assert(ds != NULL); + + if (*offset >= ds->ds_size) + return (DW_DLE_NO_ENTRY); + + aboff = *offset; + + entry = _dwarf_read_uleb128(ds->ds_data, offset); + if (entry == 0) { + /* Last entry. */ + ret = _dwarf_abbrev_add(cu, entry, 0, 0, aboff, abp, + error); + if (ret == DW_DLE_NONE) { + (*abp)->ab_length = 1; + return (ret); + } else + return (ret); + } + tag = _dwarf_read_uleb128(ds->ds_data, offset); + children = dbg->read(ds->ds_data, offset, 1); + if ((ret = _dwarf_abbrev_add(cu, entry, tag, children, aboff, + abp, error)) != DW_DLE_NONE) + return (ret); + + /* Parse attribute definitions. */ + do { + adoff = *offset; + attr = _dwarf_read_uleb128(ds->ds_data, offset); + form = _dwarf_read_uleb128(ds->ds_data, offset); + if (attr != 0) + if ((ret = _dwarf_attrdef_add(dbg, *abp, attr, + form, adoff, NULL, error)) != DW_DLE_NONE) + return (ret); + } while (attr != 0); + + (*abp)->ab_length = *offset - aboff; + + return (ret); +} + +int +_dwarf_abbrev_find(Dwarf_CU cu, uint64_t entry, Dwarf_Abbrev *abp, + Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_Section *ds; + Dwarf_Unsigned offset; + int ret; + + if (entry == 0) + return (DW_DLE_NO_ENTRY); + + /* Check if the desired abbrev entry is already in the hash table. */ + HASH_FIND(ab_hh, cu->cu_abbrev_hash, &entry, sizeof(entry), ab); + if (ab != NULL) { + *abp = ab; + return (DW_DLE_NONE); + } + + if (cu->cu_abbrev_loaded) { + return (DW_DLE_NO_ENTRY); + } + + /* Load and search the abbrev table. */ + ds = _dwarf_find_section(cu->cu_dbg, ".debug_abbrev"); + assert(ds != NULL); + offset = cu->cu_abbrev_offset_cur; + while (offset < ds->ds_size) { + ret = _dwarf_abbrev_parse(cu->cu_dbg, cu, &offset, &ab, error); + if (ret != DW_DLE_NONE) + return (ret); + if (ab->ab_entry == entry) { + cu->cu_abbrev_offset_cur = offset; + *abp = ab; + return (DW_DLE_NONE); + } + if (ab->ab_entry == 0) { + cu->cu_abbrev_offset_cur = offset; + cu->cu_abbrev_loaded = 1; + break; + } + } + + return (DW_DLE_NO_ENTRY); +} + +void +_dwarf_abbrev_cleanup(Dwarf_CU cu) +{ + Dwarf_Abbrev ab, tab; + Dwarf_AttrDef ad, tad; + + assert(cu != NULL); + + HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { + HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + free(ab); + } +} + +int +_dwarf_abbrev_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Abbrev ab; + Dwarf_AttrDef ad; + Dwarf_P_Section ds; + int ret; + + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu == NULL) + return (DW_DLE_NONE); + + /* Create .debug_abbrev section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_abbrev", 0, error)) != + DW_DLE_NONE) + return (ret); + + for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { + RCHECK(WRITE_ULEB128(ab->ab_entry)); + RCHECK(WRITE_ULEB128(ab->ab_tag)); + RCHECK(WRITE_VALUE(ab->ab_children, 1)); + STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { + RCHECK(WRITE_ULEB128(ad->ad_attrib)); + RCHECK(WRITE_ULEB128(ad->ad_form)); + } + /* Signal end of attribute spec list. */ + RCHECK(WRITE_ULEB128(0)); + RCHECK(WRITE_ULEB128(0)); + } + /* End of abbreviation for this CU. */ + RCHECK(WRITE_ULEB128(0)); + + /* Notify the creation of .debug_abbrev ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + return (DW_DLE_NONE); + +gen_fail: + + _dwarf_section_free(dbg, &ds); + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_arange.c b/contrib/elftoolchain/libdwarf/libdwarf_arange.c new file mode 100644 index 0000000..75434f6 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_arange.c @@ -0,0 +1,260 @@ +/*- + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_arange.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +void +_dwarf_arange_cleanup(Dwarf_Debug dbg) +{ + Dwarf_ArangeSet as, tas; + Dwarf_Arange ar, tar; + + STAILQ_FOREACH_SAFE(as, &dbg->dbg_aslist, as_next, tas) { + STAILQ_FOREACH_SAFE(ar, &as->as_arlist, ar_next, tar) { + STAILQ_REMOVE(&as->as_arlist, ar, _Dwarf_Arange, + ar_next); + free(ar); + } + STAILQ_REMOVE(&dbg->dbg_aslist, as, _Dwarf_ArangeSet, as_next); + free(as); + } + + if (dbg->dbg_arange_array) + free(dbg->dbg_arange_array); + + dbg->dbg_arange_array = NULL; + dbg->dbg_arange_cnt = 0; +} + +int +_dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_ArangeSet as; + Dwarf_Arange ar; + Dwarf_Section *ds; + uint64_t offset, dwarf_size, length, addr, range; + int i, ret; + + ret = DW_DLE_NONE; + + if ((ds = _dwarf_find_section(dbg, ".debug_aranges")) == NULL) + return (DW_DLE_NONE); + + if (!dbg->dbg_info_loaded) { + ret = _dwarf_info_load(dbg, 1, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + offset = 0; + while (offset < ds->ds_size) { + + if ((as = malloc(sizeof(struct _Dwarf_ArangeSet))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&as->as_arlist); + STAILQ_INSERT_TAIL(&dbg->dbg_aslist, as, as_next); + + /* Read in the table header. */ + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + as->as_length = length; + as->as_version = dbg->read(ds->ds_data, &offset, 2); + if (as->as_version != 2) { + DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + ret = DW_DLE_VERSION_STAMP_ERROR; + goto fail_cleanup; + } + + as->as_cu_offset = dbg->read(ds->ds_data, &offset, dwarf_size); + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == as->as_cu_offset) + break; + } + if (cu == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); + ret = DW_DLE_ARANGE_OFFSET_BAD; + goto fail_cleanup; + } + as->as_cu = cu; + + as->as_addrsz = dbg->read(ds->ds_data, &offset, 1); + as->as_segsz = dbg->read(ds->ds_data, &offset, 1); + + /* Skip the padding bytes. */ + offset = roundup(offset, 2 * as->as_addrsz); + + /* Read in address range descriptors. */ + while (offset < ds->ds_size) { + addr = dbg->read(ds->ds_data, &offset, as->as_addrsz); + range = dbg->read(ds->ds_data, &offset, as->as_addrsz); + if (addr == 0 && range == 0) + break; + if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + goto fail_cleanup; + } + ar->ar_as = as; + ar->ar_address = addr; + ar->ar_range = range; + STAILQ_INSERT_TAIL(&as->as_arlist, ar, ar_next); + dbg->dbg_arange_cnt++; + } + } + + /* Build arange array. */ + if (dbg->dbg_arange_cnt > 0) { + if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * + sizeof(struct _Dwarf_Arange))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + i = 0; + STAILQ_FOREACH(as, &dbg->dbg_aslist, as_next) { + STAILQ_FOREACH(ar, &as->as_arlist, ar_next) + dbg->dbg_arange_array[i++] = ar; + } + assert((Dwarf_Unsigned)i == dbg->dbg_arange_cnt); + } + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_arange_cleanup(dbg); + + return (ret); +} + +int +_dwarf_arange_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_ArangeSet as; + Dwarf_Arange ar; + uint64_t offset; + int ret; + + as = dbg->dbgp_as; + assert(as != NULL); + if (STAILQ_EMPTY(&as->as_arlist)) + return (DW_DLE_NONE); + + as->as_length = 0; + as->as_version = 2; + as->as_cu_offset = 0; /* We have only one CU. */ + as->as_addrsz = dbg->dbg_pointer_size; + as->as_segsz = 0; /* XXX */ + + /* Create .debug_arange section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_aranges", 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for .debug_aranges */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Write section header. */ + RCHECK(WRITE_VALUE(as->as_length, 4)); + RCHECK(WRITE_VALUE(as->as_version, 2)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, as->as_cu_offset, ".debug_info", error)); + RCHECK(WRITE_VALUE(as->as_addrsz, 1)); + RCHECK(WRITE_VALUE(as->as_segsz, 1)); + + /* Pad to (2 * address_size) */ + offset = roundup(ds->ds_size, 2 * as->as_addrsz); + if (offset > ds->ds_size) + RCHECK(WRITE_PADDING(0, offset - ds->ds_size)); + + /* Write tuples. */ + STAILQ_FOREACH(ar, &as->as_arlist, ar_next) { + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, ds->ds_size, + ar->ar_symndx, ar->ar_address, NULL, error)); + if (ar->ar_esymndx > 0) + RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds, + dbg->dbg_pointer_size, ds->ds_size, ar->ar_symndx, + ar->ar_esymndx, ar->ar_address, ar->ar_eoff, error)); + else + RCHECK(WRITE_VALUE(ar->ar_range, dbg->dbg_pointer_size)); + } + RCHECK(WRITE_VALUE(0, dbg->dbg_pointer_size)); + RCHECK(WRITE_VALUE(0, dbg->dbg_pointer_size)); + + /* Fill in the length field. */ + as->as_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, as->as_length, 4); + + /* Inform application the creation of .debug_aranges ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_aranges */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_arange_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_ArangeSet as; + Dwarf_Arange ar, tar; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_as == NULL) + return; + + as = dbg->dbgp_as; + STAILQ_FOREACH_SAFE(ar, &as->as_arlist, ar_next, tar) { + STAILQ_REMOVE(&as->as_arlist, ar, _Dwarf_Arange, ar_next); + free(ar); + } + free(as); + dbg->dbgp_as = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_attr.c b/contrib/elftoolchain/libdwarf/libdwarf_attr.c new file mode 100644 index 0000000..a7fb71c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_attr.c @@ -0,0 +1,458 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_attr.c 2966 2013-09-21 14:40:14Z kaiwang27 $"); + +int +_dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) +{ + Dwarf_Attribute at; + + assert(die != NULL); + assert(atp != NULL); + + if ((at = calloc(1, sizeof(struct _Dwarf_Attribute))) == NULL) { + DWARF_SET_ERROR(die->die_dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + *atp = at; + + return (DW_DLE_NONE); +} + +static int +_dwarf_attr_add(Dwarf_Die die, Dwarf_Attribute atref, Dwarf_Attribute *atp, + Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + memcpy(at, atref, sizeof(struct _Dwarf_Attribute)); + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + /* Save a pointer to the attribute name if this is one. */ + if (at->at_attrib == DW_AT_name) { + switch (at->at_form) { + case DW_FORM_strp: + die->die_name = at->u[1].s; + break; + case DW_FORM_string: + die->die_name = at->u[0].s; + break; + default: + break; + } + } + + if (atp != NULL) + *atp = at; + + return (DW_DLE_NONE); +} + +Dwarf_Attribute +_dwarf_attr_find(Dwarf_Die die, Dwarf_Half attr) +{ + Dwarf_Attribute at; + + STAILQ_FOREACH(at, &die->die_attr, at_next) { + if (at->at_attrib == attr) + break; + } + + return (at); +} + +int +_dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, + int dwarf_size, Dwarf_CU cu, Dwarf_Die die, Dwarf_AttrDef ad, + uint64_t form, int indirect, Dwarf_Error *error) +{ + struct _Dwarf_Attribute atref; + Dwarf_Section *str; + int ret; + + ret = DW_DLE_NONE; + memset(&atref, 0, sizeof(atref)); + atref.at_die = die; + atref.at_attrib = ad->ad_attrib; + atref.at_form = indirect ? form : ad->ad_form; + atref.at_indirect = indirect; + atref.at_ld = NULL; + + switch (form) { + case DW_FORM_addr: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + cu->cu_pointer_size); + break; + case DW_FORM_block: + case DW_FORM_exprloc: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_block4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); + break; + case DW_FORM_data2: + case DW_FORM_ref2: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); + break; + case DW_FORM_data4: + case DW_FORM_ref4: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); + break; + case DW_FORM_data8: + case DW_FORM_ref8: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 8); + break; + case DW_FORM_indirect: + form = _dwarf_read_uleb128(ds->ds_data, offsetp); + return (_dwarf_attr_init(dbg, ds, offsetp, dwarf_size, cu, die, + ad, form, 1, error)); + case DW_FORM_ref_addr: + if (cu->cu_version == 2) + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + cu->cu_pointer_size); + else if (cu->cu_version == 3) + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, + dwarf_size); + break; + case DW_FORM_ref_udata: + case DW_FORM_udata: + atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); + break; + case DW_FORM_sdata: + atref.u[0].s64 = _dwarf_read_sleb128(ds->ds_data, offsetp); + break; + case DW_FORM_sec_offset: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + break; + case DW_FORM_string: + atref.u[0].s = _dwarf_read_string(ds->ds_data, ds->ds_size, + offsetp); + break; + case DW_FORM_strp: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + str = _dwarf_find_section(dbg, ".debug_str"); + assert(str != NULL); + atref.u[1].s = (char *) str->ds_data + atref.u[0].u64; + break; + case DW_FORM_ref_sig8: + atref.u[0].u64 = 8; + atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, + atref.u[0].u64); + break; + case DW_FORM_flag_present: + /* This form has no value encoded in the DIE. */ + atref.u[0].u64 = 1; + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + } + + if (ret == DW_DLE_NONE) { + if (form == DW_FORM_block || form == DW_FORM_block1 || + form == DW_FORM_block2 || form == DW_FORM_block4) { + atref.at_block.bl_len = atref.u[0].u64; + atref.at_block.bl_data = atref.u[1].u8p; + } + ret = _dwarf_attr_add(die, &atref, NULL, error); + } + + return (ret); +} + +static int +_dwarf_attr_write(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, + Dwarf_CU cu, Dwarf_Attribute at, int pass2, Dwarf_Error *error) +{ + struct _Dwarf_P_Expr_Entry *ee; + uint64_t value, offset, bs; + int ret; + + assert(dbg != NULL && ds != NULL && cu != NULL && at != NULL); + + /* Fill in reference to other DIE in the second pass. */ + if (pass2) { + if (at->at_form != DW_FORM_ref4 && at->at_form != DW_FORM_ref8) + return (DW_DLE_NONE); + if (at->at_refdie == NULL || at->at_offset == 0) + return (DW_DLE_NONE); + offset = at->at_offset; + dbg->write(ds->ds_data, &offset, at->at_refdie->die_offset, + at->at_form == DW_FORM_ref4 ? 4 : 8); + return (DW_DLE_NONE); + } + + switch (at->at_form) { + case DW_FORM_addr: + if (at->at_relsym) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, cu->cu_pointer_size, + ds->ds_size, at->at_relsym, at->u[0].u64, NULL, + error); + else + ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); + break; + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + /* Write block size. */ + if (at->at_form == DW_FORM_block) { + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, at->u[0].u64, error); + if (ret != DW_DLE_NONE) + break; + } else { + if (at->at_form == DW_FORM_block1) + bs = 1; + else if (at->at_form == DW_FORM_block2) + bs = 2; + else + bs = 4; + ret = WRITE_VALUE(at->u[0].u64, bs); + if (ret != DW_DLE_NONE) + break; + } + + /* Keep block data offset for later use. */ + offset = ds->ds_size; + + /* Write block data. */ + ret = WRITE_BLOCK(at->u[1].u8p, at->u[0].u64); + if (ret != DW_DLE_NONE) + break; + if (at->at_expr == NULL) + break; + + /* Generate relocation entry for DW_OP_addr expressions. */ + STAILQ_FOREACH(ee, &at->at_expr->pe_eelist, ee_next) { + if (ee->ee_loc.lr_atom != DW_OP_addr || ee->ee_sym == 0) + continue; + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, + offset + ee->ee_loc.lr_offset + 1, ee->ee_sym, + ee->ee_loc.lr_number, NULL, error); + if (ret != DW_DLE_NONE) + break; + } + break; + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + ret = WRITE_VALUE(at->u[0].u64, 1); + break; + case DW_FORM_data2: + case DW_FORM_ref2: + ret = WRITE_VALUE(at->u[0].u64, 2); + break; + case DW_FORM_data4: + if (at->at_relsym || at->at_relsec != NULL) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, 4, ds->ds_size, at->at_relsym, + at->u[0].u64, at->at_relsec, error); + else + ret = WRITE_VALUE(at->u[0].u64, 4); + break; + case DW_FORM_data8: + if (at->at_relsym || at->at_relsec != NULL) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, 8, ds->ds_size, at->at_relsym, + at->u[0].u64, at->at_relsec, error); + else + ret = WRITE_VALUE(at->u[0].u64, 8); + break; + case DW_FORM_ref4: + case DW_FORM_ref8: + /* + * The value of ref4 and ref8 could be a reference to another + * DIE within the CU. And if we don't know the ref DIE's + * offset at the moement, then we remember at_offset and fill + * it in the second pass. + */ + if (at->at_refdie) { + value = at->at_refdie->die_offset; + if (value == 0) { + cu->cu_pass2 = 1; + at->at_offset = ds->ds_size; + } + } else + value = at->u[0].u64; + ret = WRITE_VALUE(value, at->at_form == DW_FORM_ref4 ? 4 : 8); + break; + case DW_FORM_indirect: + /* TODO. */ + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + case DW_FORM_ref_addr: + /* DWARF2 format. */ + if (at->at_relsym) + ret = _dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, cu->cu_pointer_size, + ds->ds_size, at->at_relsym, at->u[0].u64, NULL, + error); + else + ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); + break; + case DW_FORM_ref_udata: + case DW_FORM_udata: + ret = WRITE_ULEB128(at->u[0].u64); + break; + case DW_FORM_sdata: + ret = WRITE_SLEB128(at->u[0].s64); + break; + case DW_FORM_string: + assert(at->u[0].s != NULL); + ret = WRITE_STRING(at->u[0].s); + break; + case DW_FORM_strp: + ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, + 4, ds->ds_size, 0, at->u[0].u64, ".debug_str", error); + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); + ret = DW_DLE_ATTR_FORM_BAD; + break; + } + + return (ret); +} + +int +_dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, + Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, const char *secname, + Dwarf_P_Attribute *atp, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + assert(dbg != NULL && die != NULL); + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + at->at_die = die; + at->at_attrib = attr; + if (dbg->dbg_pointer_size == 4) + at->at_form = DW_FORM_data4; + else + at->at_form = DW_FORM_data8; + at->at_relsym = sym_index; + at->at_relsec = secname; + at->u[0].u64 = pc_value; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + if (atp) + *atp = at; + + return (DW_DLE_NONE); +} + +int +_dwarf_add_string_attr(Dwarf_P_Die die, Dwarf_P_Attribute *atp, Dwarf_Half attr, + char *string, Dwarf_Error *error) +{ + Dwarf_Attribute at; + Dwarf_Debug dbg; + int ret; + + dbg = die != NULL ? die->die_dbg : NULL; + + assert(atp != NULL); + + if (die == NULL || string == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) + return (ret); + + at->at_die = die; + at->at_attrib = attr; + at->at_form = DW_FORM_strp; + if ((ret = _dwarf_strtab_add(dbg, string, &at->u[0].u64, + error)) != DW_DLE_NONE) { + free(at); + return (ret); + } + at->u[1].s = _dwarf_strtab_get_table(dbg) + at->u[0].u64; + + *atp = at; + + STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_attr_gen(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, + Dwarf_CU cu, Dwarf_Die die, int pass2, Dwarf_Error *error) +{ + Dwarf_Attribute at; + int ret; + + assert(dbg != NULL && ds != NULL && cu != NULL && die != NULL); + + STAILQ_FOREACH(at, &die->die_attr, at_next) { + ret = _dwarf_attr_write(dbg, ds, drs, cu, at, pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_die.c b/contrib/elftoolchain/libdwarf/libdwarf_die.c new file mode 100644 index 0000000..4572875 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_die.c @@ -0,0 +1,455 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_die.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); + +int +_dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) +{ + Dwarf_Die die; + + assert(ret_die != NULL); + + if ((die = calloc(1, sizeof(struct _Dwarf_Die))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + STAILQ_INIT(&die->die_attr); + + *ret_die = die; + + return (DW_DLE_NONE); +} + +static int +_dwarf_die_add(Dwarf_CU cu, uint64_t offset, uint64_t abnum, Dwarf_Abbrev ab, + Dwarf_Die *diep, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Die die; + int ret; + + assert(cu != NULL); + assert(ab != NULL); + + dbg = cu->cu_dbg; + + if ((ret = _dwarf_die_alloc(dbg, &die, error)) != DW_DLE_NONE) + return (ret); + + die->die_offset = offset; + die->die_abnum = abnum; + die->die_ab = ab; + die->die_cu = cu; + die->die_dbg = cu->cu_dbg; + + if (diep != NULL) + *diep = die; + + return (DW_DLE_NONE); +} + +/* Find die at offset 'off' within the same CU. */ +Dwarf_Die +_dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + Dwarf_Die die1; + Dwarf_Error de; + int ret; + + cu = die->die_cu; + dbg = die->die_dbg; + + ret = _dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, + off, cu->cu_next_offset, &die1, 0, &de); + + if (ret == DW_DLE_NONE) + return (die1); + else + return (NULL); +} + +int +_dwarf_die_parse(Dwarf_Debug dbg, Dwarf_Section *ds, Dwarf_CU cu, + int dwarf_size, uint64_t offset, uint64_t next_offset, Dwarf_Die *ret_die, + int search_sibling, Dwarf_Error *error) +{ + Dwarf_Abbrev ab; + Dwarf_AttrDef ad; + Dwarf_Die die; + uint64_t abnum; + uint64_t die_offset; + int ret, level; + + assert(cu != NULL); + + level = 1; + die = NULL; + + while (offset < next_offset && offset < ds->ds_size) { + + die_offset = offset; + + abnum = _dwarf_read_uleb128(ds->ds_data, &offset); + + if (abnum == 0) { + if (level == 0 || !search_sibling) + return (DW_DLE_NO_ENTRY); + + /* + * Return to previous DIE level. + */ + level--; + continue; + } + + if ((ret = _dwarf_abbrev_find(cu, abnum, &ab, error)) != + DW_DLE_NONE) + return (ret); + + if ((ret = _dwarf_die_add(cu, die_offset, abnum, ab, &die, + error)) != DW_DLE_NONE) + return (ret); + + STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { + if ((ret = _dwarf_attr_init(dbg, ds, &offset, + dwarf_size, cu, die, ad, ad->ad_form, 0, + error)) != DW_DLE_NONE) + return (ret); + } + + die->die_next_off = offset; + if (search_sibling && level > 0) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + if (ab->ab_children == DW_CHILDREN_yes) { + /* Advance to next DIE level. */ + level++; + } + } else { + *ret_die = die; + return (DW_DLE_NONE); + } + } + + return (DW_DLE_NO_ENTRY); +} + +void +_dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, + Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) +{ + Dwarf_P_Die last_child; + + assert(die != NULL); + + if (parent) { + + /* Disconnect from old parent. */ + if (die->die_parent) { + if (die->die_parent != parent) { + if (die->die_parent->die_child == die) + die->die_parent->die_child = NULL; + die->die_parent = NULL; + } + } + + /* Find the last child of this parent. */ + last_child = parent->die_child; + if (last_child) { + while (last_child->die_right != NULL) + last_child = last_child->die_right; + } + + /* Connect to new parent. */ + die->die_parent = parent; + + /* + * Attach this DIE to the end of sibling list. If new + * parent doesn't have any child, set this DIE as the + * first child. + */ + if (last_child) { + assert(last_child->die_right == NULL); + last_child->die_right = die; + die->die_left = last_child; + } else + parent->die_child = die; + } + + if (child) { + + /* Disconnect from old child. */ + if (die->die_child) { + if (die->die_child != child) { + die->die_child->die_parent = NULL; + die->die_child = NULL; + } + } + + /* Connect to new child. */ + die->die_child = child; + child->die_parent = die; + } + + if (left_sibling) { + + /* Disconnect from old left sibling. */ + if (die->die_left) { + if (die->die_left != left_sibling) { + die->die_left->die_right = NULL; + die->die_left = NULL; + } + } + + /* Connect to new right sibling. */ + die->die_left = left_sibling; + left_sibling->die_right = die; + } + + if (right_sibling) { + + /* Disconnect from old right sibling. */ + if (die->die_right) { + if (die->die_right != right_sibling) { + die->die_right->die_left = NULL; + die->die_right = NULL; + } + } + + /* Connect to new right sibling. */ + die->die_right = right_sibling; + right_sibling->die_left = die; + } +} + +int +_dwarf_die_count_links(Dwarf_P_Die parent, Dwarf_P_Die child, + Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) +{ + int count; + + count = 0; + + if (parent) + count++; + if (child) + count++; + if (left_sibling) + count++; + if (right_sibling) + count++; + + return (count); +} + +static int +_dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, + Dwarf_P_Die die, int pass2, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Abbrev ab; + Dwarf_Attribute at; + Dwarf_AttrDef ad; + int match, ret; + + ds = dbg->dbgp_info; + assert(ds != NULL); + + if (pass2) + goto attr_gen; + + /* + * Add DW_AT_sibling attribute for DIEs with children, so consumers + * can quickly scan chains of siblings, while ignoring the children + * of individual siblings. + */ + if (die->die_child && die->die_right) { + if (_dwarf_attr_find(die, DW_AT_sibling) == NULL) + (void) dwarf_add_AT_reference(dbg, die, DW_AT_sibling, + die->die_right, error); + } + + /* + * Search abbrev list to find a matching entry. + */ + die->die_ab = NULL; + for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { + if (die->die_tag != ab->ab_tag) + continue; + if (ab->ab_children == DW_CHILDREN_no && die->die_child != NULL) + continue; + if (ab->ab_children == DW_CHILDREN_yes && + die->die_child == NULL) + continue; + at = STAILQ_FIRST(&die->die_attr); + ad = STAILQ_FIRST(&ab->ab_attrdef); + match = 1; + while (at != NULL && ad != NULL) { + if (at->at_attrib != ad->ad_attrib || + at->at_form != ad->ad_form) { + match = 0; + break; + } + at = STAILQ_NEXT(at, at_next); + ad = STAILQ_NEXT(ad, ad_next); + } + if ((at == NULL && ad != NULL) || (at != NULL && ad == NULL)) + match = 0; + if (match) { + die->die_ab = ab; + break; + } + } + + /* + * Create a new abbrev entry if we can not reuse any existing one. + */ + if (die->die_ab == NULL) { + ret = _dwarf_abbrev_add(cu, ++cu->cu_abbrev_cnt, die->die_tag, + die->die_child != NULL ? DW_CHILDREN_yes : DW_CHILDREN_no, + 0, &ab, error); + if (ret != DW_DLE_NONE) + return (ret); + STAILQ_FOREACH(at, &die->die_attr, at_next) { + ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib, + at->at_form, 0, NULL, error); + if (ret != DW_DLE_NONE) + return (ret); + } + die->die_ab = ab; + } + + die->die_offset = ds->ds_size; + + /* + * Transform the DIE to bytes stream. + */ + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, die->die_ab->ab_entry, error); + if (ret != DW_DLE_NONE) + return (ret); + +attr_gen: + + /* Transform the attributes of this DIE. */ + ret = _dwarf_attr_gen(dbg, ds, drs, cu, die, pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + + /* Proceed to child DIE. */ + if (die->die_child != NULL) { + ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_child, + pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* Proceed to sibling DIE. */ + if (die->die_right != NULL) { + ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_right, + pass2, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* Write a null DIE indicating the end of current level. */ + if (die->die_right == NULL) { + ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_die_gen(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_Abbrev ab, tab; + Dwarf_AttrDef ad, tad; + Dwarf_Die die; + int ret; + + assert(dbg != NULL && cu != NULL); + assert(dbg->dbgp_root_die != NULL); + + die = dbg->dbgp_root_die; + + /* + * Insert a DW_AT_stmt_list attribute into root DIE, if there are + * line number information. + */ + if (!STAILQ_EMPTY(&dbg->dbgp_lineinfo->li_lnlist)) + RCHECK(_dwarf_add_AT_dataref(dbg, die, DW_AT_stmt_list, 0, 0, + ".debug_line", NULL, error)); + + RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 0, error)); + + if (cu->cu_pass2) + RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 1, error)); + + return (DW_DLE_NONE); + +gen_fail: + + HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { + HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); + STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { + STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, + ad_next); + free(ad); + } + free(ab); + } + + return (ret); +} + +void +_dwarf_die_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Die die, tdie; + Dwarf_P_Attribute at, tat; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(die, &dbg->dbgp_dielist, die_pro_next, tdie) { + STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { + STAILQ_REMOVE(&die->die_attr, at, _Dwarf_Attribute, + at_next); + free(at); + } + free(die); + } +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c new file mode 100644 index 0000000..d3e381b --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_access.c @@ -0,0 +1,164 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_elf_access.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +int +_dwarf_elf_get_section_info(void *obj, Dwarf_Half ndx, + Dwarf_Obj_Access_Section *ret_section, int *error) +{ + Dwarf_Elf_Object *e; + GElf_Shdr *sh; + + e = obj; + assert(e != NULL); + + if (ret_section == NULL) { + if (error) + *error = DW_DLE_ARGUMENT; + return (DW_DLV_ERROR); + } + + if (ndx >= e->eo_seccnt) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + + sh = &e->eo_shdr[ndx]; + + ret_section->addr = sh->sh_addr; + ret_section->size = sh->sh_size; + + ret_section->name = elf_strptr(e->eo_elf, e->eo_strndx, sh->sh_name); + if (ret_section->name == NULL) { + if (error) + *error = DW_DLE_ELF; + return (DW_DLV_ERROR); + } + + return (DW_DLV_OK); +} + +Dwarf_Endianness +_dwarf_elf_get_byte_order(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + switch (e->eo_ehdr.e_ident[EI_DATA]) { + case ELFDATA2MSB: + return (DW_OBJECT_MSB); + + case ELFDATA2LSB: + case ELFDATANONE: + default: + return (DW_OBJECT_LSB); + } +} + +Dwarf_Small +_dwarf_elf_get_length_size(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + if (gelf_getclass(e->eo_elf) == ELFCLASS32) + return (4); + else if (e->eo_ehdr.e_machine == EM_MIPS) + return (8); + else + return (4); +} + +Dwarf_Small +_dwarf_elf_get_pointer_size(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + if (gelf_getclass(e->eo_elf) == ELFCLASS32) + return (4); + else + return (8); +} + +Dwarf_Unsigned +_dwarf_elf_get_section_count(void *obj) +{ + Dwarf_Elf_Object *e; + + e = obj; + assert(e != NULL); + + return (e->eo_seccnt); +} + +int +_dwarf_elf_load_section(void *obj, Dwarf_Half ndx, Dwarf_Small** ret_data, + int *error) +{ + Dwarf_Elf_Object *e; + Dwarf_Elf_Data *ed; + + e = obj; + assert(e != NULL); + + if (ret_data == NULL) { + if (error) + *error = DW_DLE_ARGUMENT; + return (DW_DLV_ERROR); + } + + if (ndx >= e->eo_seccnt) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + + ed = &e->eo_data[ndx]; + + if (ed->ed_alloc != NULL) + *ret_data = ed->ed_alloc; + else { + if (ed->ed_data == NULL) { + if (error) + *error = DW_DLE_NO_ENTRY; + return (DW_DLV_NO_ENTRY); + } + *ret_data = ed->ed_data->d_buf; + } + + return (DW_DLV_OK); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c new file mode 100644 index 0000000..1e374f2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c @@ -0,0 +1,334 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_elf_init.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); + +static const char *debug_name[] = { + ".debug_abbrev", + ".debug_aranges", + ".debug_frame", + ".debug_info", + ".debug_types", + ".debug_line", + ".debug_pubnames", + ".eh_frame", + ".debug_macinfo", + ".debug_str", + ".debug_loc", + ".debug_pubtypes", + ".debug_ranges", + ".debug_static_func", + ".debug_static_vars", + ".debug_typenames", + ".debug_weaknames", + NULL +}; + +static void +_dwarf_elf_apply_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data, + Elf_Data *symtab_data, int endian) +{ + Dwarf_Unsigned type; + GElf_Rela rela; + GElf_Sym sym; + size_t symndx; + uint64_t offset; + int size, j; + + j = 0; + while (gelf_getrela(rel_data, j++, &rela) != NULL) { + symndx = GELF_R_SYM(rela.r_info); + type = GELF_R_TYPE(rela.r_info); + + if (gelf_getsym(symtab_data, symndx, &sym) == NULL) + continue; + + offset = rela.r_offset; + size = _dwarf_get_reloc_size(dbg, type); + + if (endian == ELFDATA2MSB) + _dwarf_write_msb(buf, &offset, rela.r_addend, size); + else + _dwarf_write_lsb(buf, &offset, rela.r_addend, size); + } +} + +static int +_dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx, + size_t symtab, Elf_Data *symtab_data, Dwarf_Error *error) +{ + GElf_Ehdr eh; + GElf_Shdr sh; + Elf_Scn *scn; + Elf_Data *rel; + int elferr; + + if (symtab == 0 || symtab_data == NULL) + return (DW_DLE_NONE); + + if (gelf_getehdr(elf, &eh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + scn = NULL; + (void) elf_errno(); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + if (sh.sh_type != SHT_RELA || sh.sh_size == 0) + continue; + + if (sh.sh_info == shndx && sh.sh_link == symtab) { + if ((rel = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(NULL, error, + DW_DLE_ELF, elferr); + return (DW_DLE_ELF); + } else + return (DW_DLE_NONE); + } + + ed->ed_alloc = malloc(ed->ed_data->d_size); + if (ed->ed_alloc == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(ed->ed_alloc, ed->ed_data->d_buf, + ed->ed_data->d_size); + _dwarf_elf_apply_reloc(dbg, ed->ed_alloc, rel, + symtab_data, eh.e_ident[EI_DATA]); + + return (DW_DLE_NONE); + } + } + elferr = elf_errno(); + if (elferr != 0) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error) +{ + Dwarf_Obj_Access_Interface *iface; + Dwarf_Elf_Object *e; + const char *name; + GElf_Shdr sh; + Elf_Scn *scn; + Elf_Data *symtab_data; + size_t symtab_ndx; + int elferr, i, j, n, ret; + + ret = DW_DLE_NONE; + + if ((iface = calloc(1, sizeof(*iface))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((e = calloc(1, sizeof(*e))) == NULL) { + free(iface); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + e->eo_elf = elf; + e->eo_methods.get_section_info = _dwarf_elf_get_section_info; + e->eo_methods.get_byte_order = _dwarf_elf_get_byte_order; + e->eo_methods.get_length_size = _dwarf_elf_get_length_size; + e->eo_methods.get_pointer_size = _dwarf_elf_get_pointer_size; + e->eo_methods.get_section_count = _dwarf_elf_get_section_count; + e->eo_methods.load_section = _dwarf_elf_load_section; + + iface->object = e; + iface->methods = &e->eo_methods; + + dbg->dbg_iface = iface; + + if (gelf_getehdr(elf, &e->eo_ehdr) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + dbg->dbg_machine = e->eo_ehdr.e_machine; + + if (!elf_getshstrndx(elf, &e->eo_strndx)) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + n = 0; + symtab_ndx = 0; + symtab_data = NULL; + scn = NULL; + (void) elf_errno(); + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + if ((name = elf_strptr(elf, e->eo_strndx, sh.sh_name)) == + NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + if (!strcmp(name, ".symtab")) { + symtab_ndx = elf_ndxscn(scn); + if ((symtab_data = elf_getdata(scn, NULL)) == NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(NULL, error, + DW_DLE_ELF, elferr); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + } + continue; + } + + for (i = 0; debug_name[i] != NULL; i++) { + if (!strcmp(name, debug_name[i])) + n++; + } + } + elferr = elf_errno(); + if (elferr != 0) { + DWARF_SET_ELF_ERROR(dbg, error); + return (DW_DLE_ELF); + } + + e->eo_seccnt = n; + + if (n == 0) + return (DW_DLE_NONE); + + if ((e->eo_data = calloc(n, sizeof(Dwarf_Elf_Data))) == NULL || + (e->eo_shdr = calloc(n, sizeof(GElf_Shdr))) == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + scn = NULL; + j = 0; + while ((scn = elf_nextscn(elf, scn)) != NULL && j < n) { + if (gelf_getshdr(scn, &sh) == NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + memcpy(&e->eo_shdr[j], &sh, sizeof(sh)); + + if ((name = elf_strptr(elf, e->eo_strndx, sh.sh_name)) == + NULL) { + DWARF_SET_ELF_ERROR(dbg, error); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + + for (i = 0; debug_name[i] != NULL; i++) { + if (strcmp(name, debug_name[i])) + continue; + + (void) elf_errno(); + if ((e->eo_data[j].ed_data = elf_getdata(scn, NULL)) == + NULL) { + elferr = elf_errno(); + if (elferr != 0) { + _DWARF_SET_ERROR(dbg, error, + DW_DLE_ELF, elferr); + ret = DW_DLE_ELF; + goto fail_cleanup; + } + } + + if (_libdwarf.applyrela) { + if (_dwarf_elf_relocate(dbg, elf, + &e->eo_data[j], elf_ndxscn(scn), symtab_ndx, + symtab_data, error) != DW_DLE_NONE) + goto fail_cleanup; + } + + j++; + } + } + + assert(j == n); + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_elf_deinit(dbg); + + return (ret); +} + +void +_dwarf_elf_deinit(Dwarf_Debug dbg) +{ + Dwarf_Obj_Access_Interface *iface; + Dwarf_Elf_Object *e; + int i; + + iface = dbg->dbg_iface; + assert(iface != NULL); + + e = iface->object; + assert(e != NULL); + + if (e->eo_data) { + for (i = 0; (Dwarf_Unsigned) i < e->eo_seccnt; i++) { + if (e->eo_data[i].ed_alloc) + free(e->eo_data[i].ed_alloc); + } + free(e->eo_data); + } + if (e->eo_shdr) + free(e->eo_shdr); + + free(e); + free(iface); + + dbg->dbg_iface = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_error.c b/contrib/elftoolchain/libdwarf/libdwarf_error.c new file mode 100644 index 0000000..da16029 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_error.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_error.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +void +_dwarf_set_error(Dwarf_Debug dbg, Dwarf_Error *error, int errorcode, + int elferrorcode, const char *functionname, int linenumber) +{ + Dwarf_Error de; + + de.err_error = errorcode; + de.err_elferror = elferrorcode; + de.err_func = functionname; + de.err_line = linenumber; + de.err_msg[0] = '\0'; + + /* + * If the user supplied a destination for the error, copy the + * error descriptor over and return. Otherwise, if the debug + * context is known and has an error handler, invoke that. + * Otherwise, if a 'default' error handler was registered, + * invoke it. + */ + if (error) + *error = de; + else if (dbg && dbg->dbg_errhand) + dbg->dbg_errhand(de, dbg->dbg_errarg); + else if (_libdwarf.errhand) + _libdwarf.errhand(de, _libdwarf.errarg); + + /* No handler found, do nothing. */ +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_frame.c b/contrib/elftoolchain/libdwarf/libdwarf_frame.c new file mode 100644 index 0000000..375d64f --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_frame.c @@ -0,0 +1,1593 @@ +/*- + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_frame.c 2529 2012-07-29 23:31:12Z kaiwang27 $"); + +static int +_dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, + Dwarf_Cie *ret_cie) +{ + Dwarf_Cie cie; + + STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { + if (cie->cie_offset == offset) + break; + } + + if (cie == NULL) + return (DW_DLE_NO_ENTRY); + + if (ret_cie != NULL) + *ret_cie = cie; + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data, + uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, Dwarf_Error *error) +{ + uint8_t application; + + if (encode == DW_EH_PE_omit) + return (DW_DLE_NONE); + + application = encode & 0xf0; + encode &= 0x0f; + + switch (encode) { + case DW_EH_PE_absptr: + *val = dbg->read(data, offsetp, dbg->dbg_pointer_size); + break; + case DW_EH_PE_uleb128: + *val = _dwarf_read_uleb128(data, offsetp); + break; + case DW_EH_PE_udata2: + *val = dbg->read(data, offsetp, 2); + break; + case DW_EH_PE_udata4: + *val = dbg->read(data, offsetp, 4); + break; + case DW_EH_PE_udata8: + *val = dbg->read(data, offsetp, 8); + break; + case DW_EH_PE_sleb128: + *val = _dwarf_read_sleb128(data, offsetp); + break; + case DW_EH_PE_sdata2: + *val = (int16_t) dbg->read(data, offsetp, 2); + break; + case DW_EH_PE_sdata4: + *val = (int32_t) dbg->read(data, offsetp, 4); + break; + case DW_EH_PE_sdata8: + *val = dbg->read(data, offsetp, 8); + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + } + + if (application == DW_EH_PE_pcrel) { + /* + * Value is relative to .eh_frame section virtual addr. + */ + switch (encode) { + case DW_EH_PE_uleb128: + case DW_EH_PE_udata2: + case DW_EH_PE_udata4: + case DW_EH_PE_udata8: + *val += pc; + break; + case DW_EH_PE_sleb128: + case DW_EH_PE_sdata2: + case DW_EH_PE_sdata4: + case DW_EH_PE_sdata8: + *val = pc + (int64_t) *val; + break; + default: + /* DW_EH_PE_absptr is absolute value. */ + break; + } + } + + /* XXX Applications other than DW_EH_PE_pcrel are not handled. */ + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie, + Dwarf_Error *error) +{ + uint8_t *aug_p, *augdata_p; + uint64_t val, offset; + uint8_t encode; + int ret; + + assert(cie->cie_augment != NULL && *cie->cie_augment == 'z'); + + /* + * Here we're only interested in the presence of augment 'R' + * and associated CIE augment data, which describes the + * encoding scheme of FDE PC begin and range. + */ + aug_p = &cie->cie_augment[1]; + augdata_p = cie->cie_augdata; + while (*aug_p != '\0') { + switch (*aug_p) { + case 'L': + /* Skip one augment in augment data. */ + augdata_p++; + break; + case 'P': + /* Skip two augments in augment data. */ + encode = *augdata_p++; + offset = 0; + ret = _dwarf_frame_read_lsb_encoded(dbg, &val, + augdata_p, &offset, encode, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + augdata_p += offset; + break; + case 'R': + cie->cie_fde_encode = *augdata_p++; + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); + } + aug_p++; + } + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, + Dwarf_Unsigned *off, Dwarf_Cie *ret_cie, Dwarf_Error *error) +{ + Dwarf_Cie cie; + uint64_t length; + int dwarf_size, ret; + char *p; + + /* Check if we already added this CIE. */ + if (_dwarf_frame_find_cie(fs, *off, &cie) != DW_DLE_NO_ENTRY) { + *off += cie->cie_length + 4; + return (DW_DLE_NONE); + } + + if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&fs->fs_cielist, cie, cie_next); + + cie->cie_dbg = dbg; + cie->cie_index = fs->fs_cielen; + cie->cie_offset = *off; + + length = dbg->read(ds->ds_data, off, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, off, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - *off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + } + + (void) dbg->read(ds->ds_data, off, dwarf_size); /* Skip CIE id. */ + cie->cie_length = length; + + cie->cie_version = dbg->read(ds->ds_data, off, 1); + if (cie->cie_version != 1 && cie->cie_version != 3 && + cie->cie_version != 4) { + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_VERSION_BAD); + return (DW_DLE_FRAME_VERSION_BAD); + } + + cie->cie_augment = ds->ds_data + *off; + p = (char *) ds->ds_data; + while (p[(*off)++] != '\0') + ; + + /* We only recognize normal .dwarf_frame and GNU .eh_frame sections. */ + if (*cie->cie_augment != 0 && *cie->cie_augment != 'z') { + *off = cie->cie_offset + ((dwarf_size == 4) ? 4 : 12) + + cie->cie_length; + return (DW_DLE_NONE); + } + + /* Optional EH Data field for .eh_frame section. */ + if (strstr((char *)cie->cie_augment, "eh") != NULL) + cie->cie_ehdata = dbg->read(ds->ds_data, off, + dbg->dbg_pointer_size); + + cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off); + cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off); + + /* Return address register. */ + if (cie->cie_version == 1) + cie->cie_ra = dbg->read(ds->ds_data, off, 1); + else + cie->cie_ra = _dwarf_read_uleb128(ds->ds_data, off); + + /* Optional CIE augmentation data for .eh_frame section. */ + if (*cie->cie_augment == 'z') { + cie->cie_auglen = _dwarf_read_uleb128(ds->ds_data, off); + cie->cie_augdata = ds->ds_data + *off; + *off += cie->cie_auglen; + /* + * XXX Use DW_EH_PE_absptr for default FDE PC start/range, + * in case _dwarf_frame_parse_lsb_cie_augment fails to + * find out the real encode. + */ + cie->cie_fde_encode = DW_EH_PE_absptr; + ret = _dwarf_frame_parse_lsb_cie_augment(dbg, cie, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + /* CIE Initial instructions. */ + cie->cie_initinst = ds->ds_data + *off; + if (dwarf_size == 4) + cie->cie_instlen = cie->cie_offset + 4 + length - *off; + else + cie->cie_instlen = cie->cie_offset + 12 + length - *off; + + *off += cie->cie_instlen; + +#ifdef FRAME_DEBUG + printf("cie:\n"); + printf("\tcie_version=%u cie_offset=%ju cie_length=%ju cie_augment=%s" + " cie_instlen=%ju cie->cie_caf=%ju cie->cie_daf=%jd off=%ju\n", + cie->cie_version, cie->cie_offset, cie->cie_length, + (char *)cie->cie_augment, cie->cie_instlen, cie->cie_caf, + cie->cie_daf, *off); +#endif + + if (ret_cie != NULL) + *ret_cie = cie; + + fs->fs_cielen++; + + return (DW_DLE_NONE); +} + +static int +_dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, + Dwarf_Unsigned *off, int eh_frame, Dwarf_Error *error) +{ + Dwarf_Cie cie; + Dwarf_Fde fde; + Dwarf_Unsigned cieoff; + uint64_t length, val; + int dwarf_size, ret; + + if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&fs->fs_fdelist, fde, fde_next); + + fde->fde_dbg = dbg; + fde->fde_fs = fs; + fde->fde_addr = ds->ds_data + *off; + fde->fde_offset = *off; + + length = dbg->read(ds->ds_data, off, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, off, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - *off) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + } + + fde->fde_length = length; + + if (eh_frame) { + fde->fde_cieoff = dbg->read(ds->ds_data, off, 4); + cieoff = *off - (4 + fde->fde_cieoff); + /* This delta should never be 0. */ + if (cieoff == fde->fde_offset) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_CIE_FOR_FDE); + return (DW_DLE_NO_CIE_FOR_FDE); + } + } else { + fde->fde_cieoff = dbg->read(ds->ds_data, off, dwarf_size); + cieoff = fde->fde_cieoff; + } + + if (_dwarf_frame_find_cie(fs, cieoff, &cie) == + DW_DLE_NO_ENTRY) { + ret = _dwarf_frame_add_cie(dbg, fs, ds, &cieoff, &cie, + error); + if (ret != DW_DLE_NONE) + return (ret); + } + fde->fde_cie = cie; + if (eh_frame) { + /* + * The FDE PC start/range for .eh_frame is encoded according + * to the LSB spec's extension to DWARF2. + */ + ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data, + off, cie->cie_fde_encode, ds->ds_addr + *off, error); + if (ret != DW_DLE_NONE) + return (ret); + fde->fde_initloc = val; + /* + * FDE PC range should not be relative value to anything. + * So pass 0 for pc value. + */ + ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data, + off, cie->cie_fde_encode, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + fde->fde_adrange = val; + } else { + fde->fde_initloc = dbg->read(ds->ds_data, off, + dbg->dbg_pointer_size); + fde->fde_adrange = dbg->read(ds->ds_data, off, + dbg->dbg_pointer_size); + } + + /* Optional FDE augmentation data for .eh_frame section. (ignored) */ + if (eh_frame && *cie->cie_augment == 'z') { + fde->fde_auglen = _dwarf_read_uleb128(ds->ds_data, off); + fde->fde_augdata = ds->ds_data + *off; + *off += fde->fde_auglen; + } + + fde->fde_inst = ds->ds_data + *off; + if (dwarf_size == 4) + fde->fde_instlen = fde->fde_offset + 4 + length - *off; + else + fde->fde_instlen = fde->fde_offset + 12 + length - *off; + + *off += fde->fde_instlen; + +#ifdef FRAME_DEBUG + printf("fde:"); + if (eh_frame) + printf("(eh_frame)"); + putchar('\n'); + printf("\tfde_offset=%ju fde_length=%ju fde_cieoff=%ju" + " fde_instlen=%ju off=%ju\n", fde->fde_offset, fde->fde_length, + fde->fde_cieoff, fde->fde_instlen, *off); +#endif + + fs->fs_fdelen++; + + return (DW_DLE_NONE); +} + +static void +_dwarf_frame_section_cleanup(Dwarf_FrameSec fs) +{ + Dwarf_Cie cie, tcie; + Dwarf_Fde fde, tfde; + + STAILQ_FOREACH_SAFE(cie, &fs->fs_cielist, cie_next, tcie) { + STAILQ_REMOVE(&fs->fs_cielist, cie, _Dwarf_Cie, cie_next); + free(cie); + } + + STAILQ_FOREACH_SAFE(fde, &fs->fs_fdelist, fde_next, tfde) { + STAILQ_REMOVE(&fs->fs_fdelist, fde, _Dwarf_Fde, fde_next); + free(fde); + } + + if (fs->fs_ciearray != NULL) + free(fs->fs_ciearray); + if (fs->fs_fdearray != NULL) + free(fs->fs_fdearray); + + free(fs); +} + +static int +_dwarf_frame_section_init(Dwarf_Debug dbg, Dwarf_FrameSec *frame_sec, + Dwarf_Section *ds, int eh_frame, Dwarf_Error *error) +{ + Dwarf_FrameSec fs; + Dwarf_Cie cie; + Dwarf_Fde fde; + uint64_t length, offset, cie_id, entry_off; + int dwarf_size, i, ret; + + assert(frame_sec != NULL); + assert(*frame_sec == NULL); + + if ((fs = calloc(1, sizeof(struct _Dwarf_FrameSec))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&fs->fs_cielist); + STAILQ_INIT(&fs->fs_fdelist); + + offset = 0; + while (offset < ds->ds_size) { + entry_off = offset; + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - offset || + (length == 0 && !eh_frame)) { + DWARF_SET_ERROR(dbg, error, + DW_DLE_DEBUG_FRAME_LENGTH_BAD); + return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + } + + /* Check terminator for .eh_frame */ + if (eh_frame && length == 0) + break; + + cie_id = dbg->read(ds->ds_data, &offset, dwarf_size); + + if (eh_frame) { + /* GNU .eh_frame use CIE id 0. */ + if (cie_id == 0) + ret = _dwarf_frame_add_cie(dbg, fs, ds, + &entry_off, NULL, error); + else + ret = _dwarf_frame_add_fde(dbg, fs, ds, + &entry_off, 1, error); + } else { + /* .dwarf_frame use CIE id ~0 */ + if ((dwarf_size == 4 && cie_id == ~0U) || + (dwarf_size == 8 && cie_id == ~0ULL)) + ret = _dwarf_frame_add_cie(dbg, fs, ds, + &entry_off, NULL, error); + else + ret = _dwarf_frame_add_fde(dbg, fs, ds, + &entry_off, 0, error); + } + + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + offset = entry_off; + } + + /* Create CIE array. */ + if (fs->fs_cielen > 0) { + if ((fs->fs_ciearray = malloc(sizeof(Dwarf_Cie) * + fs->fs_cielen)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + i = 0; + STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { + fs->fs_ciearray[i++] = cie; + } + assert((Dwarf_Unsigned)i == fs->fs_cielen); + } + + /* Create FDE array. */ + if (fs->fs_fdelen > 0) { + if ((fs->fs_fdearray = malloc(sizeof(Dwarf_Fde) * + fs->fs_fdelen)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + i = 0; + STAILQ_FOREACH(fde, &fs->fs_fdelist, fde_next) { + fs->fs_fdearray[i++] = fde; + } + assert((Dwarf_Unsigned)i == fs->fs_fdelen); + } + + *frame_sec = fs; + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_frame_section_cleanup(fs); + + return (ret); +} + +static int +_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, + Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error) +{ + Dwarf_Regtable3 *init_rt, *saved_rt; + uint8_t *p, *pe; + uint8_t high2, low6; + uint64_t reg, reg2, uoff, soff; + int ret; + +#define CFA rt->rt3_cfa_rule +#define INITCFA init_rt->rt3_cfa_rule +#define RL rt->rt3_rules +#define INITRL init_rt->rt3_rules + +#define CHECK_TABLE_SIZE(x) \ + do { \ + if ((x) >= rt->rt3_reg_table_size) { \ + DWARF_SET_ERROR(dbg, error, \ + DW_DLE_DF_REG_NUM_TOO_HIGH); \ + ret = DW_DLE_DF_REG_NUM_TOO_HIGH; \ + goto program_done; \ + } \ + } while(0) + +#ifdef FRAME_DEBUG + printf("frame_run_inst: (caf=%ju, daf=%jd)\n", caf, daf); +#endif + + ret = DW_DLE_NONE; + init_rt = saved_rt = NULL; + *row_pc = pc; + + /* Save a copy of the table as initial state. */ + _dwarf_frame_regtable_copy(dbg, &init_rt, rt, error); + + p = insts; + pe = p + len; + + while (p < pe) { + +#ifdef FRAME_DEBUG + printf("p=%p pe=%p pc=%#jx pc_req=%#jx\n", p, pe, pc, pc_req); +#endif + + if (*p == DW_CFA_nop) { +#ifdef FRAME_DEBUG + printf("DW_CFA_nop\n"); +#endif + p++; + continue; + } + + high2 = *p & 0xc0; + low6 = *p & 0x3f; + p++; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + pc += low6 * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_advance_loc(%#jx(%u))\n", pc, + low6); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_offset: + *row_pc = pc; + CHECK_TABLE_SIZE(low6); + RL[low6].dw_offset_relevant = 1; + RL[low6].dw_value_type = DW_EXPR_OFFSET; + RL[low6].dw_regnum = dbg->dbg_frame_cfa_value; + RL[low6].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p) * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset(%jd)\n", + RL[low6].dw_offset_or_block_len); +#endif + break; + case DW_CFA_restore: + *row_pc = pc; + CHECK_TABLE_SIZE(low6); + memcpy(&RL[low6], &INITRL[low6], + sizeof(Dwarf_Regtable_Entry3)); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore(%u)\n", low6); +#endif + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; + goto program_done; + } + + continue; + } + + switch (low6) { + case DW_CFA_set_loc: + pc = dbg->decode(&p, dbg->dbg_pointer_size); +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc1: + pc += dbg->decode(&p, 1) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc1(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc2: + pc += dbg->decode(&p, 2) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc2(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_advance_loc4: + pc += dbg->decode(&p, 4) * caf; +#ifdef FRAME_DEBUG + printf("DW_CFA_set_loc4(pc=%#jx)\n", pc); +#endif + if (pc_req < pc) + goto program_done; + break; + case DW_CFA_offset_extended: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = uoff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset_extended(reg=%ju,uoff=%ju)\n", + reg, uoff); +#endif + break; + case DW_CFA_restore_extended: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + memcpy(&RL[reg], &INITRL[reg], + sizeof(Dwarf_Regtable_Entry3)); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore_extended(%ju)\n", reg); +#endif + break; + case DW_CFA_undefined: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = dbg->dbg_frame_undefined_value; +#ifdef FRAME_DEBUG + printf("DW_CFA_undefined(%ju)\n", reg); +#endif + break; + case DW_CFA_same_value: + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = dbg->dbg_frame_same_value; +#ifdef FRAME_DEBUG + printf("DW_CFA_same_value(%ju)\n", reg); +#endif + break; + case DW_CFA_register: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + reg2 = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_regnum = reg2; +#ifdef FRAME_DEBUG + printf("DW_CFA_register(reg=%ju,reg2=%ju)\n", reg, + reg2); +#endif + break; + case DW_CFA_remember_state: + _dwarf_frame_regtable_copy(dbg, &saved_rt, rt, error); +#ifdef FRAME_DEBUG + printf("DW_CFA_remember_state\n"); +#endif + break; + case DW_CFA_restore_state: + *row_pc = pc; + _dwarf_frame_regtable_copy(dbg, &rt, saved_rt, error); +#ifdef FRAME_DEBUG + printf("DW_CFA_restore_state\n"); +#endif + break; + case DW_CFA_def_cfa: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_regnum = reg; + CFA.dw_offset_or_block_len = uoff; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa(reg=%ju,uoff=%ju)\n", reg, uoff); +#endif + break; + case DW_CFA_def_cfa_register: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CFA.dw_regnum = reg; + /* + * Note that DW_CFA_def_cfa_register change the CFA + * rule register while keep the old offset. So we + * should not touch the CFA.dw_offset_relevant flag + * here. + */ +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_register(%ju)\n", reg); +#endif + break; + case DW_CFA_def_cfa_offset: + *row_pc = pc; + uoff = _dwarf_decode_uleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_offset_or_block_len = uoff; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_offset(%ju)\n", uoff); +#endif + break; + case DW_CFA_def_cfa_expression: + *row_pc = pc; + CFA.dw_offset_relevant = 0; + CFA.dw_value_type = DW_EXPR_EXPRESSION; + CFA.dw_offset_or_block_len = _dwarf_decode_uleb128(&p); + CFA.dw_block_ptr = p; + p += CFA.dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_expression\n"); +#endif + break; + case DW_CFA_expression: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_value_type = DW_EXPR_EXPRESSION; + RL[reg].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p); + RL[reg].dw_block_ptr = p; + p += RL[reg].dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_expression\n"); +#endif + break; + case DW_CFA_offset_extended_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_offset_extended_sf(reg=%ju,soff=%jd)\n", + reg, soff); +#endif + break; + case DW_CFA_def_cfa_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_regnum = reg; + CFA.dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_sf(reg=%ju,soff=%jd)\n", reg, + soff); +#endif + break; + case DW_CFA_def_cfa_offset_sf: + *row_pc = pc; + soff = _dwarf_decode_sleb128(&p); + CFA.dw_offset_relevant = 1; + CFA.dw_value_type = DW_EXPR_OFFSET; + CFA.dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_def_cfa_offset_sf(soff=%jd)\n", soff); +#endif + break; + case DW_CFA_val_offset: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = uoff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_offset(reg=%ju,uoff=%ju)\n", reg, + uoff); +#endif + break; + case DW_CFA_val_offset_sf: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 1; + RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; + RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; + RL[reg].dw_offset_or_block_len = soff * daf; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_offset_sf(reg=%ju,soff=%jd)\n", reg, + soff); +#endif + break; + case DW_CFA_val_expression: + *row_pc = pc; + reg = _dwarf_decode_uleb128(&p); + CHECK_TABLE_SIZE(reg); + RL[reg].dw_offset_relevant = 0; + RL[reg].dw_value_type = DW_EXPR_VAL_EXPRESSION; + RL[reg].dw_offset_or_block_len = + _dwarf_decode_uleb128(&p); + RL[reg].dw_block_ptr = p; + p += RL[reg].dw_offset_or_block_len; +#ifdef FRAME_DEBUG + printf("DW_CFA_val_expression\n"); +#endif + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; + goto program_done; + } + } + +program_done: + + free(init_rt->rt3_rules); + free(init_rt); + if (saved_rt) { + free(saved_rt->rt3_rules); + free(saved_rt); + } + + return (ret); + +#undef CFA +#undef INITCFA +#undef RL +#undef INITRL +#undef CHECK_TABLE_SIZE +} + +static int +_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, + Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, Dwarf_Frame_Op3 *fop3, + Dwarf_Error *error) +{ + uint8_t *p, *pe; + uint8_t high2, low6; + uint64_t reg, reg2, uoff, soff, blen; + int ret; + +#define SET_BASE_OP(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_base_op = (x) >> 6; \ + if (fop3 != NULL) \ + fop3[*count].fp_base_op = (x) >> 6; \ + } while(0) + +#define SET_EXTENDED_OP(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_extended_op = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_extended_op = (x); \ + } while(0) + +#define SET_REGISTER(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_register = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_register = (x); \ + } while(0) + +#define SET_OFFSET(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_offset = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_offset_or_block_len = \ + (x); \ + } while(0) + +#define SET_INSTR_OFFSET(x) \ + do { \ + if (fop != NULL) \ + fop[*count].fp_instr_offset = (x); \ + if (fop3 != NULL) \ + fop3[*count].fp_instr_offset = (x); \ + } while(0) + +#define SET_BLOCK_LEN(x) \ + do { \ + if (fop3 != NULL) \ + fop3[*count].fp_offset_or_block_len = \ + (x); \ + } while(0) + +#define SET_EXPR_BLOCK(addr, len) \ + do { \ + if (fop3 != NULL) { \ + fop3[*count].fp_expr_block = \ + malloc((size_t) (len)); \ + if (fop3[*count].fp_expr_block == NULL) { \ + DWARF_SET_ERROR(dbg, error, \ + DW_DLE_MEMORY); \ + return (DW_DLE_MEMORY); \ + } \ + memcpy(&fop3[*count].fp_expr_block, \ + (addr), (len)); \ + } \ + } while(0) + + ret = DW_DLE_NONE; + *count = 0; + + p = insts; + pe = p + len; + + while (p < pe) { + + SET_INSTR_OFFSET(p - insts); + + if (*p == DW_CFA_nop) { + p++; + (*count)++; + continue; + } + + high2 = *p & 0xc0; + low6 = *p & 0x3f; + p++; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + SET_BASE_OP(high2); + SET_OFFSET(low6); + break; + case DW_CFA_offset: + SET_BASE_OP(high2); + SET_REGISTER(low6); + uoff = _dwarf_decode_uleb128(&p); + SET_OFFSET(uoff); + break; + case DW_CFA_restore: + SET_BASE_OP(high2); + SET_REGISTER(low6); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + (*count)++; + continue; + } + + SET_EXTENDED_OP(low6); + + switch (low6) { + case DW_CFA_set_loc: + uoff = dbg->decode(&p, dbg->dbg_pointer_size); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc1: + uoff = dbg->decode(&p, 1); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc2: + uoff = dbg->decode(&p, 2); + SET_OFFSET(uoff); + break; + case DW_CFA_advance_loc4: + uoff = dbg->decode(&p, 4); + SET_OFFSET(uoff); + break; + case DW_CFA_offset_extended: + case DW_CFA_def_cfa: + case DW_CFA_val_offset: + reg = _dwarf_decode_uleb128(&p); + uoff = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(uoff); + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_def_cfa_register: + reg = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + break; + case DW_CFA_register: + reg = _dwarf_decode_uleb128(&p); + reg2 = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(reg2); + break; + case DW_CFA_remember_state: + case DW_CFA_restore_state: + break; + case DW_CFA_def_cfa_offset: + uoff = _dwarf_decode_uleb128(&p); + SET_OFFSET(uoff); + break; + case DW_CFA_def_cfa_expression: + blen = _dwarf_decode_uleb128(&p); + SET_BLOCK_LEN(blen); + SET_EXPR_BLOCK(p, blen); + p += blen; + break; + case DW_CFA_expression: + case DW_CFA_val_expression: + reg = _dwarf_decode_uleb128(&p); + blen = _dwarf_decode_uleb128(&p); + SET_REGISTER(reg); + SET_BLOCK_LEN(blen); + SET_EXPR_BLOCK(p, blen); + p += blen; + break; + case DW_CFA_offset_extended_sf: + case DW_CFA_def_cfa_sf: + case DW_CFA_val_offset_sf: + reg = _dwarf_decode_uleb128(&p); + soff = _dwarf_decode_sleb128(&p); + SET_REGISTER(reg); + SET_OFFSET(soff); + break; + case DW_CFA_def_cfa_offset_sf: + soff = _dwarf_decode_sleb128(&p); + SET_OFFSET(soff); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + (*count)++; + } + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, + Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, Dwarf_Error *error) +{ + Dwarf_Frame_Op *oplist; + Dwarf_Unsigned count; + int ret; + + ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, NULL, NULL, + error); + if (ret != DW_DLE_NONE) + return (ret); + + if ((oplist = calloc(count, sizeof(Dwarf_Frame_Op))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, oplist, NULL, + error); + if (ret != DW_DLE_NONE) { + free(oplist); + return (ret); + } + + *ret_oplist = oplist; + *ret_opcnt = count; + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_regtable_copy(Dwarf_Debug dbg, Dwarf_Regtable3 **dest, + Dwarf_Regtable3 *src, Dwarf_Error *error) +{ + int i; + + assert(dest != NULL); + assert(src != NULL); + + if (*dest == NULL) { + if ((*dest = malloc(sizeof(Dwarf_Regtable3))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + (*dest)->rt3_reg_table_size = src->rt3_reg_table_size; + (*dest)->rt3_rules = malloc(src->rt3_reg_table_size * + sizeof(Dwarf_Regtable_Entry3)); + if ((*dest)->rt3_rules == NULL) { + free(*dest); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + memcpy(&(*dest)->rt3_cfa_rule, &src->rt3_cfa_rule, + sizeof(Dwarf_Regtable_Entry3)); + + for (i = 0; i < (*dest)->rt3_reg_table_size && + i < src->rt3_reg_table_size; i++) + memcpy(&(*dest)->rt3_rules[i], &src->rt3_rules[i], + sizeof(Dwarf_Regtable_Entry3)); + + for (; i < (*dest)->rt3_reg_table_size; i++) + (*dest)->rt3_rules[i].dw_regnum = + dbg->dbg_frame_undefined_value; + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req, + Dwarf_Regtable3 **ret_rt, Dwarf_Addr *ret_row_pc, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Cie cie; + Dwarf_Regtable3 *rt; + Dwarf_Addr row_pc; + int i, ret; + + assert(ret_rt != NULL); + + dbg = fde->fde_dbg; + assert(dbg != NULL); + + rt = dbg->dbg_internal_reg_table; + + /* Clear the content of regtable from previous run. */ + memset(&rt->rt3_cfa_rule, 0, sizeof(Dwarf_Regtable_Entry3)); + memset(rt->rt3_rules, 0, rt->rt3_reg_table_size * + sizeof(Dwarf_Regtable_Entry3)); + + /* Set rules to initial values. */ + for (i = 0; i < rt->rt3_reg_table_size; i++) + rt->rt3_rules[i].dw_regnum = dbg->dbg_frame_rule_initial_value; + + /* Run initial instructions in CIE. */ + cie = fde->fde_cie; + assert(cie != NULL); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_initinst, + cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, ~0ULL, + &row_pc, error); + if (ret != DW_DLE_NONE) + return (ret); + + /* Run instructions in FDE. */ + if (pc_req >= fde->fde_initloc) { + ret = _dwarf_frame_run_inst(dbg, rt, fde->fde_inst, + fde->fde_instlen, cie->cie_caf, cie->cie_daf, + fde->fde_initloc, pc_req, &row_pc, error); + if (ret != DW_DLE_NONE) + return (ret); + } + + *ret_rt = rt; + *ret_row_pc = row_pc; + + return (DW_DLE_NONE); +} + +void +_dwarf_frame_cleanup(Dwarf_Debug dbg) +{ + Dwarf_Regtable3 *rt; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + if (dbg->dbg_internal_reg_table) { + rt = dbg->dbg_internal_reg_table; + free(rt->rt3_rules); + free(rt); + dbg->dbg_internal_reg_table = NULL; + } + + if (dbg->dbg_frame) { + _dwarf_frame_section_cleanup(dbg->dbg_frame); + dbg->dbg_frame = NULL; + } + + if (dbg->dbg_eh_frame) { + _dwarf_frame_section_cleanup(dbg->dbg_eh_frame); + dbg->dbg_eh_frame = NULL; + } +} + +int +_dwarf_frame_section_load(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if ((ds = _dwarf_find_section(dbg, ".debug_frame")) != NULL) { + return (_dwarf_frame_section_init(dbg, &dbg->dbg_frame, + ds, 0, error)); + } + + return (DW_DLE_NONE); +} + +int +_dwarf_frame_section_load_eh(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + if ((ds = _dwarf_find_section(dbg, ".eh_frame")) != NULL) { + return (_dwarf_frame_section_init(dbg, &dbg->dbg_eh_frame, + ds, 1, error)); + } + + return (DW_DLE_NONE); +} + +void +_dwarf_frame_params_init(Dwarf_Debug dbg) +{ + + /* Initialise call frame related parameters. */ + dbg->dbg_frame_rule_table_size = DW_FRAME_LAST_REG_NUM; + dbg->dbg_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; + dbg->dbg_frame_cfa_value = DW_FRAME_CFA_COL3; + dbg->dbg_frame_same_value = DW_FRAME_SAME_VAL; + dbg->dbg_frame_undefined_value = DW_FRAME_UNDEFINED_VAL; +} + +int +_dwarf_frame_interal_table_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Regtable3 *rt; + + if (dbg->dbg_internal_reg_table != NULL) + return (DW_DLE_NONE); + + /* Initialise internal register table. */ + if ((rt = calloc(1, sizeof(Dwarf_Regtable3))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + rt->rt3_reg_table_size = dbg->dbg_frame_rule_table_size; + if ((rt->rt3_rules = calloc(rt->rt3_reg_table_size, + sizeof(Dwarf_Regtable_Entry3))) == NULL) { + free(rt); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_internal_reg_table = rt; + + return (DW_DLE_NONE); +} + +#define _FDE_INST_INIT_SIZE 128 + +int +_dwarf_frame_fde_add_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, + Dwarf_Unsigned val2, Dwarf_Error *error) +{ + Dwarf_P_Debug dbg; + uint8_t high2, low6; + int ret; + +#define ds fde +#define ds_data fde_inst +#define ds_cap fde_instcap +#define ds_size fde_instlen + + assert(fde != NULL && fde->fde_dbg != NULL); + dbg = fde->fde_dbg; + + if (fde->fde_inst == NULL) { + fde->fde_instcap = _FDE_INST_INIT_SIZE; + fde->fde_instlen = 0; + if ((fde->fde_inst = malloc((size_t) fde->fde_instcap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + assert(fde->fde_instcap != 0); + + RCHECK(WRITE_VALUE(op, 1)); + if (op == DW_CFA_nop) + return (DW_DLE_NONE); + + high2 = op & 0xc0; + low6 = op & 0x3f; + + if (high2 > 0) { + switch (high2) { + case DW_CFA_advance_loc: + case DW_CFA_restore: + break; + case DW_CFA_offset: + RCHECK(WRITE_ULEB128(val1)); + break; + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + return (DW_DLE_NONE); + } + + switch (low6) { + case DW_CFA_set_loc: + RCHECK(WRITE_VALUE(val1, dbg->dbg_pointer_size)); + break; + case DW_CFA_advance_loc1: + RCHECK(WRITE_VALUE(val1, 1)); + break; + case DW_CFA_advance_loc2: + RCHECK(WRITE_VALUE(val1, 2)); + break; + case DW_CFA_advance_loc4: + RCHECK(WRITE_VALUE(val1, 4)); + break; + case DW_CFA_offset_extended: + case DW_CFA_def_cfa: + case DW_CFA_register: + RCHECK(WRITE_ULEB128(val1)); + RCHECK(WRITE_ULEB128(val2)); + break; + case DW_CFA_restore_extended: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_def_cfa_register: + case DW_CFA_def_cfa_offset: + RCHECK(WRITE_ULEB128(val1)); + break; + case DW_CFA_remember_state: + case DW_CFA_restore_state: + break; + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); + return (DW_DLE_FRAME_INSTR_EXEC_ERROR); + } + + return (DW_DLE_NONE); + +gen_fail: + return (ret); + +#undef ds +#undef ds_data +#undef ds_cap +#undef ds_size +} + +static int +_dwarf_frame_gen_cie(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_P_Cie cie, + Dwarf_Error *error) +{ + Dwarf_Unsigned len; + uint64_t offset; + int ret; + + assert(dbg != NULL && ds != NULL && cie != NULL); + + cie->cie_offset = offset = ds->ds_size; + cie->cie_length = 0; + cie->cie_version = 1; + + /* Length placeholder. */ + RCHECK(WRITE_VALUE(cie->cie_length, 4)); + + /* .debug_frame use CIE id ~0. */ + RCHECK(WRITE_VALUE(~0U, 4)); + + /* .debug_frame version is 1. (DWARF2) */ + RCHECK(WRITE_VALUE(cie->cie_version, 1)); + + /* Write augmentation, if present. */ + if (cie->cie_augment != NULL) + RCHECK(WRITE_BLOCK(cie->cie_augment, + strlen((char *) cie->cie_augment) + 1)); + else + RCHECK(WRITE_VALUE(0, 1)); + + /* Write caf, daf and ra. */ + RCHECK(WRITE_ULEB128(cie->cie_caf)); + RCHECK(WRITE_SLEB128(cie->cie_daf)); + RCHECK(WRITE_VALUE(cie->cie_ra, 1)); + + /* Write initial instructions, if present. */ + if (cie->cie_initinst != NULL) + RCHECK(WRITE_BLOCK(cie->cie_initinst, cie->cie_instlen)); + + /* Add padding. */ + len = ds->ds_size - cie->cie_offset - 4; + cie->cie_length = roundup(len, dbg->dbg_pointer_size); + while (len++ < cie->cie_length) + RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); + + /* Fill in the length field. */ + dbg->write(ds->ds_data, &offset, cie->cie_length, 4); + + return (DW_DLE_NONE); + +gen_fail: + return (ret); +} + +static int +_dwarf_frame_gen_fde(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Rel_Section drs, Dwarf_P_Fde fde, Dwarf_Error *error) +{ + Dwarf_Unsigned len; + uint64_t offset; + int ret; + + assert(dbg != NULL && ds != NULL && drs != NULL); + assert(fde != NULL && fde->fde_cie != NULL); + + fde->fde_offset = offset = ds->ds_size; + fde->fde_length = 0; + fde->fde_cieoff = fde->fde_cie->cie_offset; + + /* Length placeholder. */ + RCHECK(WRITE_VALUE(fde->fde_length, 4)); + + /* Write CIE pointer. */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, fde->fde_cieoff, ".debug_frame", error)); + + /* Write FDE initial location. */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, + dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, + fde->fde_initloc, NULL, error)); + + /* + * Write FDE address range. Use a pair of relocation entries if + * application provided end symbol index. Otherwise write the + * length without assoicating any relocation info. + */ + if (fde->fde_esymndx > 0) + RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds, + dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, + fde->fde_esymndx, fde->fde_initloc, fde->fde_eoff, error)); + else + RCHECK(WRITE_VALUE(fde->fde_adrange, dbg->dbg_pointer_size)); + + /* Write FDE frame instructions. */ + RCHECK(WRITE_BLOCK(fde->fde_inst, fde->fde_instlen)); + + /* Add padding. */ + len = ds->ds_size - fde->fde_offset - 4; + fde->fde_length = roundup(len, dbg->dbg_pointer_size); + while (len++ < fde->fde_length) + RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); + + /* Fill in the length field. */ + dbg->write(ds->ds_data, &offset, fde->fde_length, 4); + + return (DW_DLE_NONE); + +gen_fail: + return (ret); +} + +int +_dwarf_frame_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_P_Cie cie; + Dwarf_P_Fde fde; + int ret; + + if (STAILQ_EMPTY(&dbg->dbgp_cielist)) + return (DW_DLE_NONE); + + /* Create .debug_frame section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_frame", 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for .debug_frame */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Generate list of CIE. */ + STAILQ_FOREACH(cie, &dbg->dbgp_cielist, cie_next) + RCHECK(_dwarf_frame_gen_cie(dbg, ds, cie, error)); + + /* Generate list of FDE. */ + STAILQ_FOREACH(fde, &dbg->dbgp_fdelist, fde_next) + RCHECK(_dwarf_frame_gen_fde(dbg, ds, drs, fde, error)); + + /* Inform application the creation of .debug_frame ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_frame */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_frame_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Cie cie, tcie; + Dwarf_P_Fde fde, tfde; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(cie, &dbg->dbgp_cielist, cie_next, tcie) { + STAILQ_REMOVE(&dbg->dbgp_cielist, cie, _Dwarf_Cie, cie_next); + if (cie->cie_augment) + free(cie->cie_augment); + if (cie->cie_initinst) + free(cie->cie_initinst); + free(cie); + } + dbg->dbgp_cielen = 0; + + STAILQ_FOREACH_SAFE(fde, &dbg->dbgp_fdelist, fde_next, tfde) { + STAILQ_REMOVE(&dbg->dbgp_fdelist, fde, _Dwarf_Fde, fde_next); + if (fde->fde_inst != NULL) + free(fde->fde_inst); + free(fde); + } + dbg->dbgp_fdelen = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_info.c b/contrib/elftoolchain/libdwarf/libdwarf_info.c new file mode 100644 index 0000000..dc82b7d --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_info.c @@ -0,0 +1,281 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2010,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_info.c 2942 2013-05-04 23:03:54Z kaiwang27 $"); + +int +_dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_cu_current == NULL); + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu != NULL) { + dbg->dbg_cu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_info_loaded) + return (DW_DLE_NO_ENTRY); + + dbg->dbg_info_off = 0; + ret = _dwarf_info_load(dbg, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_cu_current = STAILQ_FIRST(&dbg->dbg_cu); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_cu_current != NULL); + cu = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); + if (cu != NULL) { + dbg->dbg_cu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_info_loaded) { + dbg->dbg_cu_current = NULL; + return (DW_DLE_NO_ENTRY); + } + + ret = _dwarf_info_load(dbg, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_cu_current = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_Section *ds; + int dwarf_size, ret; + uint64_t length; + uint64_t next_offset; + uint64_t offset; + + ret = DW_DLE_NONE; + if (dbg->dbg_info_loaded) + return (DW_DLE_NONE); + + offset = dbg->dbg_info_off; + ds = dbg->dbg_info_sec; + assert(ds != NULL); + while (offset < ds->ds_size) { + if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + cu->cu_dbg = dbg; + cu->cu_offset = offset; + + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + length = dbg->read(ds->ds_data, &offset, 8); + dwarf_size = 8; + } else + dwarf_size = 4; + cu->cu_dwarf_size = dwarf_size; + + /* + * Check if there is enough ELF data for this CU. This assumes + * that libelf gives us the entire section in one Elf_Data + * object. + */ + if (length > ds->ds_size - offset) { + free(cu); + DWARF_SET_ERROR(dbg, error, DW_DLE_CU_LENGTH_ERROR); + return (DW_DLE_CU_LENGTH_ERROR); + } + + /* Compute the offset to the next compilation unit: */ + next_offset = offset + length; + dbg->dbg_info_off = next_offset; + + /* Initialise the compilation unit. */ + cu->cu_length = length; + cu->cu_length_size = (dwarf_size == 4 ? 4 : 12); + cu->cu_version = dbg->read(ds->ds_data, &offset, 2); + cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + cu->cu_abbrev_offset_cur = cu->cu_abbrev_offset; + cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1); + cu->cu_next_offset = next_offset; + + /* Add the compilation unit to the list. */ + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + + if (cu->cu_version < 2 || cu->cu_version > 4) { + DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); + ret = DW_DLE_VERSION_STAMP_ERROR; + break; + } + + cu->cu_1st_offset = offset; + + offset = next_offset; + + if (!load_all) + break; + } + + if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) + dbg->dbg_info_loaded = 1; + + return (ret); +} + +void +_dwarf_info_cleanup(Dwarf_Debug dbg) +{ + Dwarf_CU cu, tcu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + STAILQ_FOREACH_SAFE(cu, &dbg->dbg_cu, cu_next, tcu) { + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + if (cu->cu_lineinfo != NULL) { + _dwarf_lineno_cleanup(cu->cu_lineinfo); + cu->cu_lineinfo = NULL; + } + free(cu); + } +} + +int +_dwarf_info_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_Unsigned offset; + Dwarf_CU cu; + int ret; + + assert(dbg != NULL && dbg->write_alloc != NULL); + + if (dbg->dbgp_root_die == NULL) + return (DW_DLE_NONE); + + /* Create the single CU for this debugging object. */ + if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + cu->cu_dbg = dbg; + cu->cu_version = 2; /* DWARF2 */ + cu->cu_pointer_size = dbg->dbg_pointer_size; + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + + /* Create .debug_info section. */ + if ((ret = _dwarf_section_init(dbg, &dbg->dbgp_info, ".debug_info", 0, + error)) != DW_DLE_NONE) + goto gen_fail1; + ds = dbg->dbgp_info; + + /* Create relocation section for .debug_init */ + if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Length placeholder. (We only use 32-bit DWARF format) */ + RCHECK(WRITE_VALUE(cu->cu_length, 4)); + + /* Write CU version */ + RCHECK(WRITE_VALUE(cu->cu_version, 2)); + + /* + * Write abbrev offset. (always 0, we only support single CU) + * Also generate a relocation entry for this offset. + */ + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, cu->cu_abbrev_offset, ".debug_abbrev", error)); + + /* Pointer size. */ + RCHECK(WRITE_VALUE(cu->cu_pointer_size, 1)); + + /* Transform the DIE(s) of this CU. */ + RCHECK(_dwarf_die_gen(dbg, cu, drs, error)); + + /* Now we can fill in the length of this CU. */ + cu->cu_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, cu->cu_length, 4); + + /* Inform application the creation of .debug_info ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* + * Inform application the creation of relocation section for + * .debug_info. + */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &dbg->dbgp_info); + +gen_fail1: + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + free(cu); + + return (ret); +} + +void +_dwarf_info_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_CU cu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + cu = STAILQ_FIRST(&dbg->dbg_cu); + if (cu != NULL) { + STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + free(cu); + } +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_init.c new file mode 100644 index 0000000..71d5966 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_init.c @@ -0,0 +1,316 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); + +static int +_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + const Dwarf_Obj_Access_Methods *m; + Dwarf_Obj_Access_Section sec; + void *obj; + Dwarf_Unsigned cnt; + Dwarf_Half i; + int ret; + + assert(dbg != NULL); + assert(dbg->dbg_iface != NULL); + + m = dbg->dbg_iface->methods; + obj = dbg->dbg_iface->object; + + assert(m != NULL); + assert(obj != NULL); + + if (m->get_byte_order(obj) == DW_OBJECT_MSB) { + dbg->read = _dwarf_read_msb; + dbg->write = _dwarf_write_msb; + dbg->decode = _dwarf_decode_msb; + } else { + dbg->read = _dwarf_read_lsb; + dbg->write = _dwarf_write_lsb; + dbg->decode = _dwarf_decode_lsb; + } + + dbg->dbg_pointer_size = m->get_pointer_size(obj); + dbg->dbg_offset_size = m->get_length_size(obj); + + cnt = m->get_section_count(obj); + + if (cnt == 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); + return (DW_DLE_DEBUG_INFO_NULL); + } + + dbg->dbg_seccnt = cnt; + + if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + for (i = 0; i < cnt; i++) { + if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + + dbg->dbg_section[i].ds_addr = sec.addr; + dbg->dbg_section[i].ds_size = sec.size; + dbg->dbg_section[i].ds_name = sec.name; + + if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) + != DW_DLV_OK) { + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + } + + if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || + ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == + NULL)) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); + return (DW_DLE_DEBUG_INFO_NULL); + } + + /* Initialise call frame API related parameters. */ + _dwarf_frame_params_init(dbg); + + return (DW_DLV_OK); +} + +static int +_dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) +{ + + /* Producer only support DWARF2 which has fixed 32bit offset. */ + dbg->dbg_offset_size = 4; + + if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) + pf |= DW_DLC_SIZE_32; + + if (pf & DW_DLC_SIZE_64) + dbg->dbg_pointer_size = 8; + else + dbg->dbg_pointer_size = 4; + + if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if (pf & DW_DLC_ISA_IA64) + dbg->dbgp_isa = DW_ISA_IA64; + else + dbg->dbgp_isa = DW_ISA_MIPS; + + if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 && + (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) { +#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN + pf |= DW_DLC_TARGET_BIGENDIAN; +#else + pf |= DW_DLC_TARGET_LITTLEENDIAN; +#endif + } + + if (pf & DW_DLC_TARGET_BIGENDIAN) { + dbg->write = _dwarf_write_msb; + dbg->write_alloc = _dwarf_write_msb_alloc; + } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) { + dbg->write = _dwarf_write_lsb; + dbg->write_alloc = _dwarf_write_lsb_alloc; + } else + assert(0); + + if (pf & DW_DLC_STREAM_RELOCATIONS && + pf & DW_DLC_SYMBOLIC_RELOCATIONS) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLE_ARGUMENT); + } + + if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && + (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) + pf |= DW_DLC_STREAM_RELOCATIONS; + + dbg->dbgp_flags = pf; + + STAILQ_INIT(&dbg->dbgp_dielist); + STAILQ_INIT(&dbg->dbgp_pelist); + STAILQ_INIT(&dbg->dbgp_seclist); + STAILQ_INIT(&dbg->dbgp_drslist); + STAILQ_INIT(&dbg->dbgp_cielist); + STAILQ_INIT(&dbg->dbgp_fdelist); + + if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); + STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); + + if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&dbg->dbgp_as->as_arlist); + + return (DW_DLE_NONE); +} + +int +_dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, + Dwarf_Ptr errarg, Dwarf_Error *error) +{ + int ret; + + ret = DW_DLE_NONE; + + /* + * Set the error handler fields early, so that the application + * is notified of initialization errors. + */ + dbg->dbg_errhand = errhand; + dbg->dbg_errarg = errarg; + + STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_rllist); + STAILQ_INIT(&dbg->dbg_aslist); + STAILQ_INIT(&dbg->dbg_mslist); + TAILQ_INIT(&dbg->dbg_loclist); + + if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { + ret = _dwarf_consumer_init(dbg, error); + if (ret != DW_DLE_NONE) { + _dwarf_deinit(dbg); + return (ret); + } + } + + if (dbg->dbg_mode == DW_DLC_WRITE) { + ret = _dwarf_producer_init(dbg, pro_flags, error); + if (ret != DW_DLE_NONE) { + _dwarf_deinit(dbg); + return (ret); + } + } + + /* + * Initialise internal string table. + */ + if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) + return (ret); + + return (DW_DLE_NONE); +} + +static void +_dwarf_producer_deinit(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + _dwarf_info_pro_cleanup(dbg); + _dwarf_die_pro_cleanup(dbg); + _dwarf_expr_cleanup(dbg); + _dwarf_lineno_pro_cleanup(dbg); + _dwarf_frame_pro_cleanup(dbg); + _dwarf_arange_pro_cleanup(dbg); + _dwarf_macinfo_pro_cleanup(dbg); + _dwarf_strtab_cleanup(dbg); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types); + _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars); + _dwarf_section_cleanup(dbg); + _dwarf_reloc_cleanup(dbg); +} + +static void +_dwarf_consumer_deinit(Dwarf_Debug dbg) +{ + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + _dwarf_info_cleanup(dbg); + _dwarf_loclist_cleanup(dbg); + _dwarf_ranges_cleanup(dbg); + _dwarf_frame_cleanup(dbg); + _dwarf_arange_cleanup(dbg); + _dwarf_macinfo_cleanup(dbg); + _dwarf_strtab_cleanup(dbg); + _dwarf_nametbl_cleanup(&dbg->dbg_globals); + _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); + _dwarf_nametbl_cleanup(&dbg->dbg_weaks); + _dwarf_nametbl_cleanup(&dbg->dbg_funcs); + _dwarf_nametbl_cleanup(&dbg->dbg_vars); + _dwarf_nametbl_cleanup(&dbg->dbg_types); + + free(dbg->dbg_section); +} + +void +_dwarf_deinit(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_READ) + _dwarf_consumer_deinit(dbg); + else if (dbg->dbg_mode == DW_DLC_WRITE) + _dwarf_producer_deinit(dbg); +} + +int +_dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_mode = mode; + + *ret_dbg = dbg; + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c new file mode 100644 index 0000000..8bb3c85 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c @@ -0,0 +1,785 @@ +/*- + * Copyright (c) 2009,2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_lineno.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); + +static int +_dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, + Dwarf_Error *error, Dwarf_Debug dbg) +{ + Dwarf_LineFile lf; + const char *dirname; + uint8_t *src; + int slen; + + src = *p; + + if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + lf->lf_fullpath = NULL; + lf->lf_fname = (char *) src; + src += strlen(lf->lf_fname) + 1; + lf->lf_dirndx = _dwarf_decode_uleb128(&src); + if (lf->lf_dirndx > li->li_inclen) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_DIR_INDEX_BAD); + return (DW_DLE_DIR_INDEX_BAD); + } + + /* Make full pathname if need. */ + if (*lf->lf_fname != '/') { + dirname = compdir; + if (lf->lf_dirndx > 0) + dirname = li->li_incdirs[lf->lf_dirndx - 1]; + if (dirname != NULL) { + slen = strlen(dirname) + strlen(lf->lf_fname) + 2; + if ((lf->lf_fullpath = malloc(slen)) == NULL) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + snprintf(lf->lf_fullpath, slen, "%s/%s", dirname, + lf->lf_fname); + } + } + + lf->lf_mtime = _dwarf_decode_uleb128(&src); + lf->lf_size = _dwarf_decode_uleb128(&src); + STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); + li->li_lflen++; + + *p = src; + + return (DW_DLE_NONE); +} + +static int +_dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, + uint8_t *pe, const char *compdir, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Line ln, tln; + uint64_t address, file, line, column, isa, opsize; + int is_stmt, basic_block, end_sequence; + int prologue_end, epilogue_begin; + int ret; + +#define RESET_REGISTERS \ + do { \ + address = 0; \ + file = 1; \ + line = 1; \ + column = 0; \ + is_stmt = li->li_defstmt; \ + basic_block = 0; \ + end_sequence = 0; \ + prologue_end = 0; \ + epilogue_begin = 0; \ + } while(0) + +#define APPEND_ROW \ + do { \ + ln = malloc(sizeof(struct _Dwarf_Line)); \ + if (ln == NULL) { \ + ret = DW_DLE_MEMORY; \ + DWARF_SET_ERROR(dbg, error, ret); \ + goto prog_fail; \ + } \ + ln->ln_li = li; \ + ln->ln_addr = address; \ + ln->ln_symndx = 0; \ + ln->ln_fileno = file; \ + ln->ln_lineno = line; \ + ln->ln_column = column; \ + ln->ln_bblock = basic_block; \ + ln->ln_stmt = is_stmt; \ + ln->ln_endseq = end_sequence; \ + STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);\ + li->li_lnlen++; \ + } while(0) + +#define LINE(x) (li->li_lbase + (((x) - li->li_opbase) % li->li_lrange)) +#define ADDRESS(x) ((((x) - li->li_opbase) / li->li_lrange) * li->li_minlen) + + dbg = cu->cu_dbg; + + /* + * Set registers to their default values. + */ + RESET_REGISTERS; + + /* + * Start line number program. + */ + while (p < pe) { + if (*p == 0) { + + /* + * Extended Opcodes. + */ + + p++; + opsize = _dwarf_decode_uleb128(&p); + switch (*p) { + case DW_LNE_end_sequence: + p++; + end_sequence = 1; + APPEND_ROW; + RESET_REGISTERS; + break; + case DW_LNE_set_address: + p++; + address = dbg->decode(&p, cu->cu_pointer_size); + break; + case DW_LNE_define_file: + p++; + ret = _dwarf_lineno_add_file(li, &p, compdir, + error, dbg); + if (ret != DW_DLE_NONE) + goto prog_fail; + break; + default: + /* Unrecognized extened opcodes. */ + p += opsize; + } + + } else if (*p > 0 && *p < li->li_opbase) { + + /* + * Standard Opcodes. + */ + + switch (*p++) { + case DW_LNS_copy: + APPEND_ROW; + basic_block = 0; + prologue_end = 0; + epilogue_begin = 0; + break; + case DW_LNS_advance_pc: + address += _dwarf_decode_uleb128(&p) * + li->li_minlen; + break; + case DW_LNS_advance_line: + line += _dwarf_decode_sleb128(&p); + break; + case DW_LNS_set_file: + file = _dwarf_decode_uleb128(&p); + break; + case DW_LNS_set_column: + column = _dwarf_decode_uleb128(&p); + break; + case DW_LNS_negate_stmt: + is_stmt = !is_stmt; + break; + case DW_LNS_set_basic_block: + basic_block = 1; + break; + case DW_LNS_const_add_pc: + address += ADDRESS(255); + break; + case DW_LNS_fixed_advance_pc: + address += dbg->decode(&p, 2); + break; + case DW_LNS_set_prologue_end: + prologue_end = 1; + break; + case DW_LNS_set_epilogue_begin: + epilogue_begin = 1; + break; + case DW_LNS_set_isa: + isa = _dwarf_decode_uleb128(&p); + break; + default: + /* Unrecognized extened opcodes. What to do? */ + break; + } + + } else { + + /* + * Special Opcodes. + */ + + line += LINE(*p); + address += ADDRESS(*p); + APPEND_ROW; + basic_block = 0; + prologue_end = 0; + epilogue_begin = 0; + p++; + } + } + + return (DW_DLE_NONE); + +prog_fail: + + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); + free(ln); + } + + return (ret); + +#undef RESET_REGISTERS +#undef APPEND_ROW +#undef LINE +#undef ADDRESS +} + +int +_dwarf_lineno_init(Dwarf_Die die, uint64_t offset, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_Section *ds; + Dwarf_CU cu; + Dwarf_Attribute at; + Dwarf_LineInfo li; + Dwarf_LineFile lf, tlf; + const char *compdir; + uint64_t length, hdroff, endoff; + uint8_t *p; + int dwarf_size, i, ret; + + cu = die->die_cu; + assert(cu != NULL); + + dbg = cu->cu_dbg; + assert(dbg != NULL); + + if ((ds = _dwarf_find_section(dbg, ".debug_line")) == NULL) + return (DW_DLE_NONE); + + /* + * Try to find out the dir where the CU was compiled. Later we + * will use the dir to create full pathnames, if need. + */ + compdir = NULL; + at = _dwarf_attr_find(die, DW_AT_comp_dir); + if (at != NULL) { + switch (at->at_form) { + case DW_FORM_strp: + compdir = at->u[1].s; + break; + case DW_FORM_string: + compdir = at->u[0].s; + break; + default: + break; + } + } + + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + if (length > ds->ds_size - offset) { + DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); + return (DW_DLE_DEBUG_LINE_LENGTH_BAD); + } + + if ((li = calloc(1, sizeof(struct _Dwarf_LineInfo))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + /* + * Read in line number program header. + */ + li->li_length = length; + endoff = offset + length; + li->li_version = dbg->read(ds->ds_data, &offset, 2); /* FIXME: verify version */ + li->li_hdrlen = dbg->read(ds->ds_data, &offset, dwarf_size); + hdroff = offset; + li->li_minlen = dbg->read(ds->ds_data, &offset, 1); + li->li_defstmt = dbg->read(ds->ds_data, &offset, 1); + li->li_lbase = dbg->read(ds->ds_data, &offset, 1); + li->li_lrange = dbg->read(ds->ds_data, &offset, 1); + li->li_opbase = dbg->read(ds->ds_data, &offset, 1); + STAILQ_INIT(&li->li_lflist); + STAILQ_INIT(&li->li_lnlist); + + if ((int)li->li_hdrlen - 5 < li->li_opbase - 1) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + if ((li->li_oplen = malloc(li->li_opbase)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + /* + * Read in std opcode arg length list. Note that the first + * element is not used. + */ + for (i = 1; i < li->li_opbase; i++) + li->li_oplen[i] = dbg->read(ds->ds_data, &offset, 1); + + /* + * Check how many strings in the include dir string array. + */ + length = 0; + p = ds->ds_data + offset; + while (*p != '\0') { + while (*p++ != '\0') + ; + length++; + } + li->li_inclen = length; + + /* Sanity check. */ + if (p - ds->ds_data > (int) ds->ds_size) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + if (length != 0) { + if ((li->li_incdirs = malloc(length * sizeof(char *))) == + NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + } + + /* Fill in include dir array. */ + i = 0; + p = ds->ds_data + offset; + while (*p != '\0') { + li->li_incdirs[i++] = (char *) p; + while (*p++ != '\0') + ; + } + + p++; + + /* + * Process file list. + */ + while (*p != '\0') { + ret = _dwarf_lineno_add_file(li, &p, compdir, error, dbg); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + if (p - ds->ds_data > (int) ds->ds_size) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + } + + p++; + + /* Sanity check. */ + if (p - ds->ds_data - hdroff != li->li_hdrlen) { + ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + /* + * Process line number program. + */ + ret = _dwarf_lineno_run_program(cu, li, p, ds->ds_data + endoff, compdir, + error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + cu->cu_lineinfo = li; + + return (DW_DLE_NONE); + +fail_cleanup: + + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); + if (lf->lf_fullpath) + free(lf->lf_fullpath); + free(lf); + } + + if (li->li_oplen) + free(li->li_oplen); + if (li->li_incdirs) + free(li->li_incdirs); + free(li); + + return (ret); +} + +void +_dwarf_lineno_cleanup(Dwarf_LineInfo li) +{ + Dwarf_LineFile lf, tlf; + Dwarf_Line ln, tln; + + if (li == NULL) + return; + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, + _Dwarf_LineFile, lf_next); + if (lf->lf_fullpath) + free(lf->lf_fullpath); + free(lf); + } + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, + ln_next); + free(ln); + } + if (li->li_oplen) + free(li->li_oplen); + if (li->li_incdirs) + free(li->li_incdirs); + if (li->li_lnarray) + free(li->li_lnarray); + if (li->li_lfnarray) + free(li->li_lfnarray); + free(li); +} + +static int +_dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Rel_Section drs, Dwarf_Error * error) +{ + Dwarf_LineInfo li; + Dwarf_Line ln; + Dwarf_Unsigned address, file, line, spc; + Dwarf_Unsigned addr0, maddr; + Dwarf_Signed line0, column; + int is_stmt, basic_block, end_sequence; + int need_copy; + int ret; + +#define RESET_REGISTERS \ + do { \ + address = 0; \ + file = 1; \ + line = 1; \ + column = 0; \ + is_stmt = li->li_defstmt; \ + basic_block = 0; \ + end_sequence = 0; \ + } while(0) + + li = dbg->dbgp_lineinfo; + maddr = (255 - li->li_opbase) / li->li_lrange; + + RESET_REGISTERS; + + STAILQ_FOREACH(ln, &li->li_lnlist, ln_next) { + if (ln->ln_symndx > 0) { + /* + * Generate DW_LNE_set_address extended op. + */ + RCHECK(WRITE_VALUE(0, 1)); + RCHECK(WRITE_ULEB128(dbg->dbg_pointer_size + 1)); + RCHECK(WRITE_VALUE(DW_LNE_set_address, 1)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, + dwarf_drt_data_reloc, dbg->dbg_pointer_size, + ds->ds_size, ln->ln_symndx, ln->ln_addr, + NULL, error)); + address = ln->ln_addr; + continue; + } else if (ln->ln_endseq) { + addr0 = (ln->ln_addr - address) / li->li_minlen; + if (addr0 != 0) { + RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); + RCHECK(WRITE_ULEB128(addr0)); + } + + /* + * Generate DW_LNE_end_sequence. + */ + RCHECK(WRITE_VALUE(0, 1)); + RCHECK(WRITE_ULEB128(1)); + RCHECK(WRITE_VALUE(DW_LNE_end_sequence, 1)); + RESET_REGISTERS; + continue; + } + + /* + * Generate standard opcodes for file, column, is_stmt or + * basic_block changes. + */ + if (ln->ln_fileno != file) { + RCHECK(WRITE_VALUE(DW_LNS_set_file, 1)); + RCHECK(WRITE_ULEB128(ln->ln_fileno)); + file = ln->ln_fileno; + } + if (ln->ln_column != column) { + RCHECK(WRITE_VALUE(DW_LNS_set_column, 1)); + RCHECK(WRITE_ULEB128(ln->ln_column)); + column = ln->ln_column; + } + if (ln->ln_stmt != is_stmt) { + RCHECK(WRITE_VALUE(DW_LNS_negate_stmt, 1)); + is_stmt = ln->ln_stmt; + } + if (ln->ln_bblock && !basic_block) { + RCHECK(WRITE_VALUE(DW_LNS_set_basic_block, 1)); + basic_block = 1; + } + + /* + * Calculate address and line number change. + */ + addr0 = (ln->ln_addr - address) / li->li_minlen; + line0 = ln->ln_lineno - line; + + if (addr0 == 0 && line0 == 0) + continue; + + /* + * Check if line delta is with the range and if the special + * opcode can be used. + */ + assert(li->li_lbase <= 0); + if (line0 >= li->li_lbase && + line0 <= li->li_lbase + li->li_lrange - 1) { + spc = (line0 - li->li_lbase) + + (li->li_lrange * addr0) + li->li_opbase; + if (spc <= 255) { + RCHECK(WRITE_VALUE(spc, 1)); + basic_block = 0; + goto next_line; + } + } + + /* Generate DW_LNS_advance_line for line number change. */ + if (line0 != 0) { + RCHECK(WRITE_VALUE(DW_LNS_advance_line, 1)); + RCHECK(WRITE_SLEB128(line0)); + line0 = 0; + need_copy = 1; + } else + need_copy = basic_block; + + if (addr0 != 0) { + /* See if it can be handled by DW_LNS_const_add_pc. */ + spc = (line0 - li->li_lbase) + + (li->li_lrange * (addr0 - maddr)) + li->li_opbase; + if (addr0 >= maddr && spc <= 255) { + RCHECK(WRITE_VALUE(DW_LNS_const_add_pc, 1)); + RCHECK(WRITE_VALUE(spc, 1)); + } else { + /* Otherwise we use DW_LNS_advance_pc. */ + RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); + RCHECK(WRITE_ULEB128(addr0)); + } + } + + if (need_copy) { + RCHECK(WRITE_VALUE(DW_LNS_copy, 1)); + basic_block = 0; + } + + next_line: + address = ln->ln_addr; + line = ln->ln_lineno; + } + + return (DW_DLE_NONE); + +gen_fail: + return (ret); + +#undef RESET_REGISTERS +} + +static uint8_t +_dwarf_get_minlen(Dwarf_P_Debug dbg) +{ + + assert(dbg != NULL); + + switch (dbg->dbgp_isa) { + case DW_ISA_ARM: + return (2); + case DW_ISA_X86: + case DW_ISA_X86_64: + return (1); + default: + return (4); + } +} + +static uint8_t oplen[] = {0, 1, 1, 1, 1, 0, 0, 0, 1}; + +int +_dwarf_lineno_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf; + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_Unsigned offset; + int i, ret; + + assert(dbg != NULL && dbg->dbgp_lineinfo != NULL); + + li = dbg->dbgp_lineinfo; + if (STAILQ_EMPTY(&li->li_lnlist)) + return (DW_DLE_NONE); + + li->li_length = 0; + li->li_version = 2; + li->li_hdrlen = 0; + li->li_minlen = _dwarf_get_minlen(dbg); + li->li_defstmt = 1; + li->li_lbase = -5; + li->li_lrange = 14; + li->li_opbase = 10; + + /* Create .debug_line section. */ + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_line", 0, error)) != + DW_DLE_NONE) + return (ret); + + /* Create relocation section for .debug_line */ + if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != + DW_DLE_NONE) + goto gen_fail1; + + /* Length placeholder. (We only use 32-bit DWARF format) */ + RCHECK(WRITE_VALUE(0, 4)); + + /* Write line number dwarf version. (DWARF2) */ + RCHECK(WRITE_VALUE(li->li_version, 2)); + + /* Header length placeholder. */ + offset = ds->ds_size; + RCHECK(WRITE_VALUE(li->li_hdrlen, 4)); + + /* Write minimum instruction length. */ + RCHECK(WRITE_VALUE(li->li_minlen, 1)); + + /* + * Write initial value for is_stmt. XXX Which default value we + * should use? + */ + RCHECK(WRITE_VALUE(li->li_defstmt, 1)); + + /* + * Write line_base and line_range. FIXME These value needs to be + * fine tuned. + */ + RCHECK(WRITE_VALUE(li->li_lbase, 1)); + RCHECK(WRITE_VALUE(li->li_lrange, 1)); + + /* Write opcode_base. (DWARF2) */ + RCHECK(WRITE_VALUE(li->li_opbase, 1)); + + /* Write standard op length array. */ + RCHECK(WRITE_BLOCK(oplen, sizeof(oplen) / sizeof(oplen[0]))); + + /* Write the list of include directories. */ + for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) + RCHECK(WRITE_STRING(li->li_incdirs[i])); + RCHECK(WRITE_VALUE(0, 1)); + + /* Write the list of filenames. */ + STAILQ_FOREACH(lf, &li->li_lflist, lf_next) { + RCHECK(WRITE_STRING(lf->lf_fname)); + RCHECK(WRITE_ULEB128(lf->lf_dirndx)); + RCHECK(WRITE_ULEB128(lf->lf_mtime)); + RCHECK(WRITE_ULEB128(lf->lf_size)); + } + RCHECK(WRITE_VALUE(0, 1)); + + /* Fill in the header length. */ + li->li_hdrlen = ds->ds_size - offset - 4; + dbg->write(ds->ds_data, &offset, li->li_hdrlen, 4); + + /* Generate the line number program. */ + RCHECK(_dwarf_lineno_gen_program(dbg, ds, drs, error)); + + /* Fill in the length of this line info. */ + li->li_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, li->li_length, 4); + + /* Notify the creation of .debug_line ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for .debug_line. */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail1: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_lineno_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_LineInfo li; + Dwarf_LineFile lf, tlf; + Dwarf_Line ln, tln; + int i; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_lineinfo == NULL) + return; + + li = dbg->dbgp_lineinfo; + STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { + STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, + lf_next); + if (lf->lf_fname) + free(lf->lf_fname); + free(lf); + } + STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { + STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); + free(ln); + } + if (li->li_incdirs) { + for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) + free(li->li_incdirs[i]); + free(li->li_incdirs); + } + free(li); + dbg->dbgp_lineinfo = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loc.c b/contrib/elftoolchain/libdwarf/libdwarf_loc.c new file mode 100644 index 0000000..ea366fb --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_loc.c @@ -0,0 +1,641 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +/* + * Given an array of bytes of length 'len' representing a + * DWARF expression, compute the number of operations based + * on there being one byte describing the operation and + * zero or more bytes of operands as defined in the standard + * for each operation type. Also, if lbuf is non-null, store + * the opcode and oprand in it. + */ +static int +_dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, + uint8_t *p, int len) +{ + int count; + uint64_t operand1; + uint64_t operand2; + uint8_t *ps, *pe; + + count = 0; + ps = p; + pe = p + len; + + /* + * Process each byte. If an error occurs, then the + * count will be set to -1. + */ + while (p < pe) { + + operand1 = 0; + operand2 = 0; + + if (lbuf != NULL) { + lbuf->ld_s[count].lr_atom = *p; + lbuf->ld_s[count].lr_offset = p - ps; + } + + switch (*p++) { + /* Operations with no operands. */ + case DW_OP_deref: + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + + case DW_OP_dup: + case DW_OP_drop: + + case DW_OP_over: + + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + + case DW_OP_nop: + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + case DW_OP_stack_value: + case DW_OP_GNU_push_tls_address: + break; + + /* Operations with 1-byte operands. */ + case DW_OP_const1u: + case DW_OP_const1s: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + operand1 = *p++; + break; + + /* Operations with 2-byte operands. */ + case DW_OP_call2: + case DW_OP_const2u: + case DW_OP_const2s: + case DW_OP_bra: + case DW_OP_skip: + operand1 = dbg->decode(&p, 2); + break; + + /* Operations with 4-byte operands. */ + case DW_OP_call4: + case DW_OP_const4u: + case DW_OP_const4s: + operand1 = dbg->decode(&p, 4); + break; + + /* Operations with 8-byte operands. */ + case DW_OP_const8u: + case DW_OP_const8s: + operand1 = dbg->decode(&p, 8); + break; + + /* Operations with an unsigned LEB128 operand. */ + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + operand1 = _dwarf_decode_uleb128(&p); + break; + + /* Operations with a signed LEB128 operand. */ + case DW_OP_consts: + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_fbreg: + operand1 = _dwarf_decode_sleb128(&p); + break; + + /* + * Oeration with two unsigned LEB128 operands. + */ + case DW_OP_bit_piece: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = _dwarf_decode_uleb128(&p); + break; + + /* + * Operations with an unsigned LEB128 operand + * followed by a signed LEB128 operand. + */ + case DW_OP_bregx: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = _dwarf_decode_sleb128(&p); + break; + + /* + * Operation with an unsigned LEB128 operand + * followed by a block. Store a pointer to the + * block in the operand2. + */ + case DW_OP_implicit_value: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = (Dwarf_Unsigned) (uintptr_t) p; + p += operand1; + break; + + /* Target address size operand. */ + case DW_OP_addr: + operand1 = dbg->decode(&p, pointer_size); + break; + + /* + * XXX Opcode DW_OP_call_ref has an operand with size + * "dwarf_size". Here we use dbg->dbg_offset_size + * as "dwarf_size" to be compatible with SGI libdwarf. + * However note that dbg->dbg_offset_size is just + * a "guess" value so the parsing result of + * DW_OP_call_ref might not be correct at all. XXX + */ + case DW_OP_call_ref: + operand1 = dbg->decode(&p, dbg->dbg_offset_size); + break; + + /* All other operations cause an error. */ + default: + count = -1; + break; + } + + if (lbuf != NULL) { + lbuf->ld_s[count].lr_number = operand1; + lbuf->ld_s[count].lr_number2 = operand2; + } + + count++; + } + + return (count); +} + +int +_dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, + Dwarf_Small atom, Dwarf_Unsigned operand1, Dwarf_Unsigned operand2, + int *length, Dwarf_Error *error) +{ + uint8_t buf[64]; + uint8_t *p, *pe; + uint64_t offset; + int len; + + if (out != NULL && end != NULL) { + p = out; + pe = end; + } else { + p = out = buf; + pe = &buf[sizeof(buf)]; + } + + switch (atom) { + /* Operations with no operands. */ + case DW_OP_deref: + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + + case DW_OP_dup: + case DW_OP_drop: + + case DW_OP_over: + + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + + case DW_OP_nop: + case DW_OP_GNU_push_tls_address: + *p++ = atom; + break; + + /* Operations with 1-byte operands. */ + case DW_OP_const1u: + case DW_OP_const1s: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + *p++ = atom; + *p++ = (uint8_t) operand1; + break; + + /* Operations with 2-byte operands. */ + case DW_OP_const2u: + case DW_OP_const2s: + case DW_OP_bra: + case DW_OP_skip: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 2); + p += 2; + break; + + /* Operations with 4-byte operands. */ + case DW_OP_const4u: + case DW_OP_const4s: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 4); + p += 4; + break; + + /* Operations with 8-byte operands. */ + case DW_OP_const8u: + case DW_OP_const8s: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, 8); + p += 8; + break; + + /* Operations with an unsigned LEB128 operand. */ + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + *p++ = atom; + len = _dwarf_write_uleb128(p, pe, operand1); + assert(len > 0); + p += len; + break; + + /* Operations with a signed LEB128 operand. */ + case DW_OP_consts: + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_fbreg: + *p++ = atom; + len = _dwarf_write_sleb128(p, pe, operand1); + assert(len > 0); + p += len; + break; + + /* + * Operations with an unsigned LEB128 operand + * followed by a signed LEB128 operand. + */ + case DW_OP_bregx: + *p++ = atom; + len = _dwarf_write_uleb128(p, pe, operand1); + assert(len > 0); + p += len; + len = _dwarf_write_sleb128(p, pe, operand2); + assert(len > 0); + p += len; + break; + + /* Target address size operand. */ + case DW_OP_addr: + *p++ = atom; + offset = 0; + dbg->write(p, &offset, operand1, dbg->dbg_pointer_size); + p += dbg->dbg_pointer_size; + break; + + /* All other operations cause an error. */ + default: + DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (DW_DLE_LOC_EXPR_BAD); + } + + if (length) + *length = p - out; + + return (DW_DLE_NONE); +} + +int +_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, + uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) +{ + int num; + + assert(llbuf != NULL); + assert(in != NULL); + assert(in_len > 0); + + /* Compute the number of locations. */ + if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) < + 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); + return (DW_DLE_LOC_EXPR_BAD); + } + + llbuf->ld_cents = num; + if (num <= 0) + return (DW_DLE_NONE); + + if ((llbuf->ld_s = calloc(num, sizeof(Dwarf_Loc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len); + + return (DW_DLE_NONE); +} + +int +_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, + uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error) +{ + Dwarf_Locdesc *llbuf; + int ret; + + if ((llbuf = malloc(sizeof(Dwarf_Locdesc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + llbuf->ld_lopc = 0; + llbuf->ld_hipc = ~0ULL; + llbuf->ld_s = NULL; + + ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, + error); + if (ret != DW_DLE_NONE) { + free(llbuf); + return (ret); + } + + *ret_llbuf = llbuf; + + return (ret); +} + +int +_dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + Dwarf_CU cu; + int ret; + + assert(at->at_ld == NULL); + assert(at->u[1].u8p != NULL); + assert(at->u[0].u64 > 0); + + cu = die->die_cu; + assert(cu != NULL); + + dbg = cu->cu_dbg; + assert(dbg != NULL); + + ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p, + at->u[0].u64, cu->cu_pointer_size, error); + + return (ret); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_loclist.c b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c new file mode 100644 index 0000000..8b59986 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_loclist.c @@ -0,0 +1,224 @@ +/*- + * Copyright (c) 2009,2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_loclist.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); + +static int +_dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, + uint64_t *off, Dwarf_Locdesc **ld, uint64_t *ldlen, + Dwarf_Unsigned *total_len, Dwarf_Error *error) +{ + uint64_t start, end; + int i, len, ret; + + if (total_len != NULL) + *total_len = 0; + + for (i = 0; *off < ds->ds_size; i++) { + start = dbg->read(ds->ds_data, off, cu->cu_pointer_size); + end = dbg->read(ds->ds_data, off, cu->cu_pointer_size); + if (ld != NULL) { + ld[i]->ld_lopc = start; + ld[i]->ld_hipc = end; + } + + if (total_len != NULL) + *total_len += 2 * cu->cu_pointer_size; + + /* Check if it is the end entry. */ + if (start == 0 && end ==0) { + i++; + break; + } + + /* Check if it is base-select entry. */ + if ((cu->cu_pointer_size == 4 && start == ~0U) || + (cu->cu_pointer_size == 8 && start == ~0ULL)) + continue; + + /* Otherwise it's normal entry. */ + len = dbg->read(ds->ds_data, off, 2); + if (*off + len > ds->ds_size) { + DWARF_SET_ERROR(dbg, error, + DW_DLE_DEBUG_LOC_SECTION_SHORT); + return (DW_DLE_DEBUG_LOC_SECTION_SHORT); + } + + if (total_len != NULL) + *total_len += len; + + if (ld != NULL) { + ret = _dwarf_loc_fill_locdesc(dbg, ld[i], + ds->ds_data + *off, len, cu->cu_pointer_size, + error); + if (ret != DW_DLE_NONE) + return (ret); + } + + *off += len; + } + + if (ldlen != NULL) + *ldlen = i; + + return (DW_DLE_NONE); +} + +int +_dwarf_loclist_find(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, + Dwarf_Loclist *ret_ll, Dwarf_Error *error) +{ + Dwarf_Loclist ll; + int ret; + + assert(ret_ll != NULL); + ret = DW_DLE_NONE; + + TAILQ_FOREACH(ll, &dbg->dbg_loclist, ll_next) + if (ll->ll_offset == lloff) + break; + + if (ll == NULL) + ret = _dwarf_loclist_add(dbg, cu, lloff, ret_ll, error); + else + *ret_ll = ll; + + return (ret); +} + +int +_dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff, + Dwarf_Loclist *ret_ll, Dwarf_Error *error) +{ + Dwarf_Section *ds; + Dwarf_Loclist ll, tll; + uint64_t ldlen; + int i, ret; + + ret = DW_DLE_NONE; + + if ((ds = _dwarf_find_section(dbg, ".debug_loc")) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + if ((ll = malloc(sizeof(struct _Dwarf_Loclist))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + ll->ll_offset = lloff; + + /* Get the number of locdesc the first round. */ + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, NULL, &ldlen, + NULL, error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + /* + * Dwarf_Locdesc list memory is allocated in this way (one more level + * of indirect) to make the loclist API be compatible with SGI libdwarf. + */ + ll->ll_ldlen = ldlen; + if (ldlen != 0) { + if ((ll->ll_ldlist = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + for (i = 0; (uint64_t) i < ldlen; i++) { + if ((ll->ll_ldlist[i] = + calloc(1, sizeof(Dwarf_Locdesc))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + } + } else + ll->ll_ldlist = NULL; + + lloff = ll->ll_offset; + + /* Fill in locdesc. */ + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, ll->ll_ldlist, + NULL, &ll->ll_length, error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + + /* Insert to the queue. Sort by offset. */ + TAILQ_FOREACH(tll, &dbg->dbg_loclist, ll_next) + if (tll->ll_offset > ll->ll_offset) { + TAILQ_INSERT_BEFORE(tll, ll, ll_next); + break; + } + + if (tll == NULL) + TAILQ_INSERT_TAIL(&dbg->dbg_loclist, ll, ll_next); + + *ret_ll = ll; + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_loclist_free(ll); + + return (ret); +} + +void +_dwarf_loclist_free(Dwarf_Loclist ll) +{ + int i; + + if (ll == NULL) + return; + + if (ll->ll_ldlist != NULL) { + for (i = 0; i < ll->ll_ldlen; i++) { + if (ll->ll_ldlist[i]->ld_s) + free(ll->ll_ldlist[i]->ld_s); + free(ll->ll_ldlist[i]); + } + free(ll->ll_ldlist); + } + free(ll); +} + +void +_dwarf_loclist_cleanup(Dwarf_Debug dbg) +{ + Dwarf_Loclist ll, tll; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + TAILQ_FOREACH_SAFE(ll, &dbg->dbg_loclist, ll_next, tll) { + TAILQ_REMOVE(&dbg->dbg_loclist, ll, ll_next); + _dwarf_loclist_free(ll); + } +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c b/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c new file mode 100644 index 0000000..1c9101c --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_macinfo.c @@ -0,0 +1,254 @@ +/*- + * Copyright (c) 2009-2011 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_macinfo.c 2974 2013-12-23 06:46:22Z kaiwang27 $"); + +#define _FILEINDEX_STACK_SIZE 16384 + +static int +_dwarf_macinfo_parse(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *off, + Dwarf_Macro_Details *dmd, Dwarf_Unsigned *cnt, Dwarf_Error *error) +{ + Dwarf_Unsigned lineno; + Dwarf_Signed fileindex[_FILEINDEX_STACK_SIZE]; + char *p; + int i, type, sp; + + i = 0; + sp = 0; + fileindex[sp] = -1; + while (*off < ds->ds_size) { + + if (dmd != NULL) + dmd[i].dmd_offset = *off; + + type = dbg->read(ds->ds_data, off, 1); + + if (dmd != NULL) { + dmd[i].dmd_type = type; + dmd[i].dmd_fileindex = fileindex[sp]; + } + + switch (type) { + case 0: + break; + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + lineno = _dwarf_read_uleb128(ds->ds_data, off); + p = (char *) ds->ds_data; + if (dmd != NULL) { + dmd[i].dmd_lineno = lineno; + dmd[i].dmd_macro = p + *off; + + } + while (p[(*off)++] != '\0') + ; + break; + case DW_MACINFO_start_file: + lineno = _dwarf_read_uleb128(ds->ds_data, off); + if (sp >= _FILEINDEX_STACK_SIZE - 1) { + assert(0); + } + fileindex[++sp] = _dwarf_read_uleb128(ds->ds_data, off); + if (dmd != NULL) { + dmd[i].dmd_lineno = lineno; + dmd[i].dmd_fileindex = fileindex[sp]; + } + break; + case DW_MACINFO_end_file: + if (sp > 0) { + sp--; + break; + } + /* FALLTHROUGH */ + default: + DWARF_SET_ERROR(dbg, error, + DW_DLE_DEBUG_MACRO_INCONSISTENT); + return (DW_DLE_DEBUG_MACRO_INCONSISTENT); + } + + i++; + + if (type == 0) + break; + } + + if (cnt != NULL) + *cnt = i; + + return (DW_DLE_NONE); +} + +void +_dwarf_macinfo_cleanup(Dwarf_Debug dbg) +{ + Dwarf_MacroSet ms, tms; + + if (STAILQ_EMPTY(&dbg->dbg_mslist)) + return; + + STAILQ_FOREACH_SAFE(ms, &dbg->dbg_mslist, ms_next, tms) { + STAILQ_REMOVE(&dbg->dbg_mslist, ms, _Dwarf_MacroSet, ms_next); + if (ms->ms_mdlist) + free(ms->ms_mdlist); + free(ms); + } +} + +int +_dwarf_macinfo_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_MacroSet ms; + Dwarf_Unsigned cnt; + Dwarf_Section *ds; + uint64_t offset, entry_off; + int ret; + + if ((ds = _dwarf_find_section(dbg, ".debug_macinfo")) == NULL) + return (DW_DLE_NONE); + + offset = 0; + while (offset < ds->ds_size) { + + entry_off = offset; + + ret = _dwarf_macinfo_parse(dbg, ds, &offset, NULL, &cnt, error); + if (ret != DW_DLE_NONE) + return (ret); + + if (cnt == 0) + break; + + if ((ms = calloc(1, sizeof(struct _Dwarf_MacroSet))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + STAILQ_INSERT_TAIL(&dbg->dbg_mslist, ms, ms_next); + + if ((ms->ms_mdlist = calloc(cnt, sizeof(Dwarf_Macro_Details))) + == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + + ms->ms_cnt = cnt; + + offset = entry_off; + + ret = _dwarf_macinfo_parse(dbg, ds, &offset, ms->ms_mdlist, + NULL, error); + + if (ret != DW_DLE_NONE) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + ret = DW_DLE_MEMORY; + goto fail_cleanup; + } + } + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_macinfo_cleanup(dbg); + + return (ret); +} + +int +_dwarf_macinfo_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Macro_Details *md; + int i, ret; + + if (dbg->dbgp_mdcnt == 0) + return (DW_DLE_NONE); + + /* Create .debug_frame section. */ + RCHECK(_dwarf_section_init(dbg, &ds, ".debug_macinfo", 0, error)); + + /* Write the list of Dwarf_Macro_Details. */ + for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { + md = &dbg->dbgp_mdlist[i]; + md->dmd_offset = ds->ds_size; + RCHECK(WRITE_VALUE(md->dmd_type, 1)); + switch (md->dmd_type) { + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + RCHECK(WRITE_ULEB128(md->dmd_lineno)); + assert(md->dmd_macro != NULL); + RCHECK(WRITE_STRING(md->dmd_macro)); + break; + case DW_MACINFO_start_file: + RCHECK(WRITE_ULEB128(md->dmd_lineno)); + RCHECK(WRITE_ULEB128(md->dmd_fileindex)); + break; + case DW_MACINFO_end_file: + break; + default: + assert(0); + break; + } + } + RCHECK(WRITE_VALUE(0, 1)); + + /* Inform application the creation of .debug_macinfo ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_macinfo_pro_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_Macro_Details *md; + int i; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + if (dbg->dbgp_mdlist == NULL) + return; + + assert(dbg->dbgp_mdcnt > 0); + for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { + md = &dbg->dbgp_mdlist[i]; + if (md->dmd_macro) + free(md->dmd_macro); + } + free(dbg->dbgp_mdlist); + dbg->dbgp_mdlist = NULL; + dbg->dbgp_mdcnt = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c new file mode 100644 index 0000000..158aca3 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_nametbl.c @@ -0,0 +1,253 @@ +/*- + * Copyright (c) 2009,2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_nametbl.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +void +_dwarf_nametbl_cleanup(Dwarf_NameSec *nsp) +{ + Dwarf_NameSec ns; + Dwarf_NameTbl nt, tnt; + Dwarf_NamePair np, tnp; + + assert(nsp != NULL); + if ((ns = *nsp) == NULL) + return; + + STAILQ_FOREACH_SAFE(nt, &ns->ns_ntlist, nt_next, tnt) { + STAILQ_FOREACH_SAFE(np, &nt->nt_nplist, np_next, tnp) { + STAILQ_REMOVE(&nt->nt_nplist, np, _Dwarf_NamePair, + np_next); + free(np); + } + STAILQ_REMOVE(&ns->ns_ntlist, nt, _Dwarf_NameTbl, nt_next); + free(nt); + } + if (ns->ns_array) + free(ns->ns_array); + free(ns); + *nsp = NULL; +} + +int +_dwarf_nametbl_init(Dwarf_Debug dbg, Dwarf_NameSec *namesec, Dwarf_Section *ds, + Dwarf_Error *error) +{ + Dwarf_CU cu; + Dwarf_NameSec ns; + Dwarf_NameTbl nt; + Dwarf_NamePair np; + uint64_t offset, dwarf_size, length, cuoff; + char *p; + int i, ret; + + assert(*namesec == NULL); + + if ((ns = malloc(sizeof(struct _Dwarf_NameSec))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INIT(&ns->ns_ntlist); + ns->ns_array = NULL; + ns->ns_len = 0; + + offset = 0; + while (offset < ds->ds_size) { + + /* Allocate a new name table. */ + if ((nt = malloc(sizeof(struct _Dwarf_NameTbl))) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + STAILQ_INIT(&nt->nt_nplist); + STAILQ_INSERT_TAIL(&ns->ns_ntlist, nt, nt_next); + + /* Read in the table header. */ + length = dbg->read(ds->ds_data, &offset, 4); + if (length == 0xffffffff) { + dwarf_size = 8; + length = dbg->read(ds->ds_data, &offset, 8); + } else + dwarf_size = 4; + + nt->nt_length = length; + /* FIXME: verify version */ + nt->nt_version = dbg->read(ds->ds_data, &offset, 2); + nt->nt_cu_offset = dbg->read(ds->ds_data, &offset, dwarf_size); + nt->nt_cu_length = dbg->read(ds->ds_data, &offset, dwarf_size); + + if (!dbg->dbg_info_loaded) { + ret = _dwarf_info_load(dbg, 1, error); + if (ret != DW_DLE_NONE) + goto fail_cleanup; + } + + /* Find the referenced CU. */ + STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) { + if (cu->cu_offset == nt->nt_cu_offset) + break; + } + nt->nt_cu = cu; /* FIXME: Check if NULL here */ + + /* Add name pairs. */ + while (offset < ds->ds_size) { + cuoff = dbg->read(ds->ds_data, &offset, dwarf_size); + if (cuoff == 0) + break; + if ((np = malloc(sizeof(struct _Dwarf_NamePair))) == + NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + np->np_nt = nt; + np->np_offset = cuoff; + p = (char *) ds->ds_data; + np->np_name = &p[offset]; + while (p[offset++] != '\0') + ; + STAILQ_INSERT_TAIL(&nt->nt_nplist, np, np_next); + ns->ns_len++; + } + } + + /* Build array of name pairs from all tables. */ + if (ns->ns_len > 0) { + if ((ns->ns_array = malloc(sizeof(Dwarf_NamePair) * + ns->ns_len)) == NULL) { + ret = DW_DLE_MEMORY; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; + } + + i = 0; + STAILQ_FOREACH(nt, &ns->ns_ntlist, nt_next) { + STAILQ_FOREACH(np, &nt->nt_nplist, np_next) + ns->ns_array[i++] = np; + } + assert((Dwarf_Unsigned)i == ns->ns_len); + } + + *namesec = ns; + + return (DW_DLE_NONE); + +fail_cleanup: + + _dwarf_nametbl_cleanup(&ns); + + return (ret); +} + +int +_dwarf_nametbl_gen(Dwarf_P_Debug dbg, const char *name, Dwarf_NameTbl nt, + Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Rel_Section drs; + Dwarf_NamePair np; + uint64_t offset; + int ret; + + assert(dbg != NULL && name != NULL); + if (nt == NULL || STAILQ_EMPTY(&nt->nt_nplist)) + return (DW_DLE_NONE); + + nt->nt_length = 0; + nt->nt_version = 2; + nt->nt_cu = STAILQ_FIRST(&dbg->dbg_cu); + assert(nt->nt_cu != NULL); + nt->nt_cu_offset = nt->nt_cu->cu_offset; + nt->nt_cu_length = nt->nt_cu->cu_length; + + /* Create name lookup section. */ + if ((ret = _dwarf_section_init(dbg, &ds, name, 0, error)) != + DW_DLE_NONE) + goto gen_fail0; + + /* Create relocation section for the name lookup section. */ + RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); + + /* Write table header. */ + RCHECK(WRITE_VALUE(nt->nt_length, 4)); + RCHECK(WRITE_VALUE(nt->nt_version, 2)); + RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, + ds->ds_size, 0, nt->nt_cu_offset, ".debug_info", error)); + RCHECK(WRITE_VALUE(nt->nt_cu_length, 4)); + + /* Write tuples. */ + STAILQ_FOREACH(np, &nt->nt_nplist, np_next) { + assert(np->np_die != NULL); + np->np_offset = np->np_die->die_offset; + RCHECK(WRITE_VALUE(np->np_offset, 4)); + RCHECK(WRITE_STRING(np->np_name)); + } + RCHECK(WRITE_VALUE(0, 4)); + + /* Fill in the length field. */ + nt->nt_length = ds->ds_size - 4; + offset = 0; + dbg->write(ds->ds_data, &offset, nt->nt_length, 4); + + /* Inform application the creation of name lookup ELF section. */ + RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); + + /* Finalize relocation section for the name lookup section. */ + RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); + + return (DW_DLE_NONE); + +gen_fail: + _dwarf_reloc_section_free(dbg, &drs); + +gen_fail0: + _dwarf_section_free(dbg, &ds); + + return (ret); +} + +void +_dwarf_nametbl_pro_cleanup(Dwarf_NameTbl *ntp) +{ + Dwarf_NameTbl nt; + Dwarf_NamePair np, tnp; + + assert(ntp != NULL); + if ((nt = *ntp) == NULL) + return; + + STAILQ_FOREACH_SAFE(np, &nt->nt_nplist, np_next, tnp) { + STAILQ_REMOVE(&nt->nt_nplist, np, _Dwarf_NamePair, np_next); + if (np->np_name) + free(np->np_name); + free(np); + } + free(nt); + *ntp = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_ranges.c b/contrib/elftoolchain/libdwarf/libdwarf_ranges.c new file mode 100644 index 0000000..3396bb9 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_ranges.c @@ -0,0 +1,152 @@ +/*- + * Copyright (c) 2009 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_ranges.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); + +static int +_dwarf_ranges_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, + uint64_t off, Dwarf_Ranges *rg, Dwarf_Unsigned *cnt) +{ + Dwarf_Unsigned start, end; + int i; + + i = 0; + while (off < ds->ds_size) { + + start = dbg->read(ds->ds_data, &off, cu->cu_pointer_size); + end = dbg->read(ds->ds_data, &off, cu->cu_pointer_size); + + if (rg != NULL) { + rg[i].dwr_addr1 = start; + rg[i].dwr_addr2 = end; + if (start == 0 && end == 0) + rg[i].dwr_type = DW_RANGES_END; + else if ((start == ~0U && cu->cu_pointer_size == 4) || + (start == ~0ULL && cu->cu_pointer_size == 8)) + rg[i].dwr_type = DW_RANGES_ADDRESS_SELECTION; + else + rg[i].dwr_type = DW_RANGES_ENTRY; + } + + i++; + + if (start == 0 && end == 0) + break; + } + + if (cnt != NULL) + *cnt = i; + + return (DW_DLE_NONE); +} + +int +_dwarf_ranges_find(Dwarf_Debug dbg, uint64_t off, Dwarf_Rangelist *ret_rl) +{ + Dwarf_Rangelist rl; + + STAILQ_FOREACH(rl, &dbg->dbg_rllist, rl_next) + if (rl->rl_offset == off) + break; + + if (rl == NULL) + return (DW_DLE_NO_ENTRY); + + if (ret_rl != NULL) + *ret_rl = rl; + + return (DW_DLE_NONE); +} + +void +_dwarf_ranges_cleanup(Dwarf_Debug dbg) +{ + Dwarf_Rangelist rl, trl; + + if (STAILQ_EMPTY(&dbg->dbg_rllist)) + return; + + STAILQ_FOREACH_SAFE(rl, &dbg->dbg_rllist, rl_next, trl) { + STAILQ_REMOVE(&dbg->dbg_rllist, rl, _Dwarf_Rangelist, rl_next); + if (rl->rl_rgarray) + free(rl->rl_rgarray); + free(rl); + } +} + +int +_dwarf_ranges_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t off, + Dwarf_Rangelist *ret_rl, Dwarf_Error *error) +{ + Dwarf_Section *ds; + Dwarf_Rangelist rl; + Dwarf_Unsigned cnt; + int ret; + + if ((ds = _dwarf_find_section(dbg, ".debug_ranges")) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); + } + + if ((rl = malloc(sizeof(struct _Dwarf_Rangelist))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + rl->rl_offset = off; + + ret = _dwarf_ranges_parse(dbg, cu, ds, off, NULL, &cnt); + if (ret != DW_DLE_NONE) { + free(rl); + return (ret); + } + + rl->rl_rglen = cnt; + if (cnt != 0) { + if ((rl->rl_rgarray = calloc(cnt, sizeof(Dwarf_Ranges))) == + NULL) { + free(rl); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + ret = _dwarf_ranges_parse(dbg, cu, ds, off, rl->rl_rgarray, + NULL); + if (ret != DW_DLE_NONE) { + free(rl->rl_rgarray); + free(rl); + return (ret); + } + } else + rl->rl_rgarray = NULL; + + STAILQ_INSERT_TAIL(&dbg->dbg_rllist, rl, rl_next); + *ret_rl = rl; + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_reloc.c b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c new file mode 100644 index 0000000..ea91677 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_reloc.c @@ -0,0 +1,476 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_reloc.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); + +Dwarf_Unsigned +_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64) +{ + + assert(dbg != NULL); + + switch (dbg->dbgp_isa) { + case DW_ISA_X86: + return (R_386_32); + case DW_ISA_X86_64: + return (is64 ? R_X86_64_64 : R_X86_64_32); + case DW_ISA_SPARC: + return (is64 ? R_SPARC_UA64 : R_SPARC_UA32); + case DW_ISA_PPC: + return (R_PPC_ADDR32); + case DW_ISA_ARM: + return (R_ARM_ABS32); + case DW_ISA_MIPS: + return (is64 ? R_MIPS_64 : R_MIPS_32); + case DW_ISA_IA64: + return (is64 ? R_IA_64_DIR64LSB : R_IA_64_DIR32LSB); + default: + break; + } + return (0); /* NOT REACHED */ +} + +int +_dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type) +{ + + switch (dbg->dbg_machine) { + case EM_NONE: + break; + case EM_ARM: + if (rel_type == R_ARM_ABS32) + return (4); + break; + case EM_386: + if (rel_type == R_386_32) + return (4); + break; + case EM_X86_64: + if (rel_type == R_X86_64_32) + return (4); + else if (rel_type == R_X86_64_64) + return (8); + break; + case EM_SPARC: + if (rel_type == R_SPARC_UA32) + return (4); + else if (rel_type == R_SPARC_UA64) + return (8); + break; + case EM_PPC: + if (rel_type == R_PPC_ADDR32) + return (4); + break; + case EM_MIPS: + if (rel_type == R_MIPS_32) + return (4); + else if (rel_type == R_MIPS_64) + return (8); + break; + case EM_IA_64: + if (rel_type == R_IA_64_SECREL32LSB) + return (4); + else if (rel_type == R_IA_64_DIR64LSB) + return (8); + break; + default: + break; + } + + /* unknown relocation. */ + return (0); +} + +int +_dwarf_reloc_section_init(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp, + Dwarf_P_Section ref, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + char name[128]; + int pseudo; + + assert(dbg != NULL && drsp != NULL && ref != NULL); + + if ((drs = calloc(1, sizeof(struct _Dwarf_Rel_Section))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + drs->drs_ref = ref; + + /* + * FIXME The logic here is most likely wrong. It should + * be the ISA that determines relocation type. + */ + if (dbg->dbgp_flags & DW_DLC_SIZE_64) + drs->drs_addend = 1; + else + drs->drs_addend = 0; + + if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) + pseudo = 1; + else + pseudo = 0; + + snprintf(name, sizeof(name), "%s%s", + drs->drs_addend ? ".rela" : ".rel", ref->ds_name); + if (_dwarf_section_init(dbg, &drs->drs_ds, name, pseudo, error) != + DW_DLE_NONE) { + free(drs); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + STAILQ_INIT(&drs->drs_dre); + STAILQ_INSERT_TAIL(&dbg->dbgp_drslist, drs, drs_next); + dbg->dbgp_drscnt++; + *drsp = drs; + + return (DW_DLE_NONE); +} + +void +_dwarf_reloc_section_free(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp) +{ + Dwarf_Rel_Section drs, tdrs; + Dwarf_Rel_Entry dre, tdre; + + assert(dbg != NULL && drsp != NULL); + + if (*drsp == NULL) + return; + + STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { + if (drs != *drsp) + continue; + STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, + drs_next); + STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { + STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, + dre_next); + free(dre); + } + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) + _dwarf_section_free(dbg, &drs->drs_ds); + else { + if (drs->drs_ds->ds_name) + free(drs->drs_ds->ds_name); + free(drs->drs_ds); + } + free(drs); + *drsp = NULL; + dbg->dbgp_drscnt--; + break; + } +} + +int +_dwarf_reloc_entry_add(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_P_Section ds, unsigned char type, unsigned char length, + Dwarf_Unsigned offset, Dwarf_Unsigned symndx, Dwarf_Unsigned addend, + const char *secname, Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_Unsigned reloff; + int ret; + + assert(drs != NULL); + assert(offset <= ds->ds_size); + reloff = offset; + + /* + * If the DW_DLC_SYMBOLIC_RELOCATIONS flag is set or ElfXX_Rel + * is used instead of ELfXX_Rela, we need to write the addend + * in the storage unit to be relocated. Otherwise write 0 in the + * storage unit and the addend will be written into relocation + * section later. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) || + drs->drs_addend == 0) + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + addend, length, error); + else + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + 0, length, error); + if (ret != DW_DLE_NONE) + return (ret); + if (offset > ds->ds_size) + ds->ds_size = offset; + + if ((dre = calloc(1, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&drs->drs_dre, dre, dre_next); + dre->dre_type = type; + dre->dre_length = length; + dre->dre_offset = reloff; + dre->dre_symndx = symndx; + dre->dre_addend = addend; + dre->dre_secname = secname; + drs->drs_drecnt++; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_entry_add_pair(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_P_Section ds, unsigned char length, Dwarf_Unsigned offset, + Dwarf_Unsigned symndx, Dwarf_Unsigned esymndx, Dwarf_Unsigned symoff, + Dwarf_Unsigned esymoff, Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_Unsigned reloff; + int ret; + + assert(drs != NULL); + assert(offset <= ds->ds_size); + assert(dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS); + reloff = offset; + + /* Write net offset into section stream. */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, + esymoff - symoff, length, error); + if (ret != DW_DLE_NONE) + return (ret); + if (offset > ds->ds_size) + ds->ds_size = offset; + + if ((dre = calloc(2, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[0], dre_next); + STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[1], dre_next); + dre[0].dre_type = dwarf_drt_first_of_length_pair; + dre[0].dre_length = length; + dre[0].dre_offset = reloff; + dre[0].dre_symndx = symndx; + dre[0].dre_addend = 0; + dre[0].dre_secname = NULL; + dre[1].dre_type = dwarf_drt_second_of_length_pair; + dre[1].dre_length = length; + dre[1].dre_offset = reloff; + dre[1].dre_symndx = esymndx; + dre[1].dre_addend = 0; + dre[1].dre_secname = NULL; + drs->drs_drecnt += 2; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_section_finalize(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_P_Section ds; + Dwarf_Unsigned unit; + int ret, size; + + assert(dbg != NULL && drs != NULL && drs->drs_ds != NULL && + drs->drs_ref != NULL); + + ds = drs->drs_ds; + + /* + * Calculate the size (in bytes) of the relocation section. + */ + if (dbg->dbgp_flags & DW_DLC_SIZE_64) + unit = drs->drs_addend ? sizeof(Elf64_Rela) : sizeof(Elf64_Rel); + else + unit = drs->drs_addend ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel); + assert(ds->ds_size == 0); + size = drs->drs_drecnt * unit; + + /* + * Discard this relocation section if there is no entry in it. + */ + if (size == 0) { + _dwarf_reloc_section_free(dbg, &drs); + return (DW_DLE_NONE); + } + + /* + * If we are under stream mode, realloc the section data block to + * this size. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + ds->ds_cap = size; + if ((ds->ds_data = realloc(ds->ds_data, (size_t) ds->ds_cap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + /* + * Notify the application the creation of this relocation section. + * Note that the section link here should point to the .symtab + * section, we set it to 0 since we have no way to know .symtab + * section index. + */ + ret = _dwarf_pro_callback(dbg, ds->ds_name, size, + drs->drs_addend ? SHT_RELA : SHT_REL, 0, 0, drs->drs_ref->ds_ndx, + &ds->ds_symndx, NULL); + if (ret < 0) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ELF_SECT_ERR); + return (DW_DLE_ELF_SECT_ERR); + } + ds->ds_ndx = ret; + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_section_gen(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, + Dwarf_Error *error) +{ + Dwarf_Rel_Entry dre; + Dwarf_P_Section ds; + Dwarf_Unsigned type; + int ret; + + assert((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0); + assert(drs->drs_ds != NULL && drs->drs_ds->ds_size == 0); + assert(!STAILQ_EMPTY(&drs->drs_dre)); + ds = drs->drs_ds; + + STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { + assert(dre->dre_length == 4 || dre->dre_length == 8); + type = _dwarf_get_reloc_type(dbg, dre->dre_length == 8); + if (dbg->dbgp_flags & DW_DLC_SIZE_64) { + /* Write r_offset (8 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, dre->dre_offset, 8, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_info (8 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, ELF64_R_INFO(dre->dre_symndx, type), + 8, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_addend (8 bytes) */ + if (drs->drs_addend) { + ret = dbg->write_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, dre->dre_addend, + 8, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } else { + /* Write r_offset (4 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, dre->dre_offset, 4, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_info (4 bytes) */ + ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, + &ds->ds_size, ELF32_R_INFO(dre->dre_symndx, type), + 4, error); + if (ret != DW_DLE_NONE) + return (ret); + /* Write r_addend (4 bytes) */ + if (drs->drs_addend) { + ret = dbg->write_alloc(&ds->ds_data, + &ds->ds_cap, &ds->ds_size, dre->dre_addend, + 4, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } + } + assert(ds->ds_size == ds->ds_cap); + + return (DW_DLE_NONE); +} + +int +_dwarf_reloc_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Rel_Section drs; + Dwarf_Rel_Entry dre; + Dwarf_P_Section ds; + int ret; + + STAILQ_FOREACH(drs, &dbg->dbgp_drslist, drs_next) { + /* + * Update relocation entries: translate any section name + * reference to section symbol index. + */ + STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { + if (dre->dre_secname == NULL) + continue; + ds = _dwarf_pro_find_section(dbg, dre->dre_secname); + assert(ds != NULL && ds->ds_symndx != 0); + dre->dre_symndx = ds->ds_symndx; + } + + /* + * Generate ELF relocation section if we are under stream + * mode. + */ + if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { + ret = _dwarf_reloc_section_gen(dbg, drs, error); + if (ret != DW_DLE_NONE) + return (ret); + } + } + + return (DW_DLE_NONE); +} + +void +_dwarf_reloc_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_Rel_Section drs, tdrs; + Dwarf_Rel_Entry dre, tdre; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { + STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, + drs_next); + free(drs->drs_drd); + STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { + STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, + dre_next); + free(dre); + } + if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { + if (drs->drs_ds) { + if (drs->drs_ds->ds_name) + free(drs->drs_ds->ds_name); + free(drs->drs_ds); + } + } + free(drs); + } + dbg->dbgp_drscnt = 0; + dbg->dbgp_drspos = NULL; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_rw.c b/contrib/elftoolchain/libdwarf/libdwarf_rw.c new file mode 100644 index 0000000..8cb4551 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_rw.c @@ -0,0 +1,562 @@ +/*- + * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 $"); + +uint64_t +_dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = data + *offsetp; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + case 4: + ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + case 2: + ret |= ((uint64_t) src[1]) << 8; + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_decode_lsb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 8: + ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; + ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; + case 4: + ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; + case 2: + ret |= ((uint64_t) src[1]) << 8; + case 1: + ret |= src[0]; + break; + default: + return (0); + } + + *data += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = data + *offsetp; + + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + } + + *offsetp += bytes_to_read; + + return (ret); +} + +uint64_t +_dwarf_decode_msb(uint8_t **data, int bytes_to_read) +{ + uint64_t ret; + uint8_t *src; + + src = *data; + + ret = 0; + switch (bytes_to_read) { + case 1: + ret = src[0]; + break; + case 2: + ret = src[1] | ((uint64_t) src[0]) << 8; + break; + case 4: + ret = src[3] | ((uint64_t) src[2]) << 8; + ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; + break; + case 8: + ret = src[7] | ((uint64_t) src[6]) << 8; + ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; + ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; + ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; + break; + default: + return (0); + break; + } + + *data += bytes_to_read; + + return (ret); +} + +void +_dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value, + int bytes_to_write) +{ + uint8_t *dst; + + dst = data + *offsetp; + + switch (bytes_to_write) { + case 8: + dst[7] = (value >> 56) & 0xff; + dst[6] = (value >> 48) & 0xff; + dst[5] = (value >> 40) & 0xff; + dst[4] = (value >> 32) & 0xff; + case 4: + dst[3] = (value >> 24) & 0xff; + dst[2] = (value >> 16) & 0xff; + case 2: + dst[1] = (value >> 8) & 0xff; + case 1: + dst[0] = value & 0xff; + break; + default: + return; + } + + *offsetp += bytes_to_write; +} + +int +_dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t value, int bytes_to_write, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + bytes_to_write > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_lsb(*block, offsetp, value, bytes_to_write); + + return (DW_DLE_NONE); +} + +void +_dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value, + int bytes_to_write) +{ + uint8_t *dst; + + dst = data + *offsetp; + + switch (bytes_to_write) { + case 8: + dst[7] = value & 0xff; + dst[6] = (value >> 8) & 0xff; + dst[5] = (value >> 16) & 0xff; + dst[4] = (value >> 24) & 0xff; + value >>= 32; + case 4: + dst[3] = value & 0xff; + dst[2] = (value >> 8) & 0xff; + value >>= 16; + case 2: + dst[1] = value & 0xff; + value >>= 8; + case 1: + dst[0] = value & 0xff; + break; + default: + return; + } + + *offsetp += bytes_to_write; +} + +int +_dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t value, int bytes_to_write, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + bytes_to_write > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_msb(*block, offsetp, value, bytes_to_write); + + return (DW_DLE_NONE); +} + +int64_t +_dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp) +{ + int64_t ret = 0; + uint8_t b; + int shift = 0; + uint8_t *src; + + src = data + *offsetp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + (*offsetp)++; + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 64 && (b & 0x40) != 0) + ret |= (-1 << shift); + + return (ret); +} + +int +_dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val) +{ + uint8_t *p; + + p = data; + + for (;;) { + if (p >= end) + return (-1); + *p = val & 0x7f; + val >>= 7; + if ((val == 0 && (*p & 0x40) == 0) || + (val == -1 && (*p & 0x40) != 0)) { + p++; + break; + } + *p++ |= 0x80; + } + + return (p - data); +} + +int +_dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + int64_t val, Dwarf_Error *error) +{ + int len; + + assert(*size > 0); + + while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size, + val)) < 0) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + *offsetp += len; + + return (DW_DLE_NONE); +} + +uint64_t +_dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + uint8_t *src; + + src = data + *offsetp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + (*offsetp)++; + shift += 7; + } while ((b & 0x80) != 0); + + return (ret); +} + +int +_dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val) +{ + uint8_t *p; + + p = data; + + do { + if (p >= end) + return (-1); + *p = val & 0x7f; + val >>= 7; + if (val > 0) + *p |= 0x80; + p++; + } while (val > 0); + + return (p - data); +} + +int +_dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint64_t val, Dwarf_Error *error) +{ + int len; + + assert(*size > 0); + + while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size, + val)) < 0) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + *offsetp += len; + + return (DW_DLE_NONE); +} + +int64_t +_dwarf_decode_sleb128(uint8_t **dp) +{ + int64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + if (shift < 64 && (b & 0x40) != 0) + ret |= (-1 << shift); + + *dp = src; + + return (ret); +} + +uint64_t +_dwarf_decode_uleb128(uint8_t **dp) +{ + uint64_t ret = 0; + uint8_t b; + int shift = 0; + + uint8_t *src = *dp; + + do { + b = *src++; + ret |= ((b & 0x7f) << shift); + shift += 7; + } while ((b & 0x80) != 0); + + *dp = src; + + return (ret); +} + +char * +_dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp) +{ + char *ret, *src; + + ret = src = (char *) data + *offsetp; + + while (*src != '\0' && *offsetp < size) { + src++; + (*offsetp)++; + } + + if (*src == '\0' && *offsetp < size) + (*offsetp)++; + + return (ret); +} + +void +_dwarf_write_string(void *data, uint64_t *offsetp, char *string) +{ + char *dst; + + dst = (char *) data + *offsetp; + strcpy(dst, string); + (*offsetp) += strlen(string) + 1; +} + +int +_dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + char *string, Dwarf_Error *error) +{ + size_t len; + + assert(*size > 0); + + len = strlen(string) + 1; + while (*offsetp + len > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_string(*block, offsetp, string); + + return (DW_DLE_NONE); +} + +uint8_t * +_dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length) +{ + uint8_t *ret, *src; + + ret = src = (uint8_t *) data + *offsetp; + + (*offsetp) += length; + + return (ret); +} + +void +_dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk, + uint64_t length) +{ + uint8_t *dst; + + dst = (uint8_t *) data + *offsetp; + memcpy(dst, blk, length); + (*offsetp) += length; +} + +int +_dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint8_t *blk, uint64_t length, Dwarf_Error *error) +{ + + assert(*size > 0); + + while (*offsetp + length > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_block(*block, offsetp, blk, length); + + return (DW_DLE_NONE); +} + +void +_dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte, + uint64_t length) +{ + uint8_t *dst; + + dst = (uint8_t *) data + *offsetp; + memset(dst, byte, length); + (*offsetp) += length; +} + +int +_dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp, + uint8_t byte, uint64_t cnt, Dwarf_Error *error) +{ + assert(*size > 0); + + while (*offsetp + cnt > *size) { + *size *= 2; + *block = realloc(*block, (size_t) *size); + if (*block == NULL) { + DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + _dwarf_write_padding(*block, offsetp, byte, cnt); + + return (DW_DLE_NONE); +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_sections.c b/contrib/elftoolchain/libdwarf/libdwarf_sections.c new file mode 100644 index 0000000..3ac30b2 --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_sections.c @@ -0,0 +1,259 @@ +/*- + * Copyright (c) 2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_sections.c 2379 2012-01-05 02:08:20Z jkoshy $"); + +#define _SECTION_INIT_SIZE 128 + +int +_dwarf_section_init(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp, const char *name, + int pseudo, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + + assert(dbg != NULL && dsp != NULL && name != NULL); + + if ((ds = calloc(1, sizeof(struct _Dwarf_P_Section))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if ((ds->ds_name = strdup(name)) == NULL) { + free(ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + if (!pseudo) { + ds->ds_cap = _SECTION_INIT_SIZE; + if ((ds->ds_data = malloc((size_t) ds->ds_cap)) == NULL) { + free(ds->ds_name); + free(ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + STAILQ_INSERT_TAIL(&dbg->dbgp_seclist, ds, ds_next); + dbg->dbgp_seccnt++; + } + + *dsp = ds; + + return (DW_DLE_NONE); +} + +void +_dwarf_section_free(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp) +{ + Dwarf_P_Section ds, tds; + + assert(dbg != NULL && dsp != NULL); + + if (*dsp == NULL) + return; + + STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { + if (ds == *dsp) { + STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, + ds_next); + dbg->dbgp_seccnt--; + break; + } + } + ds = *dsp; + if (ds->ds_name) + free(ds->ds_name); + if (ds->ds_data) + free(ds->ds_data); + free(ds); + *dsp = NULL; +} + +int +_dwarf_pro_callback(Dwarf_P_Debug dbg, char *name, int size, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Unsigned *symndx, int *error) +{ + int e, ret, isymndx; + + assert(dbg != NULL && name != NULL && symndx != NULL); + + if (dbg->dbgp_func_b) + ret = dbg->dbgp_func_b(name, size, type, flags, link, info, + symndx, &e); + else { + ret = dbg->dbgp_func(name, size, type, flags, link, info, + &isymndx, &e); + *symndx = isymndx; + } + if (ret < 0) { + if (error) + *error = e; + } + + return (ret); +} + +int +_dwarf_section_callback(Dwarf_P_Debug dbg, Dwarf_P_Section ds, + Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, + Dwarf_Unsigned info, Dwarf_Error *error) +{ + int ret, ndx; + + ndx = _dwarf_pro_callback(dbg, ds->ds_name, (int) ds->ds_size, + type, flags, link, info, &ds->ds_symndx, NULL); + if (ndx < 0) { + ret = DW_DLE_ELF_SECT_ERR; + DWARF_SET_ERROR(dbg, error, ret); + return (ret); + } + ds->ds_ndx = ndx; + + return (DW_DLE_NONE); +} + +int +_dwarf_generate_sections(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + int ret; + + /* Produce .debug_info section. */ + if ((ret = _dwarf_info_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_abbrev section. */ + if ((ret = _dwarf_abbrev_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_line section. */ + if ((ret = _dwarf_lineno_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_frame section. */ + if ((ret = _dwarf_frame_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_aranges section. */ + if ((ret = _dwarf_arange_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_macinfo section. */ + if ((ret = _dwarf_macinfo_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_pubnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_pubnames", dbg->dbgp_pubs, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_weaknames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_weaknames", dbg->dbgp_weaks, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_funcnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_funcnames", dbg->dbgp_funcs, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_typenames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_typenames", dbg->dbgp_types, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_varnames section. */ + if ((ret = _dwarf_nametbl_gen(dbg, ".debug_varnames", dbg->dbgp_vars, + error)) != DW_DLE_NONE) + return (ret); + + /* Produce .debug_str section. */ + if ((ret = _dwarf_strtab_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Finally, update and generate all relocation sections. */ + if ((ret = _dwarf_reloc_gen(dbg, error)) != DW_DLE_NONE) + return (ret); + + /* Set section/relocation iterator to the first element. */ + dbg->dbgp_secpos = STAILQ_FIRST(&dbg->dbgp_seclist); + dbg->dbgp_drspos = STAILQ_FIRST(&dbg->dbgp_drslist); + + return (DW_DLE_NONE); +} + +Dwarf_Section * +_dwarf_find_section(Dwarf_Debug dbg, const char *name) +{ + Dwarf_Section *ds; + Dwarf_Half i; + + assert(name != NULL); + + for (i = 0; i < dbg->dbg_seccnt; i++) { + ds = &dbg->dbg_section[i]; + if (ds->ds_name != NULL && !strcmp(ds->ds_name, name)) + return (ds); + } + + return (NULL); +} + +Dwarf_P_Section +_dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name) +{ + Dwarf_P_Section ds; + + assert(dbg != NULL && name != NULL); + + STAILQ_FOREACH(ds, &dbg->dbgp_seclist, ds_next) { + if (ds->ds_name != NULL && !strcmp(ds->ds_name ,name)) + return (ds); + } + + return (NULL); +} + +void +_dwarf_section_cleanup(Dwarf_P_Debug dbg) +{ + Dwarf_P_Section ds, tds; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); + + STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { + STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, + ds_next); + if (ds->ds_name) + free(ds->ds_name); + if (ds->ds_data) + free(ds->ds_data); + free(ds); + } + dbg->dbgp_seccnt = 0; + dbg->dbgp_secpos = 0; +} diff --git a/contrib/elftoolchain/libdwarf/libdwarf_str.c b/contrib/elftoolchain/libdwarf/libdwarf_str.c new file mode 100644 index 0000000..0c1ccac --- /dev/null +++ b/contrib/elftoolchain/libdwarf/libdwarf_str.c @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2009,2010 Kai Wang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include "_libdwarf.h" + +ELFTC_VCSID("$Id: libdwarf_str.c 2070 2011-10-27 03:05:32Z jkoshy $"); + +#define _INIT_DWARF_STRTAB_SIZE 1024 + +int +_dwarf_strtab_add(Dwarf_Debug dbg, char *string, uint64_t *off, + Dwarf_Error *error) +{ + size_t len; + + assert(dbg != NULL && string != NULL); + + len = strlen(string) + 1; + while (dbg->dbg_strtab_size + len > dbg->dbg_strtab_cap) { + dbg->dbg_strtab_cap *= 2; + dbg->dbg_strtab = realloc(dbg->dbg_strtab, + (size_t) dbg->dbg_strtab_cap); + if (dbg->dbg_strtab == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + } + + if (off != NULL) + *off = dbg->dbg_strtab_size; + + strncpy(&dbg->dbg_strtab[dbg->dbg_strtab_size], string, len - 1); + dbg->dbg_strtab_size += len; + dbg->dbg_strtab[dbg->dbg_strtab_size - 1] = '\0'; + + return (DW_DLE_NONE); +} + +char * +_dwarf_strtab_get_table(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + return (dbg->dbg_strtab); +} + +int +_dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_Section *ds; + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { + ds = _dwarf_find_section(dbg, ".debug_str"); + if (ds == NULL) { + dbg->dbg_strtab = NULL; + dbg->dbg_strtab_cap = dbg->dbg_strtab_size = 0; + return (DW_DLE_NONE); + } + + dbg->dbg_strtab_cap = dbg->dbg_strtab_size = ds->ds_size; + + if (dbg->dbg_mode == DW_DLC_RDWR) { + if ((dbg->dbg_strtab = malloc((size_t) ds->ds_size)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(dbg->dbg_strtab, ds->ds_data, ds->ds_size); + } else + dbg->dbg_strtab = (char *) ds->ds_data; + } else { + /* DW_DLC_WRITE */ + + dbg->dbg_strtab_cap = _INIT_DWARF_STRTAB_SIZE; + dbg->dbg_strtab_size = 0; + + if ((dbg->dbg_strtab = malloc((size_t) dbg->dbg_strtab_cap)) == + NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + + dbg->dbg_strtab[0] = '\0'; + } + + return (DW_DLE_NONE); +} + +void +_dwarf_strtab_cleanup(Dwarf_Debug dbg) +{ + + assert(dbg != NULL); + + if (dbg->dbg_mode == DW_DLC_RDWR || dbg->dbg_mode == DW_DLC_WRITE) + free(dbg->dbg_strtab); +} + +int +_dwarf_strtab_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) +{ + Dwarf_P_Section ds; + int ret; + + assert(dbg != NULL); + + if ((ret = _dwarf_section_init(dbg, &ds, ".debug_str", 0, error)) != + DW_DLE_NONE) + return (ret); + + if (dbg->dbg_strtab_size > ds->ds_cap) { + ds->ds_data = realloc(ds->ds_data, + (size_t) dbg->dbg_strtab_size); + if (ds->ds_data == NULL) { + _dwarf_section_free(dbg, &ds); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + ds->ds_cap = dbg->dbg_strtab_size; + } + + memcpy(ds->ds_data, dbg->dbg_strtab, dbg->dbg_strtab_size); + ds->ds_size = dbg->dbg_strtab_size; + + /* + * Inform application the creation of .debug_str ELF section. + * Note that .debug_str use a different format than usual ELF + * string table, so it should not have SHT_STRTAB as its type. + */ + ret = _dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error); + + return (ret); +} diff --git a/contrib/elftoolchain/libelf/Makefile b/contrib/elftoolchain/libelf/Makefile new file mode 100644 index 0000000..b9e4e13 --- /dev/null +++ b/contrib/elftoolchain/libelf/Makefile @@ -0,0 +1,165 @@ +# $Id: Makefile 2605 2012-10-02 17:52:20Z jkoshy $ + +TOP= ${.CURDIR}/.. + +LIB= elf + +SRCS= elf.c \ + elf_begin.c \ + elf_cntl.c \ + elf_end.c elf_errmsg.c elf_errno.c \ + elf_data.c \ + elf_fill.c \ + elf_flag.c \ + elf_getarhdr.c \ + elf_getarsym.c \ + elf_getbase.c \ + elf_getident.c \ + elf_hash.c \ + elf_kind.c \ + elf_memory.c \ + elf_next.c \ + elf_open.c \ + elf_rand.c \ + elf_rawfile.c \ + elf_phnum.c \ + elf_shnum.c \ + elf_shstrndx.c \ + elf_scn.c \ + elf_strptr.c \ + elf_update.c \ + elf_version.c \ + gelf_cap.c \ + gelf_checksum.c \ + gelf_dyn.c \ + gelf_ehdr.c \ + gelf_getclass.c \ + gelf_fsize.c \ + gelf_move.c \ + gelf_phdr.c \ + gelf_rel.c \ + gelf_rela.c \ + gelf_shdr.c \ + gelf_sym.c \ + gelf_syminfo.c \ + gelf_symshndx.c \ + gelf_xlate.c \ + libelf_align.c \ + libelf_allocate.c \ + libelf_ar.c \ + libelf_ar_util.c \ + libelf_checksum.c \ + libelf_data.c \ + libelf_ehdr.c \ + libelf_extended.c \ + libelf_memory.c \ + libelf_open.c \ + libelf_phdr.c \ + libelf_shdr.c \ + libelf_xlate.c \ + ${GENSRCS} + +INCS= libelf.h gelf.h +INCSDIR= /usr/include + +GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c +CLEANFILES= ${GENSRCS} + +SHLIB_MAJOR= 1 + +WARNS?= 6 + +MAN= elf.3 \ + elf_begin.3 \ + elf_cntl.3 \ + elf_end.3 \ + elf_errmsg.3 \ + elf_fill.3 \ + elf_flagdata.3 \ + elf_getarhdr.3 \ + elf_getarsym.3 \ + elf_getbase.3 \ + elf_getdata.3 \ + elf_getident.3 \ + elf_getscn.3 \ + elf_getphdrnum.3 \ + elf_getphnum.3 \ + elf_getshdrnum.3 \ + elf_getshnum.3 \ + elf_getshdrstrndx.3 \ + elf_getshstrndx.3 \ + elf_hash.3 \ + elf_kind.3 \ + elf_memory.3 \ + elf_next.3 \ + elf_open.3 \ + elf_rawfile.3 \ + elf_rand.3 \ + elf_strptr.3 \ + elf_update.3 \ + elf_version.3 \ + gelf.3 \ + gelf_checksum.3 \ + gelf_fsize.3 \ + gelf_getcap.3 \ + gelf_getclass.3 \ + gelf_getdyn.3 \ + gelf_getehdr.3 \ + gelf_getmove.3 \ + gelf_getphdr.3 \ + gelf_getrel.3 \ + gelf_getrela.3 \ + gelf_getshdr.3 \ + gelf_getsym.3 \ + gelf_getsyminfo.3 \ + gelf_getsymshndx.3 \ + gelf_newehdr.3 \ + gelf_newphdr.3 \ + gelf_update_ehdr.3 \ + gelf_xlatetof.3 + +MLINKS+= \ + elf_errmsg.3 elf_errno.3 \ + elf_flagdata.3 elf_flagarhdr.3 \ + elf_flagdata.3 elf_flagehdr.3 \ + elf_flagdata.3 elf_flagelf.3 \ + elf_flagdata.3 elf_flagphdr.3 \ + elf_flagdata.3 elf_flagscn.3 \ + elf_flagdata.3 elf_flagshdr.3 \ + elf_getdata.3 elf_newdata.3 \ + elf_getdata.3 elf_rawdata.3 \ + elf_getscn.3 elf_ndxscn.3 \ + elf_getscn.3 elf_newscn.3 \ + elf_getscn.3 elf_nextscn.3 \ + elf_getshstrndx.3 elf_setshstrndx.3 \ + elf_open.3 elf_openmemory.3 \ + gelf_getcap.3 gelf_update_cap.3 \ + gelf_getdyn.3 gelf_update_dyn.3 \ + gelf_getmove.3 gelf_update_move.3 \ + gelf_getrel.3 gelf_update_rel.3 \ + gelf_getrela.3 gelf_update_rela.3 \ + gelf_getsym.3 gelf_update_sym.3 \ + gelf_getsyminfo.3 gelf_update_syminfo.3 \ + gelf_getsymshndx.3 gelf_update_symshndx.3 \ + gelf_update_ehdr.3 gelf_update_phdr.3 \ + gelf_update_ehdr.3 gelf_update_shdr.3 \ + gelf_xlatetof.3 gelf_xlatetom.3 + +.for E in 32 64 +MLINKS+= \ + gelf_checksum.3 elf${E}_checksum.3 \ + gelf_fsize.3 elf${E}_fsize.3 \ + gelf_getehdr.3 elf${E}_getehdr.3 \ + gelf_getphdr.3 elf${E}_getphdr.3 \ + gelf_getshdr.3 elf${E}_getshdr.3 \ + gelf_newehdr.3 elf${E}_newehdr.3 \ + gelf_newphdr.3 elf${E}_newphdr.3 \ + gelf_xlatetof.3 elf${E}_xlatetof.3 \ + gelf_xlatetof.3 elf${E}_xlatetom.3 +.endfor + +libelf_convert.c: elf_types.m4 libelf_convert.m4 +libelf_fsize.c: elf_types.m4 libelf_fsize.m4 +libelf_msize.c: elf_types.m4 libelf_msize.m4 + +.include "${TOP}/mk/elftoolchain.lib.mk" diff --git a/contrib/elftoolchain/libelf/Version.map b/contrib/elftoolchain/libelf/Version.map new file mode 100644 index 0000000..e71a591 --- /dev/null +++ b/contrib/elftoolchain/libelf/Version.map @@ -0,0 +1,96 @@ +/* $Id: Version.map 2574 2012-09-11 15:11:59Z jkoshy $ */ + +R1.0 { +global: + elf32_checksum; + elf32_fsize; + elf32_getehdr; + elf32_getphdr; + elf32_getshdr; + elf32_newehdr; + elf32_newphdr; + elf32_xlatetof; + elf32_xlatetom; + elf64_checksum; + elf64_fsize; + elf64_getehdr; + elf64_getphdr; + elf64_getshdr; + elf64_newehdr; + elf64_newphdr; + elf64_xlatetof; + elf64_xlatetom; + elf_begin; + elf_cntl; + elf_end; + elf_errmsg; + elf_errno; + elf_fill; + elf_flagarhdr; + elf_flagdata; + elf_flagehdr; + elf_flagelf; + elf_flagphdr; + elf_flagscn; + elf_flagshdr; + elf_getarhdr; + elf_getarsym; + elf_getbase; + elf_getdata; + elf_getident; + elf_getphdrnum; + elf_getphnum; + elf_getscn; + elf_getshdrnum; + elf_getshdrstrndx; + elf_getshnum; + elf_getshstrndx; + elf_hash; + elf_kind; + elf_memory; + elf_ndxscn; + elf_newdata; + elf_newscn; + elf_next; + elf_nextscn; + elf_open; + elf_openmemory; + elf_rand; + elf_rawdata; + elf_rawfile; + elf_setshstrndx; + elf_strptr; + elf_update; + elf_version; + gelf_checksum; + gelf_fsize; + gelf_getcap; + gelf_getclass; + gelf_getdyn; + gelf_getehdr; + gelf_getmove; + gelf_getphdr; + gelf_getrel; + gelf_getrela; + gelf_getshdr; + gelf_getsym; + gelf_getsyminfo; + gelf_getsymshndx; + gelf_newehdr; + gelf_newphdr; + gelf_update_cap; + gelf_update_dyn; + gelf_update_ehdr; + gelf_update_move; + gelf_update_phdr; + gelf_update_rel; + gelf_update_rela; + gelf_update_shdr; + gelf_update_sym; + gelf_update_syminfo; + gelf_update_symshndx; + gelf_xlatetof; + gelf_xlatetom; +local: + *; +}; diff --git a/contrib/elftoolchain/libelf/_libelf.h b/contrib/elftoolchain/libelf/_libelf.h new file mode 100644 index 0000000..fba2f97 --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf.h @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: _libelf.h 2365 2011-12-29 04:36:44Z jkoshy $ + */ + +#ifndef __LIBELF_H_ +#define __LIBELF_H_ + +#include <sys/queue.h> + +#include "_libelf_config.h" + +#include "_elftc.h" + +/* + * Library-private data structures. + */ + +#define LIBELF_MSG_SIZE 256 + +struct _libelf_globals { + int libelf_arch; + unsigned int libelf_byteorder; + int libelf_class; + int libelf_error; + int libelf_fillchar; + unsigned int libelf_version; + char libelf_msg[LIBELF_MSG_SIZE]; +}; + +extern struct _libelf_globals _libelf; + +#define LIBELF_PRIVATE(N) (_libelf.libelf_##N) + +#define LIBELF_ELF_ERROR_MASK 0xFF +#define LIBELF_OS_ERROR_SHIFT 8 + +#define LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ + ((O) << LIBELF_OS_ERROR_SHIFT)) + +#define LIBELF_SET_ERROR(E, O) do { \ + LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ + } while (0) + +#define LIBELF_ADJUST_AR_SIZE(S) (((S) + 1U) & ~1U) + +/* + * Flags for library internal use. These use the upper 16 bits of the + * `e_flags' field. + */ +#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */ +#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */ +#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */ +#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */ +#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */ +#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */ +#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */ +#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */ + +struct _Elf { + int e_activations; /* activation count */ + unsigned int e_byteorder; /* ELFDATA* */ + int e_class; /* ELFCLASS* */ + Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ + int e_fd; /* associated file descriptor */ + unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ + Elf_Kind e_kind; /* ELF_K_* */ + Elf *e_parent; /* non-NULL for archive members */ + char *e_rawfile; /* uninterpreted bytes */ + size_t e_rawsize; /* size of uninterpreted bytes */ + unsigned int e_version; /* file version */ + + /* + * Header information for archive members. See the + * LIBELF_F_AR_HEADER flag. + */ + union { + Elf_Arhdr *e_arhdr; /* translated header */ + char *e_rawhdr; /* untranslated header */ + } e_hdr; + + union { + struct { /* ar(1) archives */ + off_t e_next; /* set by elf_rand()/elf_next() */ + int e_nchildren; + char *e_rawstrtab; /* file name strings */ + size_t e_rawstrtabsz; + char *e_rawsymtab; /* symbol table */ + size_t e_rawsymtabsz; + Elf_Arsym *e_symtab; + size_t e_symtabsz; + } e_ar; + struct { /* regular ELF files */ + union { + Elf32_Ehdr *e_ehdr32; + Elf64_Ehdr *e_ehdr64; + } e_ehdr; + union { + Elf32_Phdr *e_phdr32; + Elf64_Phdr *e_phdr64; + } e_phdr; + STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ + size_t e_nphdr; /* number of Phdr entries */ + size_t e_nscn; /* number of sections */ + size_t e_strndx; /* string table section index */ + } e_elf; + } e_u; +}; + +/* + * The internal descriptor wrapping the "Elf_Data" type. + */ +struct _Libelf_Data { + Elf_Data d_data; /* The exported descriptor. */ + Elf_Scn *d_scn; /* The containing section */ + unsigned int d_flags; + STAILQ_ENTRY(_Libelf_Data) d_next; +}; + +struct _Elf_Scn { + union { + Elf32_Shdr s_shdr32; + Elf64_Shdr s_shdr64; + } s_shdr; + STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ + STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ + STAILQ_ENTRY(_Elf_Scn) s_next; + struct _Elf *s_elf; /* parent ELF descriptor */ + unsigned int s_flags; /* flags for the section as a whole */ + size_t s_ndx; /* index# for this section */ + uint64_t s_offset; /* managed by elf_update() */ + uint64_t s_rawoff; /* original offset in the file */ + uint64_t s_size; /* managed by elf_update() */ +}; + + +enum { + ELF_TOFILE, + ELF_TOMEMORY +}; + +#define LIBELF_COPY_U32(DST,SRC,NAME) do { \ + if ((SRC)->NAME > UINT_MAX) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (SRC)->NAME; \ + } while (0) + +#define LIBELF_COPY_S32(DST,SRC,NAME) do { \ + if ((SRC)->NAME > INT_MAX || \ + (SRC)->NAME < INT_MIN) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (SRC)->NAME; \ + } while (0) + + +/* + * Function Prototypes. + */ + +__BEGIN_DECLS +struct _Libelf_Data *_libelf_allocate_data(Elf_Scn *_s); +Elf *_libelf_allocate_elf(void); +Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx); +Elf_Arhdr *_libelf_ar_gethdr(Elf *_e); +Elf *_libelf_ar_open(Elf *_e, int _reporterror); +Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); +int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret); +Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); +Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); +unsigned long _libelf_checksum(Elf *_e, int _elfclass); +void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); +int _libelf_falign(Elf_Type _t, int _elfclass); +size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version, + size_t count); +int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass)) + (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap); +void *_libelf_getphdr(Elf *_e, int _elfclass); +void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass); +void _libelf_init_elf(Elf *_e, Elf_Kind _kind); +int _libelf_load_section_headers(Elf *e, void *ehdr); +int _libelf_malign(Elf_Type _t, int _elfclass); +Elf *_libelf_memory(char *_image, size_t _sz, int _reporterror); +size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); +void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); +Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); +struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); +Elf *_libelf_release_elf(Elf *_e); +Elf_Scn *_libelf_release_scn(Elf_Scn *_s); +int _libelf_setphnum(Elf *_e, void *_eh, int _elfclass, size_t _phnum); +int _libelf_setshnum(Elf *_e, void *_eh, int _elfclass, size_t _shnum); +int _libelf_setshstrndx(Elf *_e, void *_eh, int _elfclass, + size_t _shstrndx); +Elf_Data *_libelf_xlate(Elf_Data *_d, const Elf_Data *_s, + unsigned int _encoding, int _elfclass, int _direction); +int _libelf_xlate_shtype(uint32_t _sht); +__END_DECLS + +#endif /* __LIBELF_H_ */ diff --git a/contrib/elftoolchain/libelf/_libelf_ar.h b/contrib/elftoolchain/libelf/_libelf_ar.h new file mode 100644 index 0000000..d6b15a7 --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf_ar.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $ + */ + +#ifndef __LIBELF_AR_H_ +#define __LIBELF_AR_H_ + +/* + * Prototypes and declarations needed by libelf's ar(1) archive + * handling code. + */ + +#include <ar.h> + +#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX "#1/" +#define LIBELF_AR_BSD_SYMTAB_NAME "__.SYMDEF" +#define LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE \ + (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) + +#define IS_EXTENDED_BSD_NAME(NAME) \ + (strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0) + + +char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname, + int _svr4names); +char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh); +char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar); +int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base, + size_t *_ret); + +#endif /* __LIBELF_AR_H_ */ diff --git a/contrib/elftoolchain/libelf/_libelf_config.h b/contrib/elftoolchain/libelf/_libelf_config.h new file mode 100644 index 0000000..b9442fd --- /dev/null +++ b/contrib/elftoolchain/libelf/_libelf_config.h @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: _libelf_config.h 2287 2011-12-04 06:45:47Z jkoshy $ + */ + +#ifdef __DragonFly__ + +#if defined(__amd64__) +#define LIBELF_ARCH EM_X86_64 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS64 +#elif defined(__i386__) +#define LIBELF_ARCH EM_386 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS32 +#endif + +#endif /* __DragonFly__ */ + +#ifdef __FreeBSD__ + +/* + * Define LIBELF_{ARCH,BYTEORDER,CLASS} based on the machine architecture. + * See also: <machine/elf.h>. + */ + +#if defined(__amd64__) + +#define LIBELF_ARCH EM_X86_64 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS64 + +#elif defined(__arm__) + +#define LIBELF_ARCH EM_ARM +#if defined(__ARMEB__) /* Big-endian ARM. */ +#define LIBELF_BYTEORDER ELFDATA2MSB +#else +#define LIBELF_BYTEORDER ELFDATA2LSB +#endif +#define LIBELF_CLASS ELFCLASS32 + +#elif defined(__i386__) + +#define LIBELF_ARCH EM_386 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS32 + +#elif defined(__ia64__) + +#define LIBELF_ARCH EM_IA_64 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS64 + +#elif defined(__mips__) + +#define LIBELF_ARCH EM_MIPS +#if defined(__MIPSEB__) +#define LIBELF_BYTEORDER ELFDATA2MSB +#else +#define LIBELF_BYTEORDER ELFDATA2LSB +#endif +#define LIBELF_CLASS ELFCLASS32 + +#elif defined(__powerpc__) + +#define LIBELF_ARCH EM_PPC +#define LIBELF_BYTEORDER ELFDATA2MSB +#define LIBELF_CLASS ELFCLASS32 + +#elif defined(__sparc__) + +#define LIBELF_ARCH EM_SPARCV9 +#define LIBELF_BYTEORDER ELFDATA2MSB +#define LIBELF_CLASS ELFCLASS64 + +#else +#error Unknown FreeBSD architecture. +#endif +#endif /* __FreeBSD__ */ + +/* + * Definitions for Minix3. + */ +#ifdef __minix + +#define LIBELF_ARCH EM_386 +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS32 + +#endif /* __minix */ + +#ifdef __NetBSD__ + +#include <machine/elf_machdep.h> + +#if !defined(ARCH_ELFSIZE) +#error ARCH_ELFSIZE is not defined. +#endif + +#if ARCH_ELFSIZE == 32 +#define LIBELF_ARCH ELF32_MACHDEP_ID +#define LIBELF_BYTEORDER ELF32_MACHDEP_ENDIANNESS +#define LIBELF_CLASS ELFCLASS32 +#define Elf_Note Elf32_Nhdr +#else +#define LIBELF_ARCH ELF64_MACHDEP_ID +#define LIBELF_BYTEORDER ELF64_MACHDEP_ENDIANNESS +#define LIBELF_CLASS ELFCLASS64 +#define Elf_Note Elf64_Nhdr +#endif + +#endif /* __NetBSD__ */ + +#if defined(__OpenBSD__) + +#include <machine/exec.h> + +#define LIBELF_ARCH ELF_TARG_MACH +#define LIBELF_BYTEORDER ELF_TARG_DATA +#define LIBELF_CLASS ELF_TARG_CLASS + +#endif + +/* + * GNU & Linux compatibility. + * + * `__linux__' is defined in an environment runs the Linux kernel and glibc. + * `__GNU__' is defined in an environment runs a GNU kernel (Hurd) and glibc. + * `__GLIBC__' is defined for an environment that runs glibc over a non-GNU + * kernel such as GNU/kFreeBSD. + */ + +#if defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) + +#if defined(__linux__) + +#include "native-elf-format.h" + +#define LIBELF_CLASS ELFTC_CLASS +#define LIBELF_ARCH ELFTC_ARCH +#define LIBELF_BYTEORDER ELFTC_BYTEORDER + +#endif /* defined(__linux__) */ + +#if LIBELF_CLASS == ELFCLASS32 +#define Elf_Note Elf32_Nhdr +#elif LIBELF_CLASS == ELFCLASS64 +#define Elf_Note Elf64_Nhdr +#else +#error LIBELF_CLASS needs to be one of ELFCLASS32 or ELFCLASS64 +#endif + +#endif /* defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) */ diff --git a/contrib/elftoolchain/libelf/elf.3 b/contrib/elftoolchain/libelf/elf.3 new file mode 100644 index 0000000..462e728 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf.3 @@ -0,0 +1,589 @@ +.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf.3 2885 2013-01-11 02:11:28Z jkoshy $ +.\" +.Dd August 14, 2011 +.Os +.Dt ELF 3 +.Sh NAME +.Nm elf +.Nd API for manipulating ELF objects +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Sh DESCRIPTION +The +.Lb libelf +provides functions that allow an application to read and manipulate +ELF object files, and to read +.Xr ar 1 +archives. +The library allows the manipulation of ELF objects in a byte ordering +and word-size independent way, allowing an application to read and +create ELF objects for 32 and 64 bit architectures and for little- +and big-endian machines. +The library is capable of processing ELF objects that use extended +section numbering. +.Pp +This manual page serves to provide an overview of the functionality in +the ELF library. +Further information may found in the manual pages for individual +.Xr ELF 3 +functions that comprise the library. +.Ss ELF Concepts +As described in +.Xr elf 5 , +ELF files contain several data structures that are laid out in a +specific way. +ELF files begin with an +.Dq Executable Header , +and may contain an optional +.Dq Program Header Table , +and optional data in the form of ELF +.Dq sections . +A +.Dq Section Header Table +describes the content of the data in these sections. +.Pp +ELF objects have an associated +.Dq "ELF class" +which denotes the natural machine word size for the architecture +the object is associated with. +Objects for 32 bit architectures have an ELF class of +.Dv ELFCLASS32 . +Objects for 64 bit architectures have an ELF class of +.Dv ELFCLASS64 . +.Pp +ELF objects also have an associated +.Dq endianness +which denotes the endianness of the machine architecture associated +with the object. +This may be +.Dv ELFDATA2LSB +for little-endian architectures and +.Dv ELFDATA2MSB +for big-endian architectures. +.Pp +ELF objects are also associated with an API version number. +This version number determines the layout of the individual components +of an ELF file and the semantics associated with these. +.Ss Data Representation And Translation +The +.Xr ELF 3 +library distinguishes between +.Dq native +representations of ELF data structures and their +.Dq file +representations. +.Pp +An application would work with ELF data in its +.Dq native +representation, i.e., using the native byteorder and alignment mandated +by the processor the application is running on. +The +.Dq file +representation of the same data could use a different byte ordering +and follow different constraints on object alignment than these native +constraints. +.Pp +Accordingly, the +.Xr ELF 3 +library offers translation facilities +.Xr ( elf32_xlatetof 3 , +.Xr elf32_xlatetom 3 , +.Xr elf64_xlatetof 3 +and +.Xr elf64_xlatetom 3 ) +to and from these +representations and also provides higher-level APIs that retrieve and store +data from the ELF object in a transparent manner. +.Ss Library Working Version +Conceptually, there are three version numbers associated with an +application using the ELF library to manipulate ELF objects: +.Bl -bullet -compact -offset indent +.It +The ELF version that the application was compiled against. +This version determines the ABI expected by the application. +.It +The ELF version of the ELF object being manipulated by the +application through the ELF library. +.It +The ELF version (or set of versions) supported by the ELF library itself. +.El +.Pp +In order to facilitate working with ELF objects of differing versions, +the ELF library requires the application to call the +.Fn elf_version +function before invoking many of its operations, in order to inform +the library of the application's desired working version. +.Pp +In the current implementation, all three versions have to be +.Dv EV_CURRENT . +.Ss Namespace use +The ELF library uses the following prefixes: +.Bl -tag -width "ELF_F_*" +.It Dv elf_ +Used for class-independent functions. +.It Dv elf32_ +Used for functions working with 32 bit ELF objects. +.It Dv elf64_ +Used for functions working with 64 bit ELF objects. +.It Dv Elf_ +Used for class-independent data types. +.It Dv ELF_C_ +Used for command values used in a few functions. +These symbols are defined as members of the +.Vt Dv Elf_Cmd +enumeration. +.It Dv ELF_E_ +Used for error numbers. +.It Dv ELF_F_ +Used for flags. +.It Dv ELF_K_ +These constants define the kind of file associated with an ELF +descriptor. +See +.Xr elf_kind 3 . +The symbols are defined by the +.Vt Elf_Kind +enumeration. +.It Dv ELF_T_ +These values are defined by the +.Vt Elf_Type +enumeration, and denote the types of ELF data structures +that can be present in an ELF object. +.El +.Pp +In addition, the library uses symbols with prefixes +.Dv _ELF +and +.Dv _libelf +for its internal use. +.Ss Descriptors +Applications communicate with the library using descriptors. +These are: +.Bl -tag -width ".Vt Elf_Data" +.It Vt Elf +An +.Vt Elf +descriptor represents an ELF object or an +.Xr ar 1 +archive. +It is allocated using one of the +.Fn elf_begin +or +.Fn elf_memory +functions. +An +.Vt Elf +descriptor can be used to read and write data to an ELF file. +An +.Vt Elf +descriptor can be associated with zero or more +.Vt Elf_Scn +section descriptors. +.Pp +Given an ELF descriptor, the application may retrieve the ELF +object's class-dependent +.Dq "Executable Header" +structures using the +.Fn elf32_getehdr +or +.Fn elf64_getehdr +functions. +A new Ehdr structure may be allocated using the +.Fn elf64_newehdr +or +.Fn elf64_newehdr +functions. +.Pp +The +.Dq "Program Header Table" +associated with an ELF descriptor may be allocated using the +.Fn elf32_getphdr +or +.Fn elf64_getphdr +functions. +A new program header table may be allocated or an existing table +resized using the +.Fn elf32_newphdr +or +.Fn elf64_newphdr +functions. +.Pp +The +.Vt Elf +structure is opaque and has no members visible to the +application. +.\" TODO describe the Elf_Arhdr and Elf_Arsym structures. +.It Vt Elf_Data +An +.Vt Elf_Data +data structure describes an individual chunk of a ELF file as +represented in memory. +It has the following application-visible members: +.Bl -tag -width ".Vt unsigned int d_version" -compact +.It Vt "uint64_t d_align" +The in-file alignment of the data buffer within its containing ELF section. +This value must be non-zero and a power of two. +.It Vt "void *d_buf" +A pointer to data in memory. +.It Vt "uint64_t d_off" +The offset within the containing section where this descriptor's data +would be placed. +This field will be computed by the library unless the application +requests full control of the ELF object's layout. +.It Vt "uint64_t d_size" +The number of bytes of data in this descriptor. +.It Vt "Elf_Type d_type" +The ELF type (see below) of the data in this descriptor. +.It Vt "unsigned int d_version" +The operating version for the data in this buffer. +.El +.Pp +.Vt Elf_Data +descriptors are usually associated with +.Vt Elf_Scn +descriptors. +Existing data descriptors associated with an ELF section may be +structures are retrieved using the +.Fn elf_getdata +and +.Fn elf_rawdata +functions. +The +.Fn elf_newdata +function may be used to attach new data descriptors to an ELF section. +.It Vt Elf_Scn +.Vt Elf_Scn +descriptors represent a section in an ELF object. +.Pp +They are retrieved using the +.Fn elf_getscn +function. +An application may iterate through the existing sections of an ELF +object using the +.Fn elf_nextscn +function. +New sections may be allocated using the +.Fn elf_newscn +function. +.Pp +The +.Vt Elf_Scn +descriptor is opaque and contains no application modifiable fields. +.El +.Ss Supported Elf Types +The following ELF datatypes are supported by the library. +.Pp +.Bl -tag -width ".Dv ELF_T_SYMINFO" -compact +.It Dv ELF_T_ADDR +Machine addresses. +.It Dv ELF_T_BYTE +Byte data. +The library will not attempt to translate byte data. +.It Dv ELF_T_CAP +Software and hardware capability records. +.It Dv ELF_T_DYN +Records used in a section of type +.Dv SHT_DYNAMIC . +.It Dv ELF_T_EHDR +ELF executable header. +.It Dv ELF_T_GNUHASH +GNU-style hash tables. +.It Dv ELF_T_HALF +16-bit unsigned words. +.It Dv ELF_T_LWORD +64 bit unsigned words. +.It Dv ELF_T_MOVE +ELF Move records. +.\".It Dv ELF_T_MOVEP +.\" As yet unsupported. +.It Dv ELF_T_NOTE +ELF Note structures. +.It Dv ELF_T_OFF +File offsets. +.It Dv ELF_T_PHDR +ELF program header table entries. +.It Dv ELF_T_REL +ELF relocation entries. +.It Dv ELF_T_RELA +ELF relocation entries with addends. +.It Dv ELF_T_SHDR +ELF section header entries. +.It Dv ELF_T_SWORD +Signed 32-bit words. +.It Dv ELF_T_SXWORD +Signed 64-bit words. +.It Dv ELF_T_SYMINFO +ELF symbol information. +.It Dv ELF_T_SYM +ELF symbol table entries. +.It Dv ELF_T_VDEF +Symbol version definition records. +.It Dv ELF_T_VNEED +Symbol version requirement records. +.It Dv ELF_T_WORD +Unsigned 32-bit words. +.It Dv ELF_T_XWORD +Unsigned 64-bit words. +.El +.Pp +The symbol +.Dv ELF_T_NUM +denotes the number of Elf types known to the library. +.Pp +The following table shows the mapping between ELF section types +defined in +.Xr elf 5 +and the types supported by the library. +.Bl -column ".Dv SHT_PREINIT_ARRAY" ".Dv ELF_T_SYMINFO" +.It Em Section Type Ta Em "Library Type" Ta Em Description +.It Dv SHT_DYNAMIC Ta Dv ELF_T_DYN Ta Xo +.Sq .dynamic +section entries. +.Xc +.It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking. +.It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers. +.It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker. +.It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes. +.It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers. +.It Dv SHT_NOBITS Ta Dv ELF_T_BYTE Ta Xo +Empty sections. +See +.Xr elf 5 . +.Xc +.It Dv SHT_NOTE Ta Dv ELF_T_NOTE Ta ELF note records. +.It Dv SHT_PREINIT_ARRAY Ta Dv ELF_T_ADDR Ta Pre-initialization function pointers. +.It Dv SHT_PROGBITS Ta Dv ELF_T_BYTE Ta Machine code. +.It Dv SHT_REL Ta Dv ELF_T_REL Ta ELF relocation records. +.It Dv SHT_RELA Ta Dv ELF_T_RELA Ta Relocation records with addends. +.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables. +.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables. +.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering. +.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions. +.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements. +.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols. +.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. +.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. +.El +.TE +.Ss Functional Grouping +This section contains a brief overview of the available functionality +in the ELF library. +Each function listed here is described further in its own manual page. +.Bl -tag -width indent +.It "Archive Access" +.Bl -tag -compact +.It Fn elf_getarsym +Retrieve the archive symbol table. +.It Fn elf_getarhdr +Retrieve the archive header for an object. +.It Fn elf_getbase +Retrieve the offset of a member inside an archive. +.It Fn elf_next +Iterate through an +.Xr ar 1 +archive. +.It Fn elf_rand +Random access inside an +.Xr ar 1 +archive. +.El +.It "Data Structures" +.Bl -tag -compact +.It Fn elf_getdata +Retrieve translated data for an ELF section. +.It Fn elf_getscn +Retrieve the section descriptor for a named section. +.It Fn elf_ndxscn +Retrieve the index for a section. +.It Fn elf_newdata +Add a new +.Vt Elf_Data +descriptor to an ELF section. +.It Fn elf_newscn +Add a new section descriptor to an ELF descriptor. +.It Fn elf_nextscn +Iterate through the sections in an ELF object. +.It Fn elf_rawdata +Retrieve untranslated data for an ELF section. +.It Fn elf_rawfile +Return a pointer to the untranslated file contents for an ELF object. +.It Fn elf32_getehdr , Fn elf64_getehdr +Retrieve the Executable Header in an ELF object. +.It Fn elf32_getphdr , Fn elf64_getphdr +Retrieve the Program Header Table in an ELF object. +.It Fn elf32_getshdr , Fn elf64_getshdr +Retrieve the ELF section header associated with an +.Vt Elf_Scn +descriptor. +.It Fn elf32_newehdr , Fn elf64_newehdr +Allocate an Executable Header in an ELF object. +.It Fn elf32_newphdr , Fn elf64_newphdr +Allocate or resize the Program Header Table in an ELF object. +.El +.It "Data Translation" +.Bl -tag -compact +.It Fn elf32_xlatetof , Fn elf64_xlatetof +Translate an ELF data structure from its native representation to its +file representation. +.It Fn elf32_xlatetom , Fn elf64_xlatetom +Translate an ELF data structure from its file representation to a +native representation. +.El +.It "Error Reporting" +.Bl -tag -compact +.It Fn elf_errno +Retrieve the current error. +.It Fn elf_errmsg +Retrieve a human readable description of the current error. +.El +.It "Initialization" +.Bl -tag -compact +.It Fn elf_begin +Opens an +.Xr ar 1 +archive or ELF object given a file descriptor. +.It Fn elf_end +Close an ELF descriptor and release all its resources. +.It Fn elf_memory +Opens an +.Xr ar 1 +archive or ELF object present in a memory arena. +.It Fn elf_version +Sets the operating version. +.El +.It "IO Control" +.Bl -tag -width ".Fn elf_setshstrndx" -compact +.It Fn elf_cntl +Manage the association between and ELF descriptor and its underlying file. +.It Fn elf_flagdata +Mark an +.Vt Elf_Data +descriptor as dirty. +.It Fn elf_flagehdr +Mark the ELF Executable Header in an ELF descriptor as dirty. +.It Fn elf_flagphdr +Mark the ELF Program Header Table in an ELF descriptor as dirty. +.It Fn elf_flagscn +Mark an +.Vt Elf_Scn +descriptor as dirty. +.It Fn elf_flagshdr +Mark an ELF Section Header as dirty. +.It Fn elf_setshstrndx +Set the index of the section name string table for the ELF object. +.It Fn elf_update +Recompute ELF object layout and optionally write the modified object +back to the underlying file. +.El +.It "Queries" +.Bl -tag -width ".Fn elf_getshstrndx" -compact +.It Fn elf32_checksum , Fn elf64_checkum +Compute checksum of an ELF object. +.It Fn elf_getident +Retrieve the identification bytes for an ELF object. +.It Fn elf_getshnum +Retrieve the number of sections in an ELF object. +.It Fn elf_getshstrndx +Retrieve the section index of the section name string table in +an ELF object. +.It Fn elf_hash +Compute the ELF hash value of a string. +.It Fn elf_kind +Query the kind of object associated with an ELF descriptor. +.It Fn elf32_fsize , Fn elf64_fsize +Return the size of the file representation of an ELF type. +.El +.El +.Ss Controlling ELF Object Layout +In the usual mode of operation, library will compute section +offsets and alignments based on the contents of an ELF descriptor's +sections without need for further intervention by the +application. +.Pp +However, if the application wishes to take complete charge of the +layout of the ELF file, it may set the +.Dv ELF_F_LAYOUT +flag on an ELF descriptor using +.Xr elf_flagelf 3 , +following which the library will use the data offsets and alignments +specified by the application when laying out the file. +Application control of file layout is described further in the +.Xr elf_update 3 +manual page. +.Pp +Gaps in between sections will be filled with the fill character +set by function +.Fn elf_fill . +.Ss Error Handling +In case an error is encountered, these library functions set an +internal error number and signal the presence of the error by +returning an special return value. +The application can check the +current error number by calling +.Xr elf_errno 3 . +A human readable description of the recorded error is available by +calling +.Xr elf_errmsg 3 . +.Ss Memory Management Rules +The library keeps track of all +.Vt Elf_Scn +and +.Vt Elf_Data +descriptors associated with an ELF descriptor and recovers them +when the descriptor is closed using +.Xr elf_end 3 . +Thus the application must not call +.Xr free 3 +on data structures allocated by the ELF library. +.Pp +Conversely the library will not +free data that it has not allocated. +As an example, an application may call +.Xr elf_newdata 3 +to allocate a new +.Vt Elf_Data +descriptor and can set the +.Va d_off +member of the descriptor to point to a region of memory allocated +using +.Xr malloc 3 . +It is the applications responsibility to free this arena, though the +library will reclaim the space used by the +.Vt Elf_Data +descriptor itself. +.Sh SEE ALSO +.Xr gelf 3 , +.Xr elf 5 +.Sh HISTORY +The original ELF(3) API was developed for Unix System V. +The current implementation of the ELF(3) API appeared in +.Fx 7.0 . +.Sh AUTHORS +The ELF library was written by +.An "Joseph Koshy" +.Aq jkoshy@FreeBSD.org . diff --git a/contrib/elftoolchain/libelf/elf.c b/contrib/elftoolchain/libelf/elf.c new file mode 100644 index 0000000..8f1925e --- /dev/null +++ b/contrib/elftoolchain/libelf/elf.c @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +struct _libelf_globals _libelf = { + .libelf_arch = LIBELF_ARCH, + .libelf_byteorder = LIBELF_BYTEORDER, + .libelf_class = LIBELF_CLASS, + .libelf_error = 0, + .libelf_fillchar = 0, + .libelf_version = EV_NONE +}; diff --git a/contrib/elftoolchain/libelf/elf_begin.3 b/contrib/elftoolchain/libelf/elf_begin.3 new file mode 100644 index 0000000..960456a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_begin.3 @@ -0,0 +1,315 @@ +.\" Copyright (c) 2006,2008-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_begin.3 2313 2011-12-11 06:19:24Z jkoshy $ +.\" +.Dd December 11, 2011 +.Os +.Dt ELF_BEGIN 3 +.Sh NAME +.Nm elf_begin +.Nd open an ELF file or ar(1) archive +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_begin "int fd" "Elf_Cmd cmd" "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_begin +is used to open ELF files and +.Xr ar 1 +archives for further processing by other APIs in the +.Xr elf 3 +library. +It is also used to access individual ELF members of an +.Xr ar 1 +archive in combination with the +.Xr elf_next 3 +and +.Xr elf_rand 3 +APIs. +.Pp +Argument +.Ar fd +is an open file descriptor returned from an +.Xr open 2 +system call. +Function +.Fn elf_begin +uses argument +.Ar fd +for reading or writing depending on the value of argument +.Ar cmd . +Argument +.Ar elf +is primarily used for iterating through archives. +.Pp +The argument +.Ar cmd +can have the following values: +.Bl -tag -width "ELF_C_WRITE" +.It ELF_C_NULL +Causes +.Fn elf_begin +to return NULL. +Arguments +.Ar fd +and +.Ar elf +are ignored, and no additional error is signalled. +.It ELF_C_READ +This value is to be when the application wishes to examine (but not +modify) the contents of the file specified by the arguments +.Ar fd +and +.Ar elf . +It can be used for both +.Xr ar 1 +archives and for ELF objects. +.Pp +If argument +.Ar elf +is NULL, the library will allocate a new ELF descriptor for the file +being processed. +The argument +.Ar fd +should have been opened for reading. +.Pp +If argument +.Ar elf +is not NULL, and references a regular ELF file previously opened with +.Fn elf_begin , +then the activation count for the descriptor referenced by argument +.Ar elf +is incremented. +The value in argument +.Ar fd +should match that used to open the descriptor argument +.Ar elf . +.Pp +If argument +.Ar elf +is not NULL, and references a descriptor for an +.Xr ar 1 +archive opened earlier with +.Fn elf_begin , +a descriptor for an element in the archive is returned as +described in the section +.Sx "Processing ar(1) archives" +below. +The value for argument +.Ar fd +should match that used to open the archive earlier. +.Pp +If argument +.Ar elf +is not NULL, and references an +.Xr ar 1 +archive opened earlier with +.Fn elf_memory , +then the value of the argument +.Ar fd +is ignored. +.It Dv ELF_C_RDWR +This command is used to prepare an ELF file for reading and writing. +This command is not supported for +.Xr ar 1 +archives. +.Pp +Argument +.Ar fd +should have been opened for reading and writing. +If argument +.Ar elf +is NULL, the library will allocate a new ELF descriptor for +the file being processed. +If the argument +.Ar elf +is non-null, it should point to a descriptor previously +allocated with +.Fn elf_begin +with the same values for arguments +.Ar fd +and +.Ar cmd ; +in this case the library will increment the activation count for descriptor +.Ar elf +and return the same descriptor. +.Pp +Changes to the in-memory image of the ELF file may be written back to +disk using the +.Xr elf_update 3 +function. +.It Dv ELF_C_WRITE +This command is used when the application wishes to create a new ELF +file. +Argument +.Ar fd +should have been opened for writing. +Argument +.Ar elf +is ignored, and the previous contents of file referenced by argument +.Ar fd +are overwritten. +.El +.Ss Processing ar(1) archives +An +.Xr ar 1 +archive may be opened in read mode (with argument +.Ar cmd +set to +.Dv ELF_C_READ ) +using +.Fn elf_begin +or +.Fn elf_memory . +The returned ELF descriptor can be passed into to +subsequent calls to +.Fn elf_begin +to access individual members of the archive. +.Pp +Random access within an opened archive is possible using +the +.Xr elf_next 3 +and +.Xr elf_rand 3 +functions. +.Pp +The symbol table of the archive may be retrieved +using +.Xr elf_getarsym 3 . +.Sh RETURN VALUES +The function returns a pointer to a ELF descriptor if successful, or NULL +if an error occurred. +.Sh EXAMPLES +To iterate through the members of an +.Xr ar 1 +archive, use: +.Bd -literal -offset indent +Elf_Cmd c; +Elf *ar_e, *elf_e; +\&... +c = ELF_C_READ; +if ((ar_e = elf_begin(fd, c, (Elf *) 0)) == 0) { + \&... handle error in opening the archive ... +} +while ((elf_e = elf_begin(fd, c, ar_e)) != 0) { + \&... process member referenced by elf_e here ... + c = elf_next(elf_e); + elf_end(elf_e); +} +.Ed +.Pp +To create a new ELF file, use: +.Bd -literal -offset indent +int fd; +Elf *e; +\&... +if ((fd = open("filename", O_RDWR|O_TRUNC|O_CREAT, 0666)) < 0) { + \&... handle the error from open(2) ... +} +if ((e = elf_begin(fd, ELF_C_WRITE, (Elf *) 0)) == 0) { + \&... handle the error from elf_begin() ... +} +\&... create the ELF image using other elf(3) APIs ... +elf_update(e, ELF_C_WRITE); +elf_end(e); +.Ed +.Sh ERRORS +Function +.Fn elf_begin +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARCHIVE +The archive denoted by argument +.Ar elf +could not be parsed. +.It Bq Er ELF_E_ARGUMENT +The value in argument +.Ar cmd +was unrecognized. +.It Bq Er ELF_E_ARGUMENT +A non-null value for argument +.Ar elf +was specified when +.Ar cmd +was set to +.Dv ELF_C_RDWR . +.It Bq Er ELF_E_ARGUMENT +The value of argument +.Ar fd +differs from the one the ELF descriptor +.Ar elf +was created with. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar cmd +differs from the value specified when ELF descriptor +.Ar elf +was created. +.It Bq Er ELF_E_ARGUMENT +An +.Xr ar 1 +archive was opened with with +.Ar cmd +set to +.Dv ELF_C_RDWR . +.It Bq Er ELF_E_ARGUMENT +The file referenced by argument +.Ar fd +was empty. +.It Bq Er ELF_E_ARGUMENT +The underlying file for argument +.Ar fd +was of an unsupported type. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Ar fd +was invalid. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Ar fd +could not be read or written to. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was encountered. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_begin +was called before a working version was established with +.Xr elf_version 3 . +.It Bq Er ELF_E_VERSION +The ELF object referenced by argument +.Ar fd +was of an unsupported ELF version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_end 3 , +.Xr elf_errno 3 , +.Xr elf_memory 3 , +.Xr elf_next 3 , +.Xr elf_rand 3 , +.Xr elf_update 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_begin.c b/contrib/elftoolchain/libelf/elf_begin.c new file mode 100644 index 0000000..9f4f237 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_begin.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_begin.c 2364 2011-12-28 17:55:25Z jkoshy $"); + +Elf * +elf_begin(int fd, Elf_Cmd c, Elf *a) +{ + Elf *e; + + e = NULL; + + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + switch (c) { + case ELF_C_NULL: + return (NULL); + + case ELF_C_WRITE: + /* + * The ELF_C_WRITE command is required to ignore the + * descriptor passed in. + */ + a = NULL; + break; + + case ELF_C_RDWR: + if (a != NULL) { /* not allowed for ar(1) archives. */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + /*FALLTHROUGH*/ + case ELF_C_READ: + /* + * Descriptor `a' could be for a regular ELF file, or + * for an ar(1) archive. If descriptor `a' was opened + * using a valid file descriptor, we need to check if + * the passed in `fd' value matches the original one. + */ + if (a && + ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + break; + + default: + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + + } + + if (a == NULL) + e = _libelf_open_object(fd, c, 1); + else if (a->e_kind == ELF_K_AR) + e = _libelf_ar_open_member(a->e_fd, c, a); + else + (e = a)->e_activations++; + + return (e); +} diff --git a/contrib/elftoolchain/libelf/elf_cntl.3 b/contrib/elftoolchain/libelf/elf_cntl.3 new file mode 100644 index 0000000..32649d1 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_cntl.3 @@ -0,0 +1,111 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_cntl.3 289 2009-01-08 08:26:08Z jkoshy $ +.\" +.Dd August 9, 2006 +.Os +.Dt ELF_CNTL 3 +.Sh NAME +.Nm elf_cntl +.Nd control an elf file descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_cntl "Elf *elf" "Elf_Cmd cmd" +.Sh DESCRIPTION +Function +.Fn elf_cntl +controls the ELF library's subsequent use of the file descriptor +used to create ELF descriptor +.Ar elf . +.Pp +Argument +.Ar cmd +informs the library of the action to be taken: +.Bl -tag -width "ELF_C_FDDONE" +.It Dv ELF_C_FDDONE +This value instructs the ELF library not to perform any further +I/O on the file descriptor associated with argument +.Ar elf . +For ELF descriptors opened with mode +.Ar ELF_C_WRITE +or +.Ar ELF_C_RDWR +subsequent +.Fn elf_update +operations on the descriptor will fail. +.It Dv ELF_C_FDREAD +This value instructs the ELF library to read in all necessary +data associated with ELF descriptor +.Ar elf +into memory so that the underlying file descriptor can be +safely closed with command +.Dv ELF_C_FDDONE . +.El +.Pp +Argument +.Ar elf +must be an ELF descriptor associated with a file system object +(e.g., an +.Xr ar 1 +archive, an ELF file, or other data file). +.Sh IMPLEMENTATION NOTES +Due to use of +.Xr mmap 2 +internally, this function is a no-op for ELF objects opened in +.Dv ELF_C_READ +mode. +.Sh RETURN VALUES +Function +.Fn elf_cntl +returns 0 on success, or -1 if an error was detected. +.Sh ERRORS +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARCHIVE +Argument +.Ar elf +is a descriptor for an archive member. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar cmd +was not recognized. +.It Bq Er ELF_E_MODE +An +.Dv ELF_C_FDREAD +operation was requested on an ELF descriptor opened +for writing. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_next 3 , +.Xr elf_update 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_cntl.c b/contrib/elftoolchain/libelf/elf_cntl.c new file mode 100644 index 0000000..0607885 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_cntl.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_cntl.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +int +elf_cntl(Elf *e, Elf_Cmd c) +{ + if (e == NULL || + (c != ELF_C_FDDONE && c != ELF_C_FDREAD)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if (e->e_parent) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (-1); + } + + if (c == ELF_C_FDREAD) { + if (e->e_cmd == ELF_C_WRITE) { + LIBELF_SET_ERROR(MODE, 0); + return (-1); + } + else + return (0); + } + + e->e_fd = -1; + return 0; +} diff --git a/contrib/elftoolchain/libelf/elf_data.c b/contrib/elftoolchain/libelf/elf_data.c new file mode 100644 index 0000000..06a3577 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_data.c @@ -0,0 +1,256 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <assert.h> +#include <errno.h> +#include <libelf.h> +#include <stdlib.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_data.c 2921 2013-03-04 16:19:22Z jkoshy $"); + +Elf_Data * +elf_getdata(Elf_Scn *s, Elf_Data *ed) +{ + Elf *e; + unsigned int sh_type; + int elfclass, elftype; + size_t fsz, msz, count; + struct _Libelf_Data *d; + uint64_t sh_align, sh_offset, sh_size; + int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + + d = (struct _Libelf_Data *) ed; + + if (s == NULL || (e = s->s_elf) == NULL || + (d != NULL && s != d->d_scn)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) + return (&d->d_data); + + if (d != NULL) + return (&STAILQ_NEXT(d, d_next)->d_data); + + if (e->e_rawfile == NULL) { + /* + * In the ELF_C_WRITE case, there is no source that + * can provide data for the section. + */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + elfclass = e->e_class; + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + + if (elfclass == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_offset = s->s_shdr.s_shdr64.sh_offset; + sh_size = s->s_shdr.s_shdr64.sh_size; + sh_align = s->s_shdr.s_shdr64.sh_addralign; + } + + if (sh_type == SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || + elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && + sh_offset + sh_size > (uint64_t) e->e_rawsize)) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) + (elftype, (size_t) 1, e->e_version)) == 0) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (NULL); + } + + if (sh_size % fsz) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + count = sh_size / fsz; + + msz = _libelf_msize(elftype, elfclass, e->e_version); + + assert(msz > 0); + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + d->d_data.d_buf = NULL; + d->d_data.d_off = 0; + d->d_data.d_align = sh_align; + d->d_data.d_size = msz * count; + d->d_data.d_type = elftype; + d->d_data.d_version = e->e_version; + + if (sh_type == SHT_NOBITS || sh_size == 0) { + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + return (&d->d_data); + } + + if ((d->d_data.d_buf = malloc(msz*count)) == NULL) { + (void) _libelf_release_data(d); + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + d->d_flags |= LIBELF_F_DATA_MALLOCED; + + xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); + if (!(*xlate)(d->d_data.d_buf, d->d_data.d_size, + e->e_rawfile + sh_offset, count, + e->e_byteorder != LIBELF_PRIVATE(byteorder))) { + _libelf_release_data(d); + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + + return (&d->d_data); +} + +Elf_Data * +elf_newdata(Elf_Scn *s) +{ + Elf *e; + struct _Libelf_Data *d; + + if (s == NULL || (e = s->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + /* + * elf_newdata() has to append a data descriptor, so + * bring in existing section data if not already present. + */ + if (e->e_rawfile && s->s_size > 0 && STAILQ_EMPTY(&s->s_data)) + if (elf_getdata(s, NULL) == NULL) + return (NULL); + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + STAILQ_INSERT_TAIL(&s->s_data, d, d_next); + + d->d_data.d_align = 1; + d->d_data.d_buf = NULL; + d->d_data.d_off = (uint64_t) ~0; + d->d_data.d_size = 0; + d->d_data.d_type = ELF_T_BYTE; + d->d_data.d_version = LIBELF_PRIVATE(version); + + (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); + + return (&d->d_data); +} + +/* + * Retrieve a data descriptor for raw (untranslated) data for section + * `s'. + */ + +Elf_Data * +elf_rawdata(Elf_Scn *s, Elf_Data *ed) +{ + Elf *e; + int elf_class; + uint32_t sh_type; + struct _Libelf_Data *d; + uint64_t sh_align, sh_offset, sh_size; + + if (s == NULL || (e = s->s_elf) == NULL || e->e_rawfile == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(e->e_kind == ELF_K_ELF); + + d = (struct _Libelf_Data *) ed; + + if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) + return (&d->d_data); + + if (d != NULL) + return (&STAILQ_NEXT(d, d_next)->d_data); + + elf_class = e->e_class; + + assert(elf_class == ELFCLASS32 || elf_class == ELFCLASS64); + + if (elf_class == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_offset = s->s_shdr.s_shdr64.sh_offset; + sh_size = s->s_shdr.s_shdr64.sh_size; + sh_align = s->s_shdr.s_shdr64.sh_addralign; + } + + if (sh_type == SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (NULL); + } + + if ((d = _libelf_allocate_data(s)) == NULL) + return (NULL); + + d->d_data.d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : + e->e_rawfile + sh_offset; + d->d_data.d_off = 0; + d->d_data.d_align = sh_align; + d->d_data.d_size = sh_size; + d->d_data.d_type = ELF_T_BYTE; + d->d_data.d_version = e->e_version; + + STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); + + return (&d->d_data); +} diff --git a/contrib/elftoolchain/libelf/elf_end.3 b/contrib/elftoolchain/libelf/elf_end.3 new file mode 100644 index 0000000..8649faa --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_end.3 @@ -0,0 +1,76 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_end.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 29, 2006 +.Os +.Dt ELF_END 3 +.Sh NAME +.Nm elf_end +.Nd release an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_end "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_end +is used to release the resources associated with an ELF descriptor +pointed to by argument +.Ar elf . +This descriptor must have been allocated by a previous call to +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +For programming convenience, a NULL value is permitted for argument +.Ar elf . +.Pp +A call to +.Fn elf_end +decrements the activation count for descriptor +.Ar elf +by one. +The resources associated with the descriptor are only released +with its activation count goes to zero. +.Pp +Once function +.Fn elf_end +returns zero, the ELF descriptor +.Ar elf +will no longer be valid and should not be used further. +.Sh RETURN VALUES +Function +.Fn elf_end +returns the current value of the ELF descriptor +.Ar elf Ap s +activation count, or zero if argument +.Ar elf +was NULL. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_memory 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_end.c b/contrib/elftoolchain/libelf/elf_end.c new file mode 100644 index 0000000..097664c --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_end.c @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2006,2008-2009,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> +#include <stdlib.h> + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include <sys/mman.h> +#endif + +ELFTC_VCSID("$Id: elf_end.c 2240 2011-11-28 06:36:48Z jkoshy $"); + +int +elf_end(Elf *e) +{ + Elf *sv; + Elf_Scn *scn, *tscn; + + if (e == NULL || e->e_activations == 0) + return (0); + + if (--e->e_activations > 0) + return (e->e_activations); + + assert(e->e_activations == 0); + + while (e && e->e_activations == 0) { + switch (e->e_kind) { + case ELF_K_AR: + /* + * If we still have open child descriptors, we + * need to defer reclaiming resources till all + * the child descriptors for the archive are + * closed. + */ + if (e->e_u.e_ar.e_nchildren > 0) + return (0); + break; + case ELF_K_ELF: + /* + * Reclaim all section descriptors. + */ + STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, + tscn) + scn = _libelf_release_scn(scn); + break; + case ELF_K_NUM: + assert(0); + default: + break; + } + + if (e->e_rawfile) { + if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) + free(e->e_rawfile); +#if ELFTC_HAVE_MMAP + else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) + (void) munmap(e->e_rawfile, e->e_rawsize); +#endif + } + + sv = e; + if ((e = e->e_parent) != NULL) + e->e_u.e_ar.e_nchildren--; + sv = _libelf_release_elf(sv); + } + + return (0); +} diff --git a/contrib/elftoolchain/libelf/elf_errmsg.3 b/contrib/elftoolchain/libelf/elf_errmsg.3 new file mode 100644 index 0000000..822ba6a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errmsg.3 @@ -0,0 +1,107 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_errmsg.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 11, 2006 +.Os +.Dt ELF_ERRMSG 3 +.Sh NAME +.Nm elf_errmsg , +.Nm elf_errno +.Nd ELF library error message handling +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_errno "void" +.Ft "const char *" +.Fn elf_errmsg "int error" +.Sh DESCRIPTION +When an error occurs during an ELF library API call, the library +encodes the error using an error number and stores the error number +internally for retrieval by the application at a later point of time. +Error numbers may contain an OS supplied error code in addition to +an ELF API specific error code. +An error number value of zero indicates no error. +.Pp +Function +.Fn elf_errno +is used to retrieve the last error recorded by the ELF library. +Invoking this function has the side-effect of resetting the +ELF library's recorded error number to zero. +.Pp +The function +.Fn elf_errmsg +returns a null-terminated string with a human readable +description of the error specified in argument +.Ar error . +A zero value for argument +.Ar error +retrieves the most recent error encountered by the ELF +library. +An argument value of -1 behaves identically, except that +it guarantees a non-NULL return from +.Fn elf_errmsg . +.Sh RETURN VALUES +Function +.Fn elf_errno +returns a non-zero value encoding the last error encountered +by the ELF library, or zero if no error was encountered. +.Pp +Function +.Fn elf_errmsg +returns a pointer to library local storage for non-zero values +of argument +.Ar error . +With a zero argument, the function will return a NULL pointer if no +error had been encountered by the library, or will return a pointer to +library local storage containing an appropriate message otherwise. +.Sh EXAMPLES +Clearing the ELF library's recorded error number can be accomplished +by invoking +.Fn elf_errno +and discarding its return value. +.Bd -literal -offset indent +/* clear error */ +(void) elf_errno(); +.Ed +.Pp +Retrieving a human-readable description of the current error number +can be done with the following snippet: +.Bd -literal -offset indent +int err; +const char *errmsg; +\&... +err = elf_errno(); +if (err != 0) + errmsg = elf_errmsg(err); +.Ed +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 +.Sh BUGS +Function +.Fn elf_errmsg +is not localized. diff --git a/contrib/elftoolchain/libelf/elf_errmsg.c b/contrib/elftoolchain/libelf/elf_errmsg.c new file mode 100644 index 0000000..adcaa74 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errmsg.c @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> +#include <stdio.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_errmsg.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * Retrieve a human readable translation for an error message. + */ + +const char *_libelf_errors[] = { +#define DEFINE_ERROR(N,S) [ELF_E_##N] = S + DEFINE_ERROR(NONE, "No Error"), + DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), + DEFINE_ERROR(ARGUMENT, "Invalid argument"), + DEFINE_ERROR(CLASS, "ELF class mismatch"), + DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), + DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), + DEFINE_ERROR(IO, "I/O error"), + DEFINE_ERROR(LAYOUT, "Layout constraint violation"), + DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), + DEFINE_ERROR(RANGE, "Value out of range of target"), + DEFINE_ERROR(RESOURCE, "Resource exhaustion"), + DEFINE_ERROR(SECTION, "Invalid section descriptor"), + DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), + DEFINE_ERROR(UNIMPL, "Unimplemented feature"), + DEFINE_ERROR(VERSION, "Unknown ELF API version"), + DEFINE_ERROR(NUM, "Unknown error") +#undef DEFINE_ERROR +}; + +const char * +elf_errmsg(int error) +{ + int oserr; + + if (error == ELF_E_NONE && + (error = LIBELF_PRIVATE(error)) == 0) + return NULL; + else if (error == -1) + error = LIBELF_PRIVATE(error); + + oserr = error >> LIBELF_OS_ERROR_SHIFT; + error &= LIBELF_ELF_ERROR_MASK; + + if (error < ELF_E_NONE || error >= ELF_E_NUM) + return _libelf_errors[ELF_E_NUM]; + if (oserr) { + (void) snprintf(LIBELF_PRIVATE(msg), + sizeof(LIBELF_PRIVATE(msg)), "%s: %s", + _libelf_errors[error], strerror(oserr)); + return (const char *)&LIBELF_PRIVATE(msg); + } + return _libelf_errors[error]; +} diff --git a/contrib/elftoolchain/libelf/elf_errno.c b/contrib/elftoolchain/libelf/elf_errno.c new file mode 100644 index 0000000..c78d4c7 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_errno.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2006,2008,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_errno.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +int +elf_errno(void) +{ + int old; + + old = LIBELF_PRIVATE(error); + LIBELF_PRIVATE(error) = 0; + return (old & LIBELF_ELF_ERROR_MASK); +} diff --git a/contrib/elftoolchain/libelf/elf_fill.3 b/contrib/elftoolchain/libelf/elf_fill.3 new file mode 100644 index 0000000..ab42a42 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_fill.3 @@ -0,0 +1,52 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_fill.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 11, 2006 +.Os +.Dt ELF_FILL 3 +.Sh NAME +.Nm elf_fill +.Nd set fill byte for inter-section padding +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft void +.Fn elf_fill "int fill" +.Sh DESCRIPTION +Function +.Fn elf_fill +allows an application to specify a fill value for the padding inserted +between two sections of an ELF file to meet section alignment +constraints. +By default the ELF library uses zero bytes for padding. +.Pp +The ELF library will only pad bytes if the +.Dv ELF_F_LAYOUT +flag is not set for the ELF file. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagelf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_fill.c b/contrib/elftoolchain/libelf/elf_fill.c new file mode 100644 index 0000000..4c9facc --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_fill.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_fill.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +void +elf_fill(int fill) +{ + LIBELF_PRIVATE(fillchar) = fill; +} diff --git a/contrib/elftoolchain/libelf/elf_flag.c b/contrib/elftoolchain/libelf/elf_flag.c new file mode 100644 index 0000000..ab9d24a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_flag.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2006,2008-2009,2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +unsigned int +elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + + if (a == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (c == ELF_C_SET) + r = a->ar_flags |= flags; + else + r = a->ar_flags &= ~flags; + + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) +{ + unsigned int r; + struct _Libelf_Data *ld; + + if (d == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ld = (struct _Libelf_Data *) d; + + if (c == ELF_C_SET) + r = ld->d_flags |= flags; + else + r = ld->d_flags &= ~flags; + + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) +{ + int ec; + void *ehdr; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; + else + ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; + + if (ehdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); +} + +unsigned int +elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) +{ + int r; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || + (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV | + ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if (c == ELF_C_SET) + r = e->e_flags |= flags; + else + r = e->e_flags &= ~flags; + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) +{ + int ec; + void *phdr; + + if (e == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) + phdr = e->e_u.e_elf.e_phdr.e_phdr32; + else + phdr = e->e_u.e_elf.e_phdr.e_phdr64; + + if (phdr == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (0); + } + + return (elf_flagelf(e, c, flags)); +} + +unsigned int +elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) +{ + int r; + + if (s == NULL) + return (0); + + if ((c != ELF_C_SET && c != ELF_C_CLR) || + (flags & ~ELF_F_DIRTY) != 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (c == ELF_C_SET) + r = s->s_flags |= flags; + else + r = s->s_flags &= ~flags; + return (r & LIBELF_F_API_MASK); +} + +unsigned int +elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) +{ + return (elf_flagscn(s, c, flags)); +} diff --git a/contrib/elftoolchain/libelf/elf_flagdata.3 b/contrib/elftoolchain/libelf/elf_flagdata.3 new file mode 100644 index 0000000..fc27109 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_flagdata.3 @@ -0,0 +1,226 @@ +.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_flagdata.3 2884 2013-01-11 02:03:46Z jkoshy $ +.\" +.Dd December 3, 2011 +.Os +.Dt ELF_FLAGDATA 3 +.Sh NAME +.Nm elf_flagarhdr , +.Nm elf_flagdata , +.Nm elf_flagehdr , +.Nm elf_flagelf , +.Nm elf_flagphdr , +.Nm elf_flagscn , +.Nm elf_flagshdr +.Nd manipulate flags associated with ELF(3) data structures +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "unsigned int" +.Fn elf_flagarhdr "Elf_Arhdr *arhdr" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagdata "Elf_Data *data" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagehdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagelf "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagphdr "Elf *elf" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagscn "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" +.Ft "unsigned int" +.Fn elf_flagshdr "Elf_Scn *scn" "Elf_Cmd cmd" "unsigned int flags" +.Sh DESCRIPTION +These functions are used to query, set or reset flags on data +structures associated with an ELF file. +.Pp +Arguments +.Ar arhdr , +.Ar data , +.Ar elf +and +.Ar scn +denote the data structures whose flags need to be changed. +These values should have been returned by prior calls to +functions in the ELF(3) API set: +.Bl -bullet -compact +.It +Argument +.Ar arhdr +should have been returned by a prior call to +.Xr elf_getarhdr 3 . +.It +Argument +.Ar data +should have been returned by a prior call to one of +.Xr elf_newdata 3 , +.Xr elf_getdata 3 +or +.Xr elf_rawdata 3 . +.It +Argument +.Ar elf +should have been allocated by a prior call to one of +.Xr elf_begin 3 +or +.Xr elf_memory 3 . +.It +Argument +.Ar scn +should have been returned by a prior call to one of +.Xr elf_getscn 3 , +.Xr elf_newscn 3 +or +.Xr elf_nextscn 3 . +.El +These values are allowed to be NULL to simplify error handling in +application code. +.Pp +Argument +.Ar cmd +may have the following values: +.Bl -tag -width ELF_C_SET +.It Dv ELF_C_CLR +The argument +.Ar flags +specifies the flags to be cleared. +.It Dv ELF_C_SET +The argument +.Ar flags +specifies the flags to be set. +.El +.Pp +The argument +.Ar flags +is allowed to have the following flags set: +.Bl -tag -width ELF_F_ARCHIVE_SYSV +.It Dv ELF_F_ARCHIVE +This flag is only valid with the +.Fn elf_flagelf +API. +It informs the library that the application desires to create an +.Xr ar 1 +archive. +Argument +.Ar elf +should have been opened for writing using the +.Dv ELF_C_WRITE +command to function +.Fn elf_begin . +.It Dv ELF_F_ARCHIVE_SYSV +This flag is used in conjunction with the +.Dv ELF_F_ARCHIVE +flag to indicate that library should create archives that conform +to System V layout rules. +The default is to create BSD style archives. +.It Dv ELF_F_DIRTY +Mark the associated data structure as needing to be written back +to the underlying file. +A subsequent call to +.Xr elf_update 3 +will resynchronize the library's internal data structures. +.It Dv ELF_F_LAYOUT +This flag is only valid with the +.Fn elf_flagelf +API. +It informs the library that the application will take +responsibility for the layout of the file and that the library is +not to insert any padding in between sections. +.El +.Pp +Marking a given data structure as +.Dq dirty +affects all of its contained elements. +Thus marking an ELF descriptor +.Ar elf +with +.Fn elf_flagelf "elf" "ELF_C_SET" "ELF_F_DIRTY" +means that the entire contents of the descriptor are +.Dq dirty . +.Pp +Using a value of zero for argument +.Ar flags +will return the current set of flags for the data structure being +queried. +.Sh RETURN VALUES +These functions return the updated flags if successful, or zero if +an error is detected. +.Sh COMPATIBILITY +The +.Fn elf_flagarhdr +function and the +.Dv ELF_F_ARCHIVE +and +.Dv ELF_F_ARCHIVE_SYSV +flags are an extension to the ELF(3) API. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +An unsupported value was used for the +.Ar cmd +argument. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar flags +had unsupported flags set. +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_MODE +The +.Dv ELF_F_ARCHIVE +flag was used with an ELF descriptor that had not been opened for writing. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_flagehdr +was called without an executable header being allocated. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_flagphdr +was called without a program header being allocated. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_newehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf32_newshdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf64_newshdr 3 , +.Xr elf_newdata 3 , +.Xr elf_update 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr gelf_newphdr 3 , +.Xr gelf_newshdr 3 , +.Xr gelf_update_dyn 3 , +.Xr gelf_update_move 3 , +.Xr gelf_update_rel 3 , +.Xr gelf_update_rela 3 , +.Xr gelf_update_sym 3 , +.Xr gelf_update_syminfo 3 diff --git a/contrib/elftoolchain/libelf/elf_getarhdr.3 b/contrib/elftoolchain/libelf/elf_getarhdr.3 new file mode 100644 index 0000000..1aab71c --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarhdr.3 @@ -0,0 +1,97 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getarhdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 15, 2006 +.Os +.Dt ELF_GETARHDR 3 +.Sh NAME +.Nm elf_getarhdr +.Nd retrieve ar(1) header for an archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Arhdr *" +.Fn elf_getarhdr "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_getarhdr +function returns a pointer to an archive member header for +a descriptor +.Ar elf . +This descriptor must have been returned by a prior call to +.Xr elf_begin 3 , +and must be a descriptor for a member inside an +.Xr ar 1 +archive. +.Pp +Structure +.Vt Elf_Arhdr +includes the following members: +.Bl -tag -width indent +.It Vt "char *" Va ar_name +A pointer to a null terminated string containing the translated +name of the archive member. +.It Vt "char *" Va ar_rawname +A pointer to a null terminated string containing the untranslated +name for the archive member, including all +.Xr ar 1 +formatting characters and trailing white space. +.It Vt time_t Va ar_date +The timestamp associated with the member. +.It Vt uid_t Va ar_uid +The uid of the creator of the member. +.It Vt gid_t Va ar_gid +The gid of the creator of the member. +.It Vt mode_t Va ar_mode +The file mode of the member. +.It Vt size_t Va ar_size +The size of the member in bytes. +.El +.Sh RETURN VALUES +This function returns a valid pointer to an +.Vt Elf_Arhdr +structure if successful, or NULL if an error is encountered. +.Sh ERRORS +Function +.Fn elf_getarhdr +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for a member of an +.Xr ar 1 +archive. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getarsym 3 , +.Xr elf_memory 3 diff --git a/contrib/elftoolchain/libelf/elf_getarhdr.c b/contrib/elftoolchain/libelf/elf_getarhdr.c new file mode 100644 index 0000000..07f6888 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarhdr.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getarhdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +Elf_Arhdr * +elf_getarhdr(Elf *e) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (e->e_flags & LIBELF_F_AR_HEADER) + return (e->e_hdr.e_arhdr); + + return (_libelf_ar_gethdr(e)); +} diff --git a/contrib/elftoolchain/libelf/elf_getarsym.3 b/contrib/elftoolchain/libelf/elf_getarsym.3 new file mode 100644 index 0000000..cda0511 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarsym.3 @@ -0,0 +1,130 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getarsym.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 15, 2006 +.Os +.Dt ELF_GETARSYM 3 +.Sh NAME +.Nm elf_getarsym +.Nd retrieve the symbol table of an archive +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Arsym *" +.Fn elf_getarsym "Elf *elf" "size_t *ptr" +.Sh DESCRIPTION +The function +.Fn elf_getarsym +retrieves the symbol table for an +.Xr ar 1 +archive, if one is available. +.Pp +Argument +.Ar elf +should be a descriptor for an +.Xr ar 1 +archive opened using +.Fn elf_begin +or +.Fn elf_memory . +.Pp +If the archive +.Ar elf +contains a symbol table with n entries, this function returns a +pointer to an array of n+1 +.Vt Elf_Arsym +structures. +An +.Vt Elf_Arsym +structure has the following elements: +.Bl -tag -width indent -compact +.It Vt "char *" Va as_name +This structure member is a pointer to a null-terminated symbol name. +.It Vt "off_t" Va as_off +This structure member contains the byte offset from the beginning of the archive to +the header for the archive member. +This value is suitable for use with +.Xr elf_rand 3 . +.It Vt "unsigned long" Va as_hash +This structure member contains a portable hash value for the symbol +name, as computed by +.Xr elf_hash 3 . +.El +.Pp +The last entry of the returned array will have a NULL value for member +.Va as_name , +a zero value for member +.Va as_off +and an illegal value of ~0UL for +.Va as_hash . +.Pp +If argument +.Ar ptr +is non-null, the +.Fn elf_getarsym +function will store the number of table entries returned (including the +sentinel entry at the end) into the location it points to. +.Sh RETURN VALUES +Function +.Fn elf_getarsym +returns a pointer to an array of +.Vt Elf_Arsym +structures if successful, or a NULL +pointer if an error was encountered. +.Pp +If argument +.Ar ptr +is non-null and there was no error, the library will store the +number of archive symbol entries returned into the location it +points to. +If argument +.Ar ptr +is non-null and an error was encountered, the library will +set the location pointed to by it to zero. +.Sh ERRORS +Function +.Fn elf_getarsym +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an +.Xr ar 1 +archive. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getarhdr 3 , +.Xr elf_hash 3 , +.Xr elf_memory 3 , +.Xr elf_next 3 , +.Xr elf_rand 3 diff --git a/contrib/elftoolchain/libelf/elf_getarsym.c b/contrib/elftoolchain/libelf/elf_getarsym.c new file mode 100644 index 0000000..eeb8513 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getarsym.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getarsym.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +Elf_Arsym * +elf_getarsym(Elf *ar, size_t *ptr) +{ + size_t n; + Elf_Arsym *symtab; + + n = 0; + symtab = NULL; + + if (ar == NULL || ar->e_kind != ELF_K_AR) + LIBELF_SET_ERROR(ARGUMENT, 0); + else if ((symtab = ar->e_u.e_ar.e_symtab) != NULL) + n = ar->e_u.e_ar.e_symtabsz; + else if (ar->e_u.e_ar.e_rawsymtab) + symtab = (ar->e_flags & LIBELF_F_AR_VARIANT_SVR4) ? + _libelf_ar_process_svr4_symtab(ar, &n) : + _libelf_ar_process_bsd_symtab(ar, &n); + else + LIBELF_SET_ERROR(ARCHIVE, 0); + + if (ptr) + *ptr = n; + return (symtab); +} diff --git a/contrib/elftoolchain/libelf/elf_getbase.3 b/contrib/elftoolchain/libelf/elf_getbase.3 new file mode 100644 index 0000000..fa17353 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getbase.3 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2006,2008,2010 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getbase.3 978 2010-06-06 12:40:19Z jkoshy $ +.\" +.Dd June 6, 2010 +.Os +.Dt ELF_GETBASE 3 +.Sh NAME +.Nm elf_getbase +.Nd get the base offset for an object file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_getbase "Elf *elf" +.Sh DESCRIPTION +Function +.Fn elf_getbase +returns the file offset to the first byte of the object referenced by ELF +descriptor +.Ar elf . +.Pp +For descriptors referencing members of archives, the returned offset is +the file offset of the member in its containing archive. +For descriptors to regular objects, the returned offset is (vacuously) +zero. +.Sh RETURN VALUES +Function +.Fn elf_getbase +returns a valid file offset if successful, or +.Pq Vt off_t +.Li -1 +in case of an error. +.Sh ERRORS +Function +.Fn elf_getbase +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getarhdr 3 , +.Xr elf_getident 3 , +.Xr elf_rawfile 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getbase.c b/contrib/elftoolchain/libelf/elf_getbase.c new file mode 100644 index 0000000..417808d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getbase.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getbase.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +off_t +elf_getbase(Elf *e) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return ((off_t) -1); + } + + if (e->e_parent == NULL) + return ((off_t) 0); + + return ((off_t) ((uintptr_t) e->e_rawfile - + (uintptr_t) e->e_parent->e_rawfile)); +} diff --git a/contrib/elftoolchain/libelf/elf_getdata.3 b/contrib/elftoolchain/libelf/elf_getdata.3 new file mode 100644 index 0000000..8816a5a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getdata.3 @@ -0,0 +1,229 @@ +.\" Copyright (c) 2006,2008,2010-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getdata.3 1766 2011-08-22 06:01:03Z jkoshy $ +.\" +.Dd January 26, 2011 +.Os +.Dt ELF_GETDATA 3 +.Sh NAME +.Nm elf_getdata , +.Nm elf_newdata , +.Nm elf_rawdata +.Nd iterate through or allocate section data +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Data *" +.Fn elf_getdata "Elf_Scn *scn" "Elf_Data *data" +.Ft "Elf_Data *" +.Fn elf_newdata "Elf_Scn *scn" +.Ft "Elf_Data *" +.Fn elf_rawdata "Elf_Scn *scn" "Elf_Data *data" +.Sh DESCRIPTION +These functions are used to access and manipulate data descriptors +associated with section descriptors. +Data descriptors used by the ELF library are described in +.Xr elf 3 . +.Pp +Function +.Fn elf_getdata +will return the next data descriptor associated with section descriptor +.Ar scn . +The returned data descriptor will be setup to contain translated data. +Argument +.Ar data +may be NULL, in which case the function returns the first data descriptor +associated with section +.Ar scn . +If argument +.Ar data +is not NULL, it must be a pointer to a data descriptor associated with +section descriptor +.Ar scn , +and function +.Fn elf_getdata +will return a pointer to the next data descriptor for the section, +or NULL when the end of the section's descriptor list is reached. +.Pp +Function +.Fn elf_newdata +will allocate a new data descriptor and append it to the list of data +descriptors associated with section descriptor +.Ar scn . +The new data descriptor will be initialized as follows: +.Bl -tag -width "d_version" -compact -offset indent +.It Va d_align +Set to 1. +.It Va d_buf +Initialized to NULL. +.It Va d_off +Set to (off_t) -1. +This field is under application control if the +.Dv ELF_F_LAYOUT +flag was set on the ELF descriptor. +.It Va d_size +Set to zero. +.It Va d_type +Initialized to +.Dv ELF_T_BYTE . +.It Va d_version +Set to the current working version of the library, as set by +.Xr elf_version 3 . +.El +The application must set these values as appropriate before +calling +.Xr elf_update 3 . +Section +.Ar scn +must be associated with an ELF file opened for writing. +If the application has not requested full control of layout by +setting the +.Dv ELF_F_LAYOUT +flag on descriptor +.Ar elf , +then the data referenced by the returned descriptor will be positioned +after the existing content of the section, honoring the file alignment +specified in member +.Va d_align . +On successful completion of a call to +.Fn elf_newdata , +the ELF library will mark the section +.Ar scn +as +.Dq dirty . +.Pp +Function +.Fn elf_rawdata +is used to step through the data descriptors associated with +section +.Ar scn . +In contrast to function +.Fn elf_getdata , +this function returns untranslated data. +If argument +.Ar data +is NULL, the first data descriptor associated with section +.Ar scn +is returned. +If argument +.Ar data +is not NULL, is must be a data descriptor associated with +section +.Ar scn , +and function +.Fn elf_rawdata +will return the next data descriptor in the list, or NULL +if no further descriptors are present. +Function +.Fn elf_rawdata +always returns +.Vt Elf_Data +structures of type +.Dv ELF_T_BYTE . +.Ss Special handling of zero-sized and SHT_NOBITS sections +For sections of type +.Dv SHT_NOBITS, +and for zero-sized sections, +the functions +.Fn elf_getdata +and +.Fn elf_rawdata +return a pointer to a valid +.Vt Elf_Data +structure that has its +.Va d_buf +member set to NULL and its +.Va d_size +member set to the size of the section. +.Pp +If an application wishes to create a section of type +.Dv SHT_NOBITS , +it should add a data buffer to the section using function +.Fn elf_newdata . +It should then set the +.Va d_buf +and +.Va d_size +members of the returned +.Vt Elf_Data +structure to NULL and the desired size of the section respectively. +.Sh RETURN VALUES +These functions return a valid pointer to a data descriptor if successful, or +NULL if an error occurs. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Either of the arguments +.Ar scn +or +.Ar data +was NULL. +.It Bq Er ELF_E_ARGUMENT +The data descriptor referenced by argument +.Ar data +is not associated with section descriptor +.Ar scn . +.It Bq Er ELF_E_ARGUMENT +The section denoted by argument +.Ar scn +had no data associated with it. +.It Bq Er ELF_E_DATA +Retrieval of data from the underlying object failed. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +Section +.Ar scn +had type +.Dv SHT_NULL . +.It Bq Er ELF_E_SECTION +The type of the section +.Ar scn +was not recognized by the library. +.It Bq Er ELF_E_SECTION +The size of the section +.Ar scn +is not a multiple of the file size for its section type. +.It Bq Er ELF_E_SECTION +The file offset for section +.Ar scn +is incorrect. +.It Bq Er ELF_E_UNIMPL +The section type associated with section +.Ar scn +is currently unsupported by the library. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagdata 3 , +.Xr elf_flagscn 3 , +.Xr elf_getscn 3 , +.Xr elf_getshdr 3 , +.Xr elf_newscn 3 , +.Xr elf_rawfile 3 , +.Xr elf_update 3 , +.Xr elf_version 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getident.3 b/contrib/elftoolchain/libelf/elf_getident.3 new file mode 100644 index 0000000..01d7f97 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getident.3 @@ -0,0 +1,83 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getident.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd July 3, 2006 +.Os +.Dt ELF_GETIDENT 3 +.Sh NAME +.Nm elf_getident +.Nd return the initial bytes of a file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft char * +.Fn elf_getident "Elf *elf" "size_t *sz" +.Sh DESCRIPTION +Function +.Fn elf_getident +returns a pointer to the initial bytes of the file for descriptor +.Ar elf . +.Pp +If argument +.Ar sz +is non-null, the size of the identification area returned is written +to the location pointed to by +.Ar sz . +This location is set to zero on errors. +.Sh RETURN VALUES +Function +.Fn elf_getident +will return a non-NULL pointer to the initial bytes of the file if +successful, or NULL if an error condition is detected. +.Sh ERRORS +Function +.Fn elf_getident +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_SEQUENCE +ELF descriptor +.Ar elf +was opened for writing and function +.Fn elf_getident +was called before a call to +.Xr elf_update 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getarhdr 3 , +.Xr elf_getbase 3 , +.Xr elf_getflags 3 , +.Xr elf_kind 3 , +.Xr elf_rawfile 3 , +.Xr elf_update 3 , +.Xr gelf 3 , +.Xr gelf_getclass 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getident.c b/contrib/elftoolchain/libelf/elf_getident.c new file mode 100644 index 0000000..aeea996 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getident.c @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <assert.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_getident.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +char * +elf_getident(Elf *e, size_t *sz) +{ + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + goto error; + } + + if (e->e_cmd == ELF_C_WRITE && e->e_rawfile == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + goto error; + } + + assert(e->e_kind != ELF_K_AR || e->e_cmd == ELF_C_READ); + + if (sz) { + if (e->e_kind == ELF_K_AR) + *sz = SARMAG; + else if (e->e_kind == ELF_K_ELF) + *sz = EI_NIDENT; + else + *sz = e->e_rawsize; + } + + return ((char *) e->e_rawfile); + + error: + if (sz) + *sz = 0; + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/elf_getphdrnum.3 b/contrib/elftoolchain/libelf/elf_getphdrnum.3 new file mode 100644 index 0000000..f0fae5e --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getphdrnum.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getphdrnum.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 5, 2009 +.Os +.Dt ELF_GETPHDRNUM 3 +.Sh NAME +.Nm elf_getphdrnum +.Nd return the number of program headers in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getphdrnum "Elf *elf" "size_t *phnum" +.Sh DESCRIPTION +Function +.Fn elf_getphdrnum +retrieves the number of ELF program headers associated with descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar phnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects and ELF objects that use extended numbering. +.Pp +.Sh RETURN VALUES +Function +.Fn elf_getphdrnum +returns a zero value if successful, or -1 in case of an error. +.Sh ERRORS +Function +.Fn elf_getphnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable Header. +.It Bq Er ELF_E_HEADER +The ELF Executable Header associated with argument +.Ar elf +was corrupt. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +was corrupt. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getshdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getphnum.3 b/contrib/elftoolchain/libelf/elf_getphnum.3 new file mode 100644 index 0000000..95c7540 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getphnum.3 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getphnum.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 5, 2009 +.Os +.Dt ELF_GETPHNUM 3 +.Sh NAME +.Nm elf_getphnum +.Nd return the number of program headers in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getphnum "Elf *elf" "size_t *phnum" +.Sh DESCRIPTION +This function is deprecated. +Please use function +.Xr elf_getphdrnum 3 +instead. +.Pp +Function +.Fn elf_getphnum +retrieves the number of ELF program headers associated with descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar phnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects and ELF objects that use extended numbering. +.Pp +.Sh RETURN VALUES +Function +.Fn elf_getphnum +returns a non-zero value if successful, or zero in case of an +error. +.Sh ERRORS +Function +.Fn elf_getphnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable Header. +.It Bq Er ELF_E_HEADER +The ELF Executable Header associated with argument +.Ar elf +was corrupt. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +was corrupt. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getscn.3 b/contrib/elftoolchain/libelf/elf_getscn.3 new file mode 100644 index 0000000..0afe443 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getscn.3 @@ -0,0 +1,151 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getscn.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd October 22, 2007 +.Os +.Dt ELF_GETSCN 3 +.Sh NAME +.Nm elf_getscn , +.Nm elf_ndxscn , +.Nm elf_newscn , +.Nm elf_nextscn +.Nd get/allocate section information for an ELF object +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Scn *" +.Fn elf_getscn "Elf *elf" "size_t index" +.Ft size_t +.Fn elf_ndxscn "Elf_Scn *scn" +.Ft "Elf_Scn *" +.Fn elf_newscn "Elf *elf" +.Ft "Elf_Scn *" +.Fn elf_nextscn "Elf *elf" "Elf_Scn *scn" +.Sh DESCRIPTION +These functions are used to iterate through the sections associated +with an ELF descriptor. +.Pp +Function +.Fn elf_getscn +will return a section descriptor for the section at index +.Ar index +in the object denoted by ELF descriptor +.Ar elf . +An error will be signalled if the specified section does not +exist. +.Pp +Function +.Fn elf_ndxscn +returns the section table index associated with section descriptor +.Ar scn . +.Pp +Function +.Fn elf_newscn +creates a new section and appends it to the list of sections +associated with descriptor +.Ar elf . +The library will automatically increment the +.Va e_shnum +field of the ELF header associated with descriptor +.Ar elf , +and will set the +.Dv ELF_F_DIRTY +flag on the returned section descriptor. +For ELF descriptors opened for writing, the ELF library will +automatically create an empty section at index zero +.Dv ( SHN_UNDEF ) +on the first call to +.Fn elf_newscn . +.Pp +Function +.Fn elf_nextscn +takes a section descriptor +.Ar scn +and returns a pointer to the section descriptor at the next higher +index. +Argument +.Ar scn +is allowed to be NULL, in which case this function will return a +pointer to the section descriptor at index 1. +If no further sections are present, function +.Fn elf_nextscn +will return a NULL pointer. +.Sh RETURN VALUES +Functions +.Fn elf_getscn , +.Fn elf_newscn +and +.Fn elf_nextscn +return a valid pointer to a section descriptor if successful, or +NULL if an error occurs. +.Pp +Function +.Fn elf_ndxscn +returns a valid section table index if successful, or +.Dv SHN_UNDEF +if an error occurs. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar elf +or +.Ar scn +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar index +exceeded the current number of sections in the ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Section descriptor +.Ar scn +was not associated with ELF descriptor +.Ar elf . +.It Bq Er ELF_E_CLASS +Descriptor +.Ar elf +was of an unknown ELF class. +.It Bq Er ELF_E_SECTION +Argument +.Ar elf +specified extended section numbering in the ELF header with the section header at +index +.Dv SHN_UNDEF +not being of type +.Dv SHT_NULL . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagdata 3 , +.Xr elf_flagscn 3 , +.Xr elf_getdata 3 , +.Xr elf_getshdr 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_getshdrnum.3 b/contrib/elftoolchain/libelf/elf_getshdrnum.3 new file mode 100644 index 0000000..e2bf354 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshdrnum.3 @@ -0,0 +1,78 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getshdrnum.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 4, 2009 +.Os +.Dt ELF_GETSHDRNUM 3 +.Sh NAME +.Nm elf_getshdrnum +.Nd return the number of sections in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshdrnum "Elf *elf" "size_t *shnum" +.Sh DESCRIPTION +Function +.Fn elf_getshdrnum +retrieves the number of ELF sections associated with descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar shnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects, and ELF objects that use extended section numbering. +.Pp +.Sh RETURN VALUES +Function +.Fn elf_getshdrnum +returns zero value if successful, or -1 in case of an error. +.Sh ERRORS +Function +.Fn elf_getshdrnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable header. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 b/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 new file mode 100644 index 0000000..b02e715 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 @@ -0,0 +1,79 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getshdrstrndx.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 5, 2009 +.Os +.Dt ELF_GETSHDRSTRNDX 3 +.Sh NAME +.Nm elf_getshdrstrndx +.Nd retrieve the index of the section name string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshdrstrndx "Elf *elf" "size_t *ndxptr" +.Sh DESCRIPTION +Function +.Fn elf_getshdrstrndx +retrieves the section index of the string table containing section +names from descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar ndxptr . +.Pp +This function allow applications to process both normal ELF +objects and ELF objects that use extended section numbering uniformly. +.Pp +.Sh RETURN VALUES +These functions return zero if successful, or -1 in case of an error. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable header. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +contained a value in the reserved range of section indices. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshnum.3 b/contrib/elftoolchain/libelf/elf_getshnum.3 new file mode 100644 index 0000000..615aa71 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshnum.3 @@ -0,0 +1,84 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getshnum.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 5, 2009 +.Os +.Dt ELF_GETSHNUM 3 +.Sh NAME +.Nm elf_getshnum +.Nd return the number of sections in an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshnum "Elf *elf" "size_t *shnum" +.Sh DESCRIPTION +This function is deprecated. +Please use +.Xr elf_getshdrnum 3 +instead. +.Pp +Function +.Fn elf_getshnum +retrieves the number of ELF sections associated with descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar shnum . +.Pp +This routine allows applications to uniformly process both normal ELF +objects, and ELF objects that use extended section numbering. +.Pp +.Sh RETURN VALUES +Function +.Fn elf_getshnum +returns a non-zero value if successful, or zero in case of an +error. +.Sh ERRORS +Function +.Fn elf_getshnum +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable header. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrstrndx 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_getshstrndx.3 b/contrib/elftoolchain/libelf/elf_getshstrndx.3 new file mode 100644 index 0000000..71c6f95 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_getshstrndx.3 @@ -0,0 +1,94 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_getshstrndx.3 467 2009-08-05 18:18:49Z jkoshy $ +.\" +.Dd August 5, 2009 +.Os +.Dt ELF_GETSHSTRNDX 3 +.Sh NAME +.Nm elf_getshstrndx , +.Nm elf_setshstrndx +.Nd retrieve/update the index of the section name string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft int +.Fn elf_getshstrndx "Elf *elf" "size_t *ndxptr" +.Ft int +.Fn elf_setshstrndx "Elf *elf" "size_t ndx" +.Sh DESCRIPTION +Function +.Fn elf_getshstrndx +retrieves the section index of the string table containing section +names from descriptor +.Ar elf +and stores it into the location pointed to by argument +.Ar ndxptr . +Function +.Fn elf_getshstrndx +is deprecated. +Please use +.Xr elf_getshdrstrndx 3 +instead. +.Pp +Function +.Fn elf_setshstrndx +sets the index of the section name string table to argument +.Ar ndx . +.Pp +These routines allow applications to process both normal ELF +objects and ELF objects that use extended section numbering uniformly. +.Pp +.Sh RETURN VALUES +These functions return a non-zero value if successful, or zero in case +of an error. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was passed in for argument +.Ar elf . +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not for an ELF file. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +lacks an ELF Executable header. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +contained a value in the reserved range of section indices. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_getident 3 , +.Xr elf_getphdrnum 3 , +.Xr elf_getshdrnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 diff --git a/contrib/elftoolchain/libelf/elf_hash.3 b/contrib/elftoolchain/libelf/elf_hash.3 new file mode 100644 index 0000000..f099558 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_hash.3 @@ -0,0 +1,57 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_hash.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 15, 2006 +.Os +.Dt ELF_HASH 3 +.Sh NAME +.Nm elf_hash +.Nd compute a hash value for a string +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "unsigned long" +.Fn elf_hash "const char *name" +.Sh DESCRIPTION +Function +.Fn elf_hash +computes a portable hash value for the null terminated string +pointed to by argument +.Ar name . +.Pp +The hash value returned is will be identical across +machines of different architectures. +This allows hash tables to be built on one machine and +correctly used on another of a different architecture. +The hash value returned is also guaranteed +.Em not +to be the bit pattern of all ones (~0UL). +.Sh IMPLEMENTATION NOTES +The library internally uses unsigned 32 bit arithmetic to compute +the hash value. +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_hash.c b/contrib/elftoolchain/libelf/elf_hash.c new file mode 100644 index 0000000..3735237 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_hash.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_hash.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * This elf_hash function is defined by the System V ABI. + */ + +unsigned long +elf_hash(const char *name) +{ + unsigned long h, t; + const unsigned char *s; + + s = (const unsigned char *) name; + h = t = 0; + + for (; *s != '\0'; h = h & ~t) { + h = (h << 4) + *s++; + t = h & 0xF0000000UL; + if (t) + h ^= t >> 24; + } + + return (h); +} diff --git a/contrib/elftoolchain/libelf/elf_kind.3 b/contrib/elftoolchain/libelf/elf_kind.3 new file mode 100644 index 0000000..a5bbf9d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_kind.3 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_kind.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 1, 2006 +.Os +.Dt ELF_KIND 3 +.Sh NAME +.Nm elf_kind +.Nd determine ELF file type +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft Elf_Kind +.Fn elf_kind "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_kind +function identifies the kind of file associated with its argument +.Ar elf . +The argument +.Ar elf +is allowed to be NULL. +.Sh RETURN VALUES +The +.Fn elf_kind +function returns one of the following values: +.Bl -tag -width indent +.It Dv ELF_K_AR +The file associated with argument +.Ar elf +is an archive. +.It Dv ELF_K_ELF +The file associated with argument +.Ar elf +is an ELF file. +.It Dv ELF_K_NONE +The argument +.Ar elf +was NULL, or the ELF library could not determine the type of the file +associated with argument +.Ar elf , +or an error occurred when processing. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_getident 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_kind.c b/contrib/elftoolchain/libelf/elf_kind.c new file mode 100644 index 0000000..ba83adc --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_kind.c @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_kind.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +Elf_Kind +elf_kind(Elf *e) +{ + if (e == NULL) + return (ELF_K_NONE); + if (e->e_kind == ELF_K_AR || + e->e_kind == ELF_K_ELF) + return (e->e_kind); + return (ELF_K_NONE); +} diff --git a/contrib/elftoolchain/libelf/elf_memory.3 b/contrib/elftoolchain/libelf/elf_memory.3 new file mode 100644 index 0000000..bcb888f --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_memory.3 @@ -0,0 +1,122 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_memory.3 2314 2011-12-11 06:19:51Z jkoshy $ +.\" +.Dd June 28, 2006 +.Os +.Dt ELF_MEMORY 3 +.Sh NAME +.Nm elf_memory +.Nd process an ELF or ar(1) archive mapped into memory +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_memory "char *image" "size_t size" +.Sh DESCRIPTION +Function +.Fn elf_memory +is used to process an ELF file or +.Xr ar 1 +archive whose image is present in memory. +.Pp +Argument +.Ar image +points to the start of the memory image of the file or archive. +Argument +.Ar size +contains the size in bytes of the memory image. +.Pp +The ELF descriptor is created for reading (i.e., analogous to the +use of +.Xr elf_begin 3 +with a command argument value of +.Dv ELF_C_READ Ns ). +.Sh RETURN VALUES +Function +.Fn elf_memory +returns a pointer to a new ELF descriptor if successful, or NULL if an +error occurred. +.Pp +The return value may be queried for the file type using +.Xr elf_kind 3 . +.Sh EXAMPLES +To read parse an elf file, use: +.Bd -literal -offset indent +int fd; +void *p; +struct stat sb; +Elf *e; +\&... +if ((fd = open("./elf-file", O_RDONLY)) < 0 || + fstat(fd, &sb) < 0 || + (p = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t) 0)) == + MAP_FAILED) { + ... handle system error ... +} + +if ((e = elf_memory(p, sb.st_size)) == NULL) { + ... handle elf(3) error ... +} +\&... use ELF descriptor "e" here ... +.Ed +.Sh ERRORS +Function +.Fn elf_memory +can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +A NULL value was used for argument +.Ar image +or the value of argument +.Ar sz +was zero. +.It Bq Er ELF_E_HEADER +The header of the ELF object contained an unsupported value in its +.Va e_ident[EI_CLASS] +field. +.It Bq Er ELF_E_HEADER +The header of the ELF object contained an unsupported value in its +.Va e_ident[EI_DATA] +field. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SEQUENCE +Function +.Fn elf_memory +was called before a working version was set using +.Xr elf_version 3 . +.It Bq Er ELF_E_VERSION +The ELF object referenced by argument +.Ar image +was of an unsupported ELF version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_errno 3 , +.Xr elf_kind 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_memory.c b/contrib/elftoolchain/libelf/elf_memory.c new file mode 100644 index 0000000..9c4755d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_memory.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); + +Elf * +elf_memory(char *image, size_t sz) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + if (image == NULL || sz == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (_libelf_memory(image, sz, 1)); +} diff --git a/contrib/elftoolchain/libelf/elf_next.3 b/contrib/elftoolchain/libelf/elf_next.3 new file mode 100644 index 0000000..859d06c --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_next.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_next.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 17, 2006 +.Os +.Dt ELF_NEXT 3 +.Sh NAME +.Nm elf_next +.Nd provide sequential access to the next archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft Elf_Cmd +.Fn elf_next "Elf *elf" +.Sh DESCRIPTION +The +.Fn elf_next +function causes the ELF archive descriptor corresponding to argument +.Ar elf +to be adjusted to provide access to the next member in +the archive on a subsequent call to +.Fn elf_begin . +.Pp +The return value of +.Fn elf_next +is suitable for use in a loop invoking +.Fn elf_begin . +.Sh RETURN VALUES +If successful, function +.Fn elf_next +returns the value +.Dv ELF_C_READ . +Otherwise, if argument +.Ar elf +was not associated with an archive, or if it was +.Dv NULL , +or if any other error occurred, the value +.Dv ELF_C_NULL +is returned. +.Sh EXAMPLES +To process all the members of an archive use: +.Bd -literal -offset indent +Elf_Cmd cmd; +Elf *archive, *e; +\&... +cmd = ELF_C_READ; +archive = elf_begin(fd, cmd, NULL); +while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) +{ + ... process `e' here ... + + cmd = elf_next(e); + elf_end(e); +} +elf_end(archive); +.Ed +.Sh ERRORS +Function +.Fn elf_next +may fail with the following error: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not associated with a containing +.Xr ar 1 +archive. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_rand 3 diff --git a/contrib/elftoolchain/libelf/elf_next.c b/contrib/elftoolchain/libelf/elf_next.c new file mode 100644 index 0000000..605a593 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_next.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <assert.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_next.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +Elf_Cmd +elf_next(Elf *e) +{ + off_t next; + Elf *parent; + + if (e == NULL) + return (ELF_C_NULL); + + if ((parent = e->e_parent) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (ELF_C_NULL); + } + + assert (parent->e_kind == ELF_K_AR); + assert (parent->e_cmd == ELF_C_READ); + assert(e->e_rawfile > parent->e_rawfile); + + next = e->e_rawfile - parent->e_rawfile + e->e_rawsize; + next = (next + 1) & ~1; /* round up to an even boundary */ + + parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? + (off_t) 0 : next; + + return (ELF_C_READ); +} diff --git a/contrib/elftoolchain/libelf/elf_open.3 b/contrib/elftoolchain/libelf/elf_open.3 new file mode 100644 index 0000000..dad969e --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_open.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2012 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_open.3 2512 2012-05-31 06:15:57Z jkoshy $ +.\" +.Dd May 31, 2012 +.Os +.Dt ELF_OPEN 3 +.Sh NAME +.Nm elf_open +.Nd open ELF objects and ar(1) archives +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf *" +.Fn elf_open "int fd" +.Ft "Elf *" +.Fn elf_openmemory "char *image" "size_t sz" +.Sh DESCRIPTION +.Em Important : +The functions +.Fn elf_open +and +.Fn elf_openmemory +are extensions to the ELF(3) API, for the internal use of the +Elftoolchain project. +Portable applications should not use these functions. +.Pp +The function +.Fn elf_open +returns an Elf descriptor opened with mode +.Dv ELF_C_READ +for the ELF object or +.Xr ar 1 +archive referenced by the file descriptor in argument +.Ar fd . +.Pp +The function +.Fn elf_openmemory +returns an ELF descriptor opened with mode +.Dv ELF_C_READ +for the ELF object or +.Xr ar 1 +archive contained in the memory area pointed to by the argument +.Ar image . +The argument +.Ar sz +specifies the size of the memory area in bytes. +.Sh COMPATIBILITY +These functions are non-standard extensions to the ELF(3) API set. +.Pp +The behavior of these functions differs from their counterparts +.Xr elf_begin 3 +and +.Xr elf_memory 3 +in that these functions will successfully open malformed ELF objects +and +.Xr ar 1 +archives, returning an Elf descriptor of type +.Dv ELF_K_NONE . +.Sh RETURN VALUES +The function returns a pointer to a ELF descriptor if successful, or +NULL if an error occurred. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar fd +was of an unsupported file type. +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar sz +was zero, or the argument +.Ar image +was NULL. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Ar fd +was invalid. +.It Bq Er ELF_E_IO +The file descriptor in argument +.Ar fd +could not be read. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was encountered. +.It Bq Er ELF_E_SEQUENCE +Functions +.Fn elf_open +or +.Fn elf_openmemory +was called before a working version was established with +.Xr elf_version 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_errno 3 , +.Xr elf_memory 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_open.c b/contrib/elftoolchain/libelf/elf_open.c new file mode 100644 index 0000000..b039431 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_open.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id$"); + +/* + * Extension API: open a file for reading, ignoring parse errors. + */ + +Elf * +elf_open(int fd) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + return (_libelf_open_object(fd, ELF_C_READ, 0)); +} + +/* + * Extension API: create an ELF descriptor for an in-memory object, + * ignoring parse errors. + */ + +Elf * +elf_openmemory(char *image, size_t sz) +{ + if (LIBELF_PRIVATE(version) == EV_NONE) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + if (image == NULL || sz == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (_libelf_memory(image, sz, 0)); +} diff --git a/contrib/elftoolchain/libelf/elf_phnum.c b/contrib/elftoolchain/libelf/elf_phnum.c new file mode 100644 index 0000000..5994806 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_phnum.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_phnum.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +static int +_libelf_getphdrnum(Elf *e, size_t *phnum) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *phnum = e->e_u.e_elf.e_nphdr; + + return (0); +} + +int +elf_getphdrnum(Elf *e, size_t *phnum) +{ + return (_libelf_getphdrnum(e, phnum)); +} + +/* Deprecated API */ +int +elf_getphnum(Elf *e, size_t *phnum) +{ + return (_libelf_getphdrnum(e, phnum) >= 0); +} diff --git a/contrib/elftoolchain/libelf/elf_rand.3 b/contrib/elftoolchain/libelf/elf_rand.3 new file mode 100644 index 0000000..e5affd6 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rand.3 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_rand.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd June 17, 2006 +.Os +.Dt ELF_RAND 3 +.Sh NAME +.Nm elf_rand +.Nd provide sequential access to the next archive member +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_rand "Elf *archive" "off_t offset" +.Sh DESCRIPTION +The +.Fn elf_rand +function causes the ELF descriptor +.Ar archive +to be adjusted so that the next call to +.Xr elf_begin 3 +will provide access to the archive member at byte offset +.Ar offset +in the archive. +Argument +.Ar offset +is the byte offset from the start of the archive to the beginning of +the archive header for the desired member. +.Pp +Archive member offsets may be retrieved using the +.Xr elf_getarsym 3 +function. +.Sh RETURN VALUES +Function +.Fn elf_rand +returns +.Ar offset +if successful or zero in case of an error. +.Sh EXAMPLES +To process all the members of an archive use: +.Bd -literal -offset indent +off_t off; +Elf *archive, *e; +\&... +cmd = ELF_C_READ; +archive = elf_begin(fd, cmd, NULL); +while ((e = elf_begin(fd, cmd, archive)) != (Elf *) 0) +{ + ... process `e' here ... + elf_end(e); + + off = ...new value...; + if (elf_rand(archive, off) != off) { + ... process error ... + } +} +elf_end(archive); +.Ed +.Pp +To rewind an archive, use: +.Bd -literal -offset indent +Elf *archive; +\&... +if (elf_rand(archive, SARMAG) != SARMAG) { + ... error ... +} +.Ed +.Sh ERRORS +Function +.Fn elf_rand +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar archive +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar archive +was not a descriptor for an +.Xr ar 1 +archive. +.It Bq Er ELF_E_ARCHIVE +Argument +.Ar offset +did not correspond to the start of an archive member header. +.El +.Sh SEE ALSO +.Xr ar 1 , +.Xr elf 3 , +.Xr elf_begin 3 , +.Xr elf_end 3 , +.Xr elf_getarsym 3 , +.Xr elf_next 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_rand.c b/contrib/elftoolchain/libelf/elf_rand.c new file mode 100644 index 0000000..f48f017 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rand.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_rand.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +off_t +elf_rand(Elf *ar, off_t offset) +{ + struct ar_hdr *arh; + + if (ar == NULL || ar->e_kind != ELF_K_AR || + (offset & 1) || offset < SARMAG || + offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return 0; + } + + arh = (struct ar_hdr *) (ar->e_rawfile + offset); + + /* a too simple sanity check */ + if (arh->ar_fmag[0] != '`' || arh->ar_fmag[1] != '\n') { + LIBELF_SET_ERROR(ARCHIVE, 0); + return 0; + } + + ar->e_u.e_ar.e_next = offset; + + return (offset); +} diff --git a/contrib/elftoolchain/libelf/elf_rawfile.3 b/contrib/elftoolchain/libelf/elf_rawfile.3 new file mode 100644 index 0000000..a713b42 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rawfile.3 @@ -0,0 +1,76 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_rawfile.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd July 3, 2006 +.Os +.Dt ELF_RAWFILE 3 +.Sh NAME +.Nm elf_rawfile +.Nd return uninterpreted contents of an ELF file +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft char * +.Fn elf_rawfile "Elf *elf" "size_t *sz" +.Sh DESCRIPTION +Function +.Fn elf_rawfile +returns the uninterpreted contents of the file referenced by ELF descriptor +.Ar elf . +.Pp +If argument +.Ar sz +is non-null, the function stores the file's size in bytes +in the location to which it points. +A value of zero is written to this location if an error is +encountered. +.Sh RETURN VALUES +Function +.Fn elf_rawfile +returns a valid pointer if successful or NULL if an error occurs. +.Sh ERRORS +Function +.Fn elf_rawfile +may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_SEQUENCE +Argument +.Ar elf +was opened for writing and function +.Fn elf_rawfile +was invoked before +.Xr elf_update 3 . +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getident 3 , +.Xr elf_kind 3 , +.Xr elf_update 3 diff --git a/contrib/elftoolchain/libelf/elf_rawfile.c b/contrib/elftoolchain/libelf/elf_rawfile.c new file mode 100644 index 0000000..76cfd7f --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_rawfile.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_rawfile.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +char * +elf_rawfile(Elf *e, size_t *sz) +{ + char *ptr; + size_t size; + + size = e ? e->e_rawsize : 0; + ptr = NULL; + + if (e == NULL) + LIBELF_SET_ERROR(ARGUMENT, 0); + else if ((ptr = e->e_rawfile) == NULL && e->e_cmd == ELF_C_WRITE) + LIBELF_SET_ERROR(SEQUENCE, 0); + + if (sz) + *sz = size; + + return (ptr); +} diff --git a/contrib/elftoolchain/libelf/elf_scn.c b/contrib/elftoolchain/libelf/elf_scn.c new file mode 100644 index 0000000..357fbb3 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_scn.c @@ -0,0 +1,232 @@ +/*- + * Copyright (c) 2006,2008-2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +#include <sys/queue.h> + +#include <assert.h> +#include <errno.h> +#include <gelf.h> +#include <libelf.h> +#include <stddef.h> +#include <stdlib.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * Load an ELF section table and create a list of Elf_Scn structures. + */ +int +_libelf_load_section_headers(Elf *e, void *ehdr) +{ + int ec, swapbytes; + size_t fsz, i, shnum; + uint64_t shoff; + char *src; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + Elf_Scn *scn; + int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + + assert(e != NULL); + assert(ehdr != NULL); + assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); + +#define CHECK_EHDR(E,EH) do { \ + if (fsz != (EH)->e_shentsize || \ + shoff + fsz * shnum > e->e_rawsize) { \ + LIBELF_SET_ERROR(HEADER, 0); \ + return (0); \ + } \ + } while (0) + + ec = e->e_class; + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); + assert(fsz > 0); + + shnum = e->e_u.e_elf.e_nscn; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + shoff = (uint64_t) eh32->e_shoff; + CHECK_EHDR(e, eh32); + } else { + eh64 = (Elf64_Ehdr *) ehdr; + shoff = eh64->e_shoff; + CHECK_EHDR(e, eh64); + } + + xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); + + swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); + src = e->e_rawfile + shoff; + + /* + * If the file is using extended numbering then section #0 + * would have already been read in. + */ + + i = 0; + if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { + assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == + STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); + + i = 1; + src += fsz; + } + + for (; i < shnum; i++, src += fsz) { + if ((scn = _libelf_allocate_scn(e, i)) == NULL) + return (0); + + (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, + (size_t) 1, swapbytes); + + if (ec == ELFCLASS32) { + scn->s_offset = scn->s_rawoff = + scn->s_shdr.s_shdr32.sh_offset; + scn->s_size = scn->s_shdr.s_shdr32.sh_size; + } else { + scn->s_offset = scn->s_rawoff = + scn->s_shdr.s_shdr64.sh_offset; + scn->s_size = scn->s_shdr.s_shdr64.sh_size; + } + } + + e->e_flags |= LIBELF_F_SHDRS_LOADED; + + return (1); +} + + +Elf_Scn * +elf_getscn(Elf *e, size_t index) +{ + int ec; + void *ehdr; + Elf_Scn *s; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return (NULL); + + STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) + if (s->s_ndx == index) + return (s); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +size_t +elf_ndxscn(Elf_Scn *s) +{ + if (s == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (SHN_UNDEF); + } + return (s->s_ndx); +} + +Elf_Scn * +elf_newscn(Elf *e) +{ + int ec; + void *ehdr; + Elf_Scn *scn; + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + /* + * The application may be asking for a new section descriptor + * on an ELF object opened with ELF_C_RDWR or ELF_C_READ. We + * need to bring in the existing section information before + * appending a new one to the list. + * + * Per the ELF(3) API, an application is allowed to open a + * file using ELF_C_READ, mess with its internal structure and + * use elf_update(...,ELF_C_NULL) to compute its new layout. + */ + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return (NULL); + + if (STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { + assert(e->e_u.e_elf.e_nscn == 0); + if ((scn = _libelf_allocate_scn(e, (size_t) SHN_UNDEF)) == + NULL) + return (NULL); + e->e_u.e_elf.e_nscn++; + } + + assert(e->e_u.e_elf.e_nscn > 0); + + if ((scn = _libelf_allocate_scn(e, e->e_u.e_elf.e_nscn)) == NULL) + return (NULL); + + e->e_u.e_elf.e_nscn++; + + (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); + + return (scn); +} + +Elf_Scn * +elf_nextscn(Elf *e, Elf_Scn *s) +{ + if (e == NULL || (e->e_kind != ELF_K_ELF) || + (s && s->s_elf != e)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + return (s == NULL ? elf_getscn(e, (size_t) 1) : + STAILQ_NEXT(s, s_next)); +} diff --git a/contrib/elftoolchain/libelf/elf_shnum.c b/contrib/elftoolchain/libelf/elf_shnum.c new file mode 100644 index 0000000..a06a9e4 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_shnum.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_shnum.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +static int +_libelf_getshdrnum(Elf *e, size_t *shnum) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *shnum = e->e_u.e_elf.e_nscn; + + return (0); +} + +int +elf_getshdrnum(Elf *e, size_t *shnum) +{ + return (_libelf_getshdrnum(e, shnum)); +} + +/* Deprecated API. */ +int +elf_getshnum(Elf *e, size_t *shnum) +{ + return (_libelf_getshdrnum(e, shnum) >= 0); +} diff --git a/contrib/elftoolchain/libelf/elf_shstrndx.c b/contrib/elftoolchain/libelf/elf_shstrndx.c new file mode 100644 index 0000000..0a7bab9 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_shstrndx.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <ar.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_shstrndx.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +static int +_libelf_getshdrstrndx(Elf *e, size_t *strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (-1); + } + + if ((eh = _libelf_ehdr(e, ec, 0)) == NULL) + return (-1); + + *strndx = e->e_u.e_elf.e_strndx; + + return (0); +} + +int +elf_getshdrstrndx(Elf *e, size_t *strndx) +{ + return (_libelf_getshdrstrndx(e, strndx)); +} + +int +elf_getshstrndx(Elf *e, size_t *strndx) /* Deprecated API. */ +{ + return (_libelf_getshdrstrndx(e, strndx) >= 0); +} + +int +elf_setshstrndx(Elf *e, size_t strndx) +{ + void *eh; + int ec; + + if (e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + ((eh = _libelf_ehdr(e, ec, 0)) == NULL)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + return (_libelf_setshstrndx(e, eh, ec, strndx)); +} diff --git a/contrib/elftoolchain/libelf/elf_strptr.3 b/contrib/elftoolchain/libelf/elf_strptr.3 new file mode 100644 index 0000000..31e0f83 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_strptr.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_strptr.3 1081 2010-08-14 02:23:48Z jkoshy $ +.\" +.Dd December 16, 2006 +.Os +.Dt ELF_STRPTR 3 +.Sh NAME +.Nm elf_strptr +.Nd retrieve a string pointer in a string table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "char *" +.Fn elf_strptr "Elf *elf" "size_t scndx" "size_t stroffset" +.Sh DESCRIPTION +Function +.Fn elf_strptr +allows an application to convert a string table offset to a string +pointer, correctly translating the offset in the presence +of multiple +.Vt Elf_Data +descriptors covering the contents of the section. +.Pp +Argument +.Ar elf +is a descriptor for an ELF object. +Argument +.Ar scndx +is the section index for an ELF string table. +Argument +.Ar stroffset +is the index of the desired string in the string +table. +.Sh RETURN VALUES +Function +.Fn elf_strptr +returns a valid pointer on success or NULL in case an error was +encountered. +.Sh ERRORS +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar scndx +was not the section index for a string table. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar stroffset +exceeded the size of the string table. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar stroffset +index an unallocated region of the string table. +.It Bq Er ELF_E_DATA +Offset +.Ar stroffset +indexed a region that was not covered by any Elf_Data +descriptor. +.It Bq Er ELF_E_DATA +An erroneous +.Vt Elf_Data +descriptor was part of the section specified by argument +.Ar scndx . +.It Bq Er ELF_E_HEADER +ELF descriptor +.Ar elf +contained an invalid section header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +Section +.Ar scndx +contained a malformed section header. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Ar elf +did not adhere to the conventions used for extended numbering. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getshdr 3 , +.Xr elf64_getshdr 3 , +.Xr elf_getdata 3 , +.Xr elf_rawdata 3 , +.Xr gelf 3 , +.Xr gelf_getshdr 3 diff --git a/contrib/elftoolchain/libelf/elf_strptr.c b/contrib/elftoolchain/libelf/elf_strptr.c new file mode 100644 index 0000000..c79970d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_strptr.c @@ -0,0 +1,132 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/param.h> + +#include <assert.h> +#include <gelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_strptr.c 2271 2011-12-03 17:06:35Z jkoshy $"); + +/* + * Convert an ELF section#,offset pair to a string pointer. + */ + +char * +elf_strptr(Elf *e, size_t scndx, size_t offset) +{ + Elf_Scn *s; + Elf_Data *d; + size_t alignment, count; + GElf_Shdr shdr; + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((s = elf_getscn(e, scndx)) == NULL || + gelf_getshdr(s, &shdr) == NULL) + return (NULL); + + if (shdr.sh_type != SHT_STRTAB || + offset >= shdr.sh_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + d = NULL; + if (e->e_flags & ELF_F_LAYOUT) { + + /* + * The application is taking responsibility for the + * ELF object's layout, so we can directly translate + * an offset to a `char *' address using the `d_off' + * members of Elf_Data descriptors. + */ + while ((d = elf_getdata(s, d)) != NULL) { + + if (d->d_buf == 0 || d->d_size == 0) + continue; + + if (d->d_type != ELF_T_BYTE) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if (offset >= d->d_off && + offset < d->d_off + d->d_size) + return ((char *) d->d_buf + offset - d->d_off); + } + } else { + /* + * Otherwise, the `d_off' members are not useable and + * we need to compute offsets ourselves, taking into + * account 'holes' in coverage of the section introduced + * by alignment requirements. + */ + count = (size_t) 0; /* cumulative count of bytes seen */ + while ((d = elf_getdata(s, d)) != NULL && count <= offset) { + + if (d->d_buf == NULL || d->d_size == 0) + continue; + + if (d->d_type != ELF_T_BYTE) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((alignment = d->d_align) > 1) { + if ((alignment & (alignment - 1)) != 0) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + count = roundup2(count, alignment); + } + + if (offset < count) { + /* offset starts in the 'hole' */ + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (offset < count + d->d_size) { + if (d->d_buf != NULL) + return ((char *) d->d_buf + + offset - count); + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + count += d->d_size; + } + } + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/elf_types.m4 b/contrib/elftoolchain/libelf/elf_types.m4 new file mode 100644 index 0000000..9e9680d --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_types.m4 @@ -0,0 +1,309 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: elf_types.m4 321 2009-03-07 16:59:14Z jkoshy $ + */ + +/* + * ELF types, defined in the "enum Elf_Type" API. + * + * The members of the list form a 2-tuple: (name, C-type-suffix). + * + `name' is an Elf_Type symbol without the `ELF_T_' prefix. + * + `C-type-suffix' is the suffix for Elf32_ and Elf64_ type names. + */ + +define(`ELF_TYPE_LIST', + ``ADDR, Addr', + `BYTE, Byte', + `CAP, Cap', + `DYN, Dyn', + `EHDR, Ehdr', + `GNUHASH, -', + `HALF, Half', + `LWORD, Lword', + `MOVE, Move', + `MOVEP, MoveP', + `NOTE, Note', + `OFF, Off', + `PHDR, Phdr', + `REL, Rel', + `RELA, Rela', + `SHDR, Shdr', + `SWORD, Sword', + `SXWORD, Sxword', + `SYMINFO, Syminfo', + `SYM, Sym', + `VDEF, Verdef', + `VNEED, Verneed', + `WORD, Word', + `XWORD, Xword', + `NUM, _'') + +/* + * DEFINE_STRUCT(NAME,MEMBERLIST...) + * + * Map a type name to its members. + * + * Each member-list element comprises of pairs of (field name, type), + * in the sequence used in the file representation of `NAME'. + * + * Each member list element comprises a pair containing a field name + * and a basic type. Basic types include IDENT, HALF, WORD, LWORD, + * ADDR{32,64}, OFF{32,64}, SWORD, XWORD, SXWORD. + * + * The last element of a member list is the null element: `_,_'. + */ + +define(`DEFINE_STRUCT',`define(`$1_DEF',shift($@))dnl') + +DEFINE_STRUCT(`Elf32_Cap', + ``c_tag, WORD', + `c_un.c_val, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Cap', + ``c_tag, XWORD', + `c_un.c_val, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Dyn', + ``d_tag, SWORD', + `d_un.d_ptr, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Dyn', + ``d_tag, SXWORD', + `d_un.d_ptr, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Ehdr', + ``e_ident, IDENT', + `e_type, HALF', + `e_machine, HALF', + `e_version, WORD', + `e_entry, ADDR', + `e_phoff, OFF', + `e_shoff, OFF', + `e_flags, WORD', + `e_ehsize, HALF', + `e_phentsize, HALF', + `e_phnum, HALF', + `e_shentsize, HALF', + `e_shnum, HALF', + `e_shstrndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Ehdr', + ``e_ident, IDENT', + `e_type, HALF', + `e_machine, HALF', + `e_version, WORD', + `e_entry, ADDR', + `e_phoff, OFF', + `e_shoff, OFF', + `e_flags, WORD', + `e_ehsize, HALF', + `e_phentsize, HALF', + `e_phnum, HALF', + `e_shentsize, HALF', + `e_shnum, HALF', + `e_shstrndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Move', + ``m_value, LWORD', + `m_info, WORD', + `m_poffset, WORD', + `m_repeat, HALF', + `m_stride, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Move', + ``m_value, LWORD', + `m_info, XWORD', + `m_poffset, XWORD', + `m_repeat, HALF', + `m_stride, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Phdr', + ``p_type, WORD', + `p_offset, OFF', + `p_vaddr, ADDR', + `p_paddr, ADDR', + `p_filesz, WORD', + `p_memsz, WORD', + `p_flags, WORD', + `p_align, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Phdr', + ``p_type, WORD', + `p_flags, WORD', + `p_offset, OFF', + `p_vaddr, ADDR', + `p_paddr, ADDR', + `p_filesz, XWORD', + `p_memsz, XWORD', + `p_align, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Rel', + ``r_offset, ADDR', + `r_info, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Rel', + ``r_offset, ADDR', + `r_info, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Rela', + ``r_offset, ADDR', + `r_info, WORD', + `r_addend, SWORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Rela', + ``r_offset, ADDR', + `r_info, XWORD', + `r_addend, SXWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Shdr', + ``sh_name, WORD', + `sh_type, WORD', + `sh_flags, WORD', + `sh_addr, ADDR', + `sh_offset, OFF', + `sh_size, WORD', + `sh_link, WORD', + `sh_info, WORD', + `sh_addralign, WORD', + `sh_entsize, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Shdr', + ``sh_name, WORD', + `sh_type, WORD', + `sh_flags, XWORD', + `sh_addr, ADDR', + `sh_offset, OFF', + `sh_size, XWORD', + `sh_link, WORD', + `sh_info, WORD', + `sh_addralign, XWORD', + `sh_entsize, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Sym', + ``st_name, WORD', + `st_value, ADDR', + `st_size, WORD', + `st_info, BYTE', + `st_other, BYTE', + `st_shndx, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Sym', + ``st_name, WORD', + `st_info, BYTE', + `st_other, BYTE', + `st_shndx, HALF', + `st_value, ADDR', + `st_size, XWORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Syminfo', + ``si_boundto, HALF', + `si_flags, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf64_Syminfo', + ``si_boundto, HALF', + `si_flags, HALF', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verdaux', + ``vda_name, WORD', + `vda_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verdaux', + ``vda_name, WORD', + `vda_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verdef', + ``vd_version, HALF', + `vd_flags, HALF', + `vd_ndx, HALF', + `vd_cnt, HALF', + `vd_hash, WORD', + `vd_aux, WORD', + `vd_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verdef', + ``vd_version, HALF', + `vd_flags, HALF', + `vd_ndx, HALF', + `vd_cnt, HALF', + `vd_hash, WORD', + `vd_aux, WORD', + `vd_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Verneed', + ``vn_version, HALF', + `vn_cnt, HALF', + `vn_file, WORD', + `vn_aux, WORD', + `vn_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Verneed', + ``vn_version, HALF', + `vn_cnt, HALF', + `vn_file, WORD', + `vn_aux, WORD', + `vn_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf32_Vernaux', + ``vna_hash, WORD', + `vna_flags, HALF', + `vna_other, HALF', + `vna_name, WORD', + `vna_next, WORD', + `_,_'') + +DEFINE_STRUCT(`Elf64_Vernaux', + ``vna_hash, WORD', + `vna_flags, HALF', + `vna_other, HALF', + `vna_name, WORD', + `vna_next, WORD', + `_,_'') diff --git a/contrib/elftoolchain/libelf/elf_update.3 b/contrib/elftoolchain/libelf/elf_update.3 new file mode 100644 index 0000000..40a1e40 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_update.3 @@ -0,0 +1,378 @@ +.\" Copyright (c) 2006-2011 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_update.3 1729 2011-08-14 09:13:00Z jkoshy $ +.\" +.Dd August 14, 2011 +.Os +.Dt ELF_UPDATE 3 +.Sh NAME +.Nm elf_update +.Nd update an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft off_t +.Fn elf_update "Elf *elf" "Elf_Cmd cmd" +.Sh DESCRIPTION +Function +.Fn elf_update +causes the library to recalculate the structure of an ELF +object and optionally write out the image of the object +to file. +.Pp +Argument +.Ar elf +should reference a valid ELF descriptor. +.Pp +Argument +.Ar cmd +can be one of the following values: +.Bl -tag -width "Dv ELF_C_WRITE" +.It Dv ELF_C_NULL +The library will recalculate structural information flagging +modified structures with the +.Dv ELF_F_DIRTY +flag, but will not write data to the underlying file image. +.It Dv ELF_C_WRITE +The library will recalculate structural information and will +also write the new image to the underlying file. +The ELF descriptor referenced by argument +.Ar elf +should permit the underlying ELF object to be written or updated +(see +.Xr elf_begin 3 ) . +.El +.Pp +All pointers to +.Vt Elf_Scn +and +.Vt Elf_Data +descriptors associated with descriptor +.Ar elf +should be considered invalid after a call to +.Fn elf_update . +.Ss Specifying Object Layout +The +.Lb libelf +supports two layout modes. +.Bl -tag -width indent +.It "Library Layout" +If the +.Dv ELF_F_LAYOUT +flag is not set on the ELF descriptor, the ELF library will lay out +the ELF object according to the following scheme: +.Bl -tag -compact -width "Section Data" +.It Em EHDR +The ELF executable header will be placed at the start of the object. +.It Em PHDR +If the ELF descriptor contains a program header table, it will be +placed after the Executable Header. +.It Em Section Data +ELF section data, if any, will be placed next, keeping each section's +alignment requirements in mind. +.It Em SHDR +The ELF section header table, if any, will be placed last. +.El +.It "Application Controlled Layout" +The application can take full control of the layout of the ELF object +by setting the +.Dv ELF_F_LAYOUT +flag on the ELF descriptor (see +.Xr elf_flagelf 3 ) . +In this case the library will lay out the ELF object using +application-supplied information as below: +.Pp +.Bl -tag -compact -width "Section Data" +.It Em EHDR +The ELF executable header will be placed at the start of the object. +.It Em PHDR +The ELF program header table, if any, it will be placed at the offset +specified in the +.Va e_phoff +field of the ELF executable header. +.It Em Section Data +The data for each ELF section will be placed at the offset specified +by the +.Va sh_offset +field of the section's header. +The size of the section will be taken from the +.Va sh_size +field of the section header. +.It Em SHDR +The ELF section header table, if any, will be placed at the offset +specified by the +.Va e_shoff +field of the executable header. +.El +.El +.Pp +Gaps in the coverage of the file's contents will be set to the fill value +specified by +.Xr elf_fill 3 . +.Ss Application Supplied Information +The application needs to set the following fields in the data +structures associated with the ELF descriptor prior to calling +.Fn elf_update . +.Bl -tag -width indent +.It "Executable Header" +The fields of the ELF executable header that need to be set by the +application are: +.Pp +.Bl -tag -width "e_ident[EI_OSABI]" -compact +.It Va e_entry +To be set to the desired entry address for executables. +.It Va e_flags +To be set to the desired processor specific flags. +.It Va "e_ident[EI_DATA]" +Must be set to one of +.Dv ELFDATA2LSB +or +.Dv ELFDATA2MSB . +.It Va "e_ident[EI_OSABI]" +To be set to the OS ABI desired. +For example, for +.Fx +executables, this field should be set to +.Dv ELFOSABI_FREEBSD . +.It Va e_machine +To be set to the desired machine architecture, one of the +.Dv EM_* +values in the header file +.In elfdefinitions.h . +.It Va e_phoff +If the application is managing the object's layout, it must +set this field to the file offset of the ELF program header table. +.It Va e_shoff +If the application is managing the object's layout, it must +set this field to the file offset of the ELF section header table. +.It Va e_shstrndx +To be set to the index of the string table containing +section names. +.It Va e_type +To be set to the type of the ELF object, one of the +.Dv ET_* +values in the header file +.In elfdefinitions.h . +.It Va e_version +To be set to the desired version of the ELF object. +.El +.It "Program Header" +All fields of the entries in the program header table need to be +set by the application. +.It "Section Header" +The fields of ELF section headers that need to be set by the +application are: +.Pp +.Bl -tag -width "sh_addralign" -compact +.It Va sh_addr +To be set to the memory address where the section should reside. +.It Va sh_addralign +If the application is managing the file layout, it must set this +field to the desired alignment for the section's contents. +This value must be a power of two and must be at least as large as the +largest alignment needed by any +.Vt Elf_Data +descriptor associated with the section. +.It Va sh_entsize +To be set to the size of each entry, for sections containing fixed size +elements, or set to zero for sections without fixed size elements. +If the application is not managing file layout, it may leave this +field as zero for those sections whose types are known to the library. +.It Va sh_flags +To be set to the desired section flags. +.It Va sh_info +To be set as described in +.Xr elf 5 . +.It Va sh_link +To be set as described in +.Xr elf 5 . +.It Va sh_name +To be set to the index of the section's name in the string table +containing section names. +.It Va sh_offset +If the application is managing the file layout, it must set this +field to the file offset of the section's contents. +.It Va sh_size +If the application is managing the file layout, it must set this +field to the file size of the section's contents. +.It Va sh_type +To be set to the type of the section. +.El +.It "Section Data" +The +.Vt Elf_Data +descriptors associated with each section specify its contents +(see +.Xr elf_getdata 3 ) . +While all the fields in these descriptors are under application +control, the following fields influence object layout: +.Bl -tag -width "Va d_align" -compact +.It Va d_align +To be set to the desired alignment, within the containing section, of +the descriptor's data. +.It Va d_off +If the application is managing object layout, it must set this field +to the file offset, within the section, at which the descriptor's data +should be placed. +.It Va d_size +To be set to the size in bytes of the memory representation of the +descriptor's data. +.El +.El +.Sh RETURN VALUES +Function +.Fn elf_update +returns the total size of the file image if successful, or -1 if an +error occurred. +.Sh ERRORS +This function may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar cmd +was not recognized. +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +The +.Va e_ident[EI_CLASS] +field of the executable header of argument +.Ar elf +did not match the class of the file. +.It Bq Er ELF_E_DATA +An +.Vt Elf_Data +descriptor contained in argument +.Ar elf +specified an unsupported type. +.It Bq Er ELF_E_DATA +An +.Vt Elf_Data +descriptor specified an alignment that was zero or was not a power of +two. +.It Bq Er ELF_E_HEADER +The ELF header in argument +.Ar elf +requested a different byte order from the byte order already +associated with the file. +.It Bq Er ELF_E_IO +An I/O error was encountered. +.It Bq Er ELF_E_LAYOUT +An +.Vt Elf_Data +descriptor contained in argument +.Ar elf +specified an alignment incompatible with its containing section. +.It Bq Er ELF_E_LAYOUT +Argument +.Ar elf +contained section descriptors that overlapped in extent. +.It Bq Er ELF_E_LAYOUT +Argument +.Ar elf +contained section descriptors that were incorrectly aligned or were +too small for their data. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the executable header overlapped +with the program header table. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the program header table was placed +at a misaligned file offset. +.It Bq Er ELF_E_LAYOUT +The flag +.Dv ELF_F_LAYOUT +was set on the Elf descriptor and the section header table overlapped +an extent mapped by a section descriptor. +.It Bq Er ELF_E_LAYOUT +The +.Dv ELF_F_LAYOUT +flag was set on the Elf descriptor, and the +.Va d_offset +field in an +.Vt Elf_Data +descriptor contained a value that was not a multiple of the +descriptor's specified alignment. +.It Bq Er ELF_E_MODE +An +.Dv ELF_C_WRITE +operation was requested with an ELF descriptor that was not opened for +writing or updating. +.It Bq Er ELF_E_SECTION +Argument +.Ar elf +contained a section with an unrecognized type. +.It Bq Er ELF_E_SECTION +The section header at index +.Dv SHN_UNDEF +had an illegal section type. +.It Bq Er ELF_E_SEQUENCE +An +.Dv ELF_C_WRITE +operation was requested after a prior call to +.Fn elf_cntl elf ELF_C_FDDONE +disassociated the ELF descriptor +.Ar elf +from its underlying file. +.It Bq Er ELF_E_VERSION +Argument +.Ar elf +had an unsupported version or contained an +.Vt Elf_Data +descriptor with an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf32_getphdr 3 , +.Xr elf32_newehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf64_getphdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf_begin 3 , +.Xr elf_cntl 3 , +.Xr elf_fill 3 , +.Xr elf_flagehdr 3 , +.Xr elf_flagelf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr elf_newdata 3 , +.Xr elf_newscn 3 , +.Xr elf_rawdata 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr gelf_newphdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/elf_update.c b/contrib/elftoolchain/libelf/elf_update.c new file mode 100644 index 0000000..b589233 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_update.c @@ -0,0 +1,1202 @@ +/*- + * Copyright (c) 2006-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/param.h> +#include <sys/stat.h> + +#include <assert.h> +#include <errno.h> +#include <gelf.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include <sys/mman.h> +#endif + +ELFTC_VCSID("$Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy $"); + +/* + * Layout strategy: + * + * - Case 1: ELF_F_LAYOUT is asserted + * In this case the application has full control over where the + * section header table, program header table, and section data + * will reside. The library only perform error checks. + * + * - Case 2: ELF_F_LAYOUT is not asserted + * + * The library will do the object layout using the following + * ordering: + * - The executable header is placed first, are required by the + * ELF specification. + * - The program header table is placed immediately following the + * executable header. + * - Section data, if any, is placed after the program header + * table, aligned appropriately. + * - The section header table, if needed, is placed last. + * + * There are two sub-cases to be taken care of: + * + * - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR + * + * In this sub-case, the underlying ELF object may already have + * content in it, which the application may have modified. The + * library will retrieve content from the existing object as + * needed. + * + * - Case 2b: e->e_cmd == ELF_C_WRITE + * + * The ELF object is being created afresh in this sub-case; + * there is no pre-existing content in the underlying ELF + * object. + */ + +/* + * The types of extents in an ELF object. + */ +enum elf_extent { + ELF_EXTENT_EHDR, + ELF_EXTENT_PHDR, + ELF_EXTENT_SECTION, + ELF_EXTENT_SHDR +}; + +/* + * A extent descriptor, used when laying out an ELF object. + */ +struct _Elf_Extent { + SLIST_ENTRY(_Elf_Extent) ex_next; + uint64_t ex_start; /* Start of the region. */ + uint64_t ex_size; /* The size of the region. */ + enum elf_extent ex_type; /* Type of region. */ + void *ex_desc; /* Associated descriptor. */ +}; + +SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); + +/* + * Compute the extents of a section, by looking at the data + * descriptors associated with it. The function returns 1 + * if successful, or zero if an error was detected. + */ +static int +_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) +{ + int ec; + Elf_Data *d; + size_t fsz, msz; + uint32_t sh_type; + uint64_t d_align; + Elf32_Shdr *shdr32; + Elf64_Shdr *shdr64; + unsigned int elftype; + struct _Libelf_Data *ld; + uint64_t scn_size, scn_alignment; + uint64_t sh_align, sh_entsize, sh_offset, sh_size; + + ec = e->e_class; + + shdr32 = &s->s_shdr.s_shdr32; + shdr64 = &s->s_shdr.s_shdr64; + if (ec == ELFCLASS32) { + sh_type = shdr32->sh_type; + sh_align = (uint64_t) shdr32->sh_addralign; + sh_entsize = (uint64_t) shdr32->sh_entsize; + sh_offset = (uint64_t) shdr32->sh_offset; + sh_size = (uint64_t) shdr32->sh_size; + } else { + sh_type = shdr64->sh_type; + sh_align = shdr64->sh_addralign; + sh_entsize = shdr64->sh_entsize; + sh_offset = shdr64->sh_offset; + sh_size = shdr64->sh_size; + } + + assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS); + + elftype = _libelf_xlate_shtype(sh_type); + if (elftype > ELF_T_LAST) { + LIBELF_SET_ERROR(SECTION, 0); + return (0); + } + + if (sh_align == 0) + sh_align = _libelf_falign(elftype, ec); + + /* + * Compute the section's size and alignment using the data + * descriptors associated with the section. + */ + if (STAILQ_EMPTY(&s->s_data)) { + /* + * The section's content (if any) has not been read in + * yet. If section is not dirty marked dirty, we can + * reuse the values in the 'sh_size' and 'sh_offset' + * fields of the section header. + */ + if ((s->s_flags & ELF_F_DIRTY) == 0) { + /* + * If the library is doing the layout, then we + * compute the new start offset for the + * section based on the current offset and the + * section's alignment needs. + * + * If the application is doing the layout, we + * can use the value in the 'sh_offset' field + * in the section header directly. + */ + if (e->e_flags & ELF_F_LAYOUT) + goto updatedescriptor; + else + goto computeoffset; + } + + /* + * Otherwise, we need to bring in the section's data + * from the underlying ELF object. + */ + if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL) + return (0); + } + + /* + * Loop through the section's data descriptors. + */ + scn_size = 0L; + scn_alignment = 0; + STAILQ_FOREACH(ld, &s->s_data, d_next) { + + d = &ld->d_data; + + /* + * The data buffer's type is known. + */ + if (d->d_type >= ELF_T_NUM) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * The data buffer's version is supported. + */ + if (d->d_version != e->e_version) { + LIBELF_SET_ERROR(VERSION, 0); + return (0); + } + + /* + * The buffer's alignment is non-zero and a power of + * two. + */ + if ((d_align = d->d_align) == 0 || + (d_align & (d_align - 1))) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * The buffer's size should be a multiple of the + * memory size of the underlying type. + */ + msz = _libelf_msize(d->d_type, ec, e->e_version); + if (d->d_size % msz) { + LIBELF_SET_ERROR(DATA, 0); + return (0); + } + + /* + * If the application is controlling layout, then the + * d_offset field should be compatible with the + * buffer's specified alignment. + */ + if ((e->e_flags & ELF_F_LAYOUT) && + (d->d_off & (d_align - 1))) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + + /* + * Compute the section's size. + */ + if (e->e_flags & ELF_F_LAYOUT) { + if ((uint64_t) d->d_off + d->d_size > scn_size) + scn_size = d->d_off + d->d_size; + } else { + scn_size = roundup2(scn_size, d->d_align); + d->d_off = scn_size; + fsz = _libelf_fsize(d->d_type, ec, d->d_version, + d->d_size / msz); + scn_size += fsz; + } + + /* + * The section's alignment is the maximum alignment + * needed for its data buffers. + */ + if (d_align > scn_alignment) + scn_alignment = d_align; + } + + + /* + * If the application is requesting full control over the + * layout of the section, check the section's specified size, + * offsets and alignment for sanity. + */ + if (e->e_flags & ELF_F_LAYOUT) { + if (scn_alignment > sh_align || sh_offset % sh_align || + sh_size < scn_size) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + goto updatedescriptor; + } + + /* + * Otherwise, compute the values in the section header. + * + * The section alignment is the maximum alignment for any of + * its contained data descriptors. + */ + if (scn_alignment > sh_align) + sh_align = scn_alignment; + + /* + * If the section entry size is zero, try and fill in an + * appropriate entry size. Per the elf(5) manual page + * sections without fixed-size entries should have their + * 'sh_entsize' field set to zero. + */ + if (sh_entsize == 0 && + (sh_entsize = _libelf_fsize(elftype, ec, e->e_version, + (size_t) 1)) == 1) + sh_entsize = 0; + + sh_size = scn_size; + +computeoffset: + /* + * Compute the new offset for the section based on + * the section's alignment needs. + */ + sh_offset = roundup(rc, sh_align); + + /* + * Update the section header. + */ + if (ec == ELFCLASS32) { + shdr32->sh_addralign = (uint32_t) sh_align; + shdr32->sh_entsize = (uint32_t) sh_entsize; + shdr32->sh_offset = (uint32_t) sh_offset; + shdr32->sh_size = (uint32_t) sh_size; + } else { + shdr64->sh_addralign = sh_align; + shdr64->sh_entsize = sh_entsize; + shdr64->sh_offset = sh_offset; + shdr64->sh_size = sh_size; + } + +updatedescriptor: + /* + * Update the section descriptor. + */ + s->s_size = sh_size; + s->s_offset = sh_offset; + + return (1); +} + +/* + * Free a list of extent descriptors. + */ + +static void +_libelf_release_extents(struct _Elf_Extent_List *extents) +{ + struct _Elf_Extent *ex; + + while ((ex = SLIST_FIRST(extents)) != NULL) { + SLIST_REMOVE_HEAD(extents, ex_next); + free(ex); + } +} + +/* + * Check if an extent 's' defined by [start..start+size) is free. + * This routine assumes that the given extent list is sorted in order + * of ascending extent offsets. + */ + +static int +_libelf_extent_is_unused(struct _Elf_Extent_List *extents, + const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt) +{ + uint64_t tmax, tmin; + struct _Elf_Extent *t, *pt; + const uint64_t smax = start + size; + + /* First, look for overlaps with existing extents. */ + pt = NULL; + SLIST_FOREACH(t, extents, ex_next) { + tmin = t->ex_start; + tmax = tmin + t->ex_size; + + if (tmax <= start) { + /* + * 't' lies entirely before 's': ...| t |...| s |... + */ + pt = t; + continue; + } else if (smax <= tmin) { + /* + * 's' lies entirely before 't', and after 'pt': + * ...| pt |...| s |...| t |... + */ + assert(pt == NULL || + pt->ex_start + pt->ex_size <= start); + break; + } else + /* 's' and 't' overlap. */ + return (0); + } + + if (prevt) + *prevt = pt; + return (1); +} + +/* + * Insert an extent into the list of extents. + */ + +static int +_libelf_insert_extent(struct _Elf_Extent_List *extents, int type, + uint64_t start, uint64_t size, void *desc) +{ + struct _Elf_Extent *ex, *prevt; + + assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR); + + prevt = NULL; + + /* + * If the requested range overlaps with an existing extent, + * signal an error. + */ + if (!_libelf_extent_is_unused(extents, start, size, &prevt)) { + LIBELF_SET_ERROR(LAYOUT, 0); + return (0); + } + + /* Allocate and fill in a new extent descriptor. */ + if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return (0); + } + ex->ex_start = start; + ex->ex_size = size; + ex->ex_desc = desc; + ex->ex_type = type; + + /* Insert the region descriptor into the list. */ + if (prevt) + SLIST_INSERT_AFTER(prevt, ex, ex_next); + else + SLIST_INSERT_HEAD(extents, ex, ex_next); + return (1); +} + +/* + * Recompute section layout. + */ + +static off_t +_libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) +{ + int ec; + Elf_Scn *s; + size_t sh_type; + + ec = e->e_class; + + /* + * Make a pass through sections, computing the extent of each + * section. + */ + STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) { + if (ec == ELFCLASS32) + sh_type = s->s_shdr.s_shdr32.sh_type; + else + sh_type = s->s_shdr.s_shdr64.sh_type; + + if (sh_type == SHT_NOBITS || sh_type == SHT_NULL) + continue; + + if (_libelf_compute_section_extents(e, s, rc) == 0) + return ((off_t) -1); + + if (s->s_size == 0) + continue; + + if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION, + s->s_offset, s->s_size, s)) + return ((off_t) -1); + + if ((size_t) rc < s->s_offset + s->s_size) + rc = s->s_offset + s->s_size; + } + + return (rc); +} + +/* + * Recompute the layout of the ELF object and update the internal data + * structures associated with the ELF descriptor. + * + * Returns the size in bytes the ELF object would occupy in its file + * representation. + * + * After a successful call to this function, the following structures + * are updated: + * + * - The ELF header is updated. + * - All extents in the ELF object are sorted in order of ascending + * addresses. Sections have their section header table entries + * updated. An error is signalled if an overlap was detected among + * extents. + * - Data descriptors associated with sections are checked for valid + * types, offsets and alignment. + * + * After a resync_elf() successfully returns, the ELF descriptor is + * ready for being handed over to _libelf_write_elf(). + */ + +static off_t +_libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) +{ + int ec, eh_class; + unsigned int eh_byteorder, eh_version; + size_t align, fsz; + size_t phnum, shnum; + off_t rc, phoff, shoff; + void *ehdr, *phdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + rc = 0; + + ec = e->e_class; + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + /* + * Prepare the EHDR. + */ + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return ((off_t) -1); + + eh32 = ehdr; + eh64 = ehdr; + + if (ec == ELFCLASS32) { + eh_byteorder = eh32->e_ident[EI_DATA]; + eh_class = eh32->e_ident[EI_CLASS]; + phoff = (uint64_t) eh32->e_phoff; + shoff = (uint64_t) eh32->e_shoff; + eh_version = eh32->e_version; + } else { + eh_byteorder = eh64->e_ident[EI_DATA]; + eh_class = eh64->e_ident[EI_CLASS]; + phoff = eh64->e_phoff; + shoff = eh64->e_shoff; + eh_version = eh64->e_version; + } + + if (eh_version == EV_NONE) + eh_version = EV_CURRENT; + + if (eh_version != e->e_version) { /* always EV_CURRENT */ + LIBELF_SET_ERROR(VERSION, 0); + return ((off_t) -1); + } + + if (eh_class != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return ((off_t) -1); + } + + if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) { + LIBELF_SET_ERROR(HEADER, 0); + return ((off_t) -1); + } + + shnum = e->e_u.e_elf.e_nscn; + phnum = e->e_u.e_elf.e_nphdr; + + e->e_byteorder = eh_byteorder; + +#define INITIALIZE_EHDR(E,EC,V) do { \ + (E)->e_ident[EI_MAG0] = ELFMAG0; \ + (E)->e_ident[EI_MAG1] = ELFMAG1; \ + (E)->e_ident[EI_MAG2] = ELFMAG2; \ + (E)->e_ident[EI_MAG3] = ELFMAG3; \ + (E)->e_ident[EI_CLASS] = (EC); \ + (E)->e_ident[EI_VERSION] = (V); \ + (E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \ + (size_t) 1); \ + (E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \ + ELF_T_PHDR, (EC), (V), (size_t) 1); \ + (E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \ + (size_t) 1); \ + } while (0) + + if (ec == ELFCLASS32) + INITIALIZE_EHDR(eh32, ec, eh_version); + else + INITIALIZE_EHDR(eh64, ec, eh_version); + + (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); + + rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); + + if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) + return ((off_t) -1); + + /* + * Compute the layout the program header table, if one is + * present. The program header table needs to be aligned to a + * `natural' boundary. + */ + if (phnum) { + fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum); + align = _libelf_falign(ELF_T_PHDR, ec); + + if (e->e_flags & ELF_F_LAYOUT) { + /* + * Check offsets for sanity. + */ + if (rc > phoff) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + + if (phoff % align) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + + } else + phoff = roundup(rc, align); + + rc = phoff + fsz; + + phdr = _libelf_getphdr(e, ec); + + if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, + fsz, phdr)) + return ((off_t) -1); + } else + phoff = 0; + + /* + * Compute the layout of the sections associated with the + * file. + */ + + if (e->e_cmd != ELF_C_WRITE && + (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && + _libelf_load_section_headers(e, ehdr) == 0) + return ((off_t) -1); + + if ((rc = _libelf_resync_sections(e, rc, extents)) < 0) + return ((off_t) -1); + + /* + * Compute the space taken up by the section header table, if + * one is needed. + * + * If ELF_F_LAYOUT has been asserted, the application may have + * placed the section header table in between existing + * sections, so the net size of the file need not increase due + * to the presence of the section header table. + * + * If the library is responsible for laying out the object, + * the section header table is placed after section data. + */ + if (shnum) { + fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum); + align = _libelf_falign(ELF_T_SHDR, ec); + + if (e->e_flags & ELF_F_LAYOUT) { + if (shoff % align) { + LIBELF_SET_ERROR(LAYOUT, 0); + return ((off_t) -1); + } + } else + shoff = roundup(rc, align); + + if (shoff + fsz > (size_t) rc) + rc = shoff + fsz; + + if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, + fsz, NULL)) + return ((off_t) -1); + } else + shoff = 0; + + /* + * Set the fields of the Executable Header that could potentially use + * extended numbering. + */ + _libelf_setphnum(e, ehdr, ec, phnum); + _libelf_setshnum(e, ehdr, ec, shnum); + + /* + * Update the `e_phoff' and `e_shoff' fields if the library is + * doing the layout. + */ + if ((e->e_flags & ELF_F_LAYOUT) == 0) { + if (ec == ELFCLASS32) { + eh32->e_phoff = (uint32_t) phoff; + eh32->e_shoff = (uint32_t) shoff; + } else { + eh64->e_phoff = (uint64_t) phoff; + eh64->e_shoff = (uint64_t) shoff; + } + } + + return (rc); +} + +/* + * Write out the contents of an ELF section. + */ + +static size_t +_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) +{ + int ec; + Elf_Scn *s; + int elftype; + Elf_Data *d, dst; + uint32_t sh_type; + struct _Libelf_Data *ld; + uint64_t sh_off, sh_size; + size_t fsz, msz, nobjects, rc; + + assert(ex->ex_type == ELF_EXTENT_SECTION); + + s = ex->ex_desc; + rc = ex->ex_start; + + if ((ec = e->e_class) == ELFCLASS32) { + sh_type = s->s_shdr.s_shdr32.sh_type; + sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; + } else { + sh_type = s->s_shdr.s_shdr64.sh_type; + sh_size = s->s_shdr.s_shdr64.sh_size; + } + + /* + * Ignore sections that do not allocate space in the file. + */ + if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0) + return (rc); + + elftype = _libelf_xlate_shtype(sh_type); + assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST); + + sh_off = s->s_offset; + assert(sh_off % _libelf_falign(elftype, ec) == 0); + + /* + * If the section has a `rawdata' descriptor, and the section + * contents have not been modified, use its contents directly. + * The `s_rawoff' member contains the offset into the original + * file, while `s_offset' contains its new location in the + * destination. + */ + + if (STAILQ_EMPTY(&s->s_data)) { + + if ((d = elf_rawdata(s, NULL)) == NULL) + return ((off_t) -1); + + STAILQ_FOREACH(ld, &s->s_rawdata, d_next) { + + d = &ld->d_data; + + if ((uint64_t) rc < sh_off + d->d_off) + (void) memset(nf + rc, + LIBELF_PRIVATE(fillchar), sh_off + + d->d_off - rc); + rc = sh_off + d->d_off; + + assert(d->d_buf != NULL); + assert(d->d_type == ELF_T_BYTE); + assert(d->d_version == e->e_version); + + (void) memcpy(nf + rc, + e->e_rawfile + s->s_rawoff + d->d_off, d->d_size); + + rc += d->d_size; + } + + return (rc); + } + + /* + * Iterate over the set of data descriptors for this section. + * The prior call to _libelf_resync_elf() would have setup the + * descriptors for this step. + */ + + dst.d_version = e->e_version; + + STAILQ_FOREACH(ld, &s->s_data, d_next) { + + d = &ld->d_data; + + msz = _libelf_msize(d->d_type, ec, e->e_version); + + if ((uint64_t) rc < sh_off + d->d_off) + (void) memset(nf + rc, + LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); + + rc = sh_off + d->d_off; + + assert(d->d_buf != NULL); + assert(d->d_version == e->e_version); + assert(d->d_size % msz == 0); + + nobjects = d->d_size / msz; + + fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); + + dst.d_buf = nf + rc; + dst.d_size = fsz; + + if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) == + NULL) + return ((off_t) -1); + + rc += fsz; + } + + return ((off_t) rc); +} + +/* + * Write out an ELF Executable Header. + */ + +static off_t +_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) +{ + int ec; + void *ehdr; + size_t fsz, msz; + Elf_Data dst, src; + + assert(ex->ex_type == ELF_EXTENT_EHDR); + assert(ex->ex_start == 0); /* Ehdr always comes first. */ + + ec = e->e_class; + + ehdr = _libelf_ehdr(e, ec, 0); + assert(ehdr != NULL); + + fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); + msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + src.d_buf = ehdr; + src.d_size = msz; + src.d_type = ELF_T_EHDR; + src.d_version = dst.d_version = e->e_version; + + dst.d_buf = nf; + dst.d_size = fsz; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == + NULL) + return ((off_t) -1); + + return ((off_t) fsz); +} + +/* + * Write out an ELF program header table. + */ + +static off_t +_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) +{ + int ec; + void *ehdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + Elf_Data dst, src; + size_t fsz, phnum; + uint64_t phoff; + + assert(ex->ex_type == ELF_EXTENT_PHDR); + + ec = e->e_class; + ehdr = _libelf_ehdr(e, ec, 0); + phnum = e->e_u.e_elf.e_nphdr; + + assert(phnum > 0); + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + phoff = (uint64_t) eh32->e_phoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + phoff = eh64->e_phoff; + } + + assert(phoff > 0); + assert(ex->ex_start == phoff); + assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum); + assert(fsz > 0); + + src.d_buf = _libelf_getphdr(e, ec); + src.d_version = dst.d_version = e->e_version; + src.d_type = ELF_T_PHDR; + src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec, + e->e_version); + + dst.d_size = fsz; + dst.d_buf = nf + ex->ex_start; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == + NULL) + return ((off_t) -1); + + return (phoff + fsz); +} + +/* + * Write out an ELF section header table. + */ + +static off_t +_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) +{ + int ec; + void *ehdr; + Elf_Scn *scn; + uint64_t shoff; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + size_t fsz, nscn; + Elf_Data dst, src; + + assert(ex->ex_type == ELF_EXTENT_SHDR); + + ec = e->e_class; + ehdr = _libelf_ehdr(e, ec, 0); + nscn = e->e_u.e_elf.e_nscn; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + shoff = (uint64_t) eh32->e_shoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + shoff = eh64->e_shoff; + } + + assert(nscn > 0); + assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0); + assert(ex->ex_start == shoff); + + (void) memset(&dst, 0, sizeof(dst)); + (void) memset(&src, 0, sizeof(src)); + + src.d_type = ELF_T_SHDR; + src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); + src.d_version = dst.d_version = e->e_version; + + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); + + STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) { + if (ec == ELFCLASS32) + src.d_buf = &scn->s_shdr.s_shdr32; + else + src.d_buf = &scn->s_shdr.s_shdr64; + + dst.d_size = fsz; + dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz; + + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, + ELF_TOFILE) == NULL) + return ((off_t) -1); + } + + return (ex->ex_start + nscn * fsz); +} + +/* + * Write out the file image. + * + * The original file could have been mapped in with an ELF_C_RDWR + * command and the application could have added new content or + * re-arranged its sections before calling elf_update(). Consequently + * its not safe to work `in place' on the original file. So we + * malloc() the required space for the updated ELF object and build + * the object there and write it out to the underlying file at the + * end. Note that the application may have opened the underlying file + * in ELF_C_RDWR and only retrieved/modified a few sections. We take + * care to avoid translating file sections unnecessarily. + * + * Gaps in the coverage of the file by the file's sections will be + * filled with the fill character set by elf_fill(3). + */ + +static off_t +_libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) +{ + off_t nrc, rc; + char *newfile; + Elf_Scn *scn, *tscn; + struct _Elf_Extent *ex; + + assert(e->e_kind == ELF_K_ELF); + assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); + assert(e->e_fd >= 0); + + if ((newfile = malloc((size_t) newsize)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return ((off_t) -1); + } + + nrc = rc = 0; + SLIST_FOREACH(ex, extents, ex_next) { + + /* Fill inter-extent gaps. */ + if (ex->ex_start > (size_t) rc) + (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), + ex->ex_start - rc); + + switch (ex->ex_type) { + case ELF_EXTENT_EHDR: + if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_PHDR: + if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_SECTION: + if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0) + goto error; + break; + + case ELF_EXTENT_SHDR: + if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0) + goto error; + break; + + default: + assert(0); + break; + } + + assert(ex->ex_start + ex->ex_size == (size_t) nrc); + assert(rc < nrc); + + rc = nrc; + } + + assert(rc == newsize); + + /* + * For regular files, throw away existing file content and + * unmap any existing mappings. + */ + if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) { + if (ftruncate(e->e_fd, (off_t) 0) < 0 || + lseek(e->e_fd, (off_t) 0, SEEK_SET)) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } +#if ELFTC_HAVE_MMAP + if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { + assert(e->e_rawfile != NULL); + assert(e->e_cmd == ELF_C_RDWR); + if (munmap(e->e_rawfile, e->e_rawsize) < 0) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + } +#endif + } + + /* + * Write out the new contents. + */ + if (write(e->e_fd, newfile, (size_t) newsize) != newsize) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + + /* + * For files opened in ELF_C_RDWR mode, set up the new 'raw' + * contents. + */ + if (e->e_cmd == ELF_C_RDWR) { + assert(e->e_rawfile != NULL); + assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) || + (e->e_flags & LIBELF_F_RAWFILE_MMAP)); + if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { + free(e->e_rawfile); + e->e_rawfile = newfile; + newfile = NULL; + } +#if ELFTC_HAVE_MMAP + else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { + if ((e->e_rawfile = mmap(NULL, (size_t) newsize, + PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) == + MAP_FAILED) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + } +#endif /* ELFTC_HAVE_MMAP */ + + /* Record the new size of the file. */ + e->e_rawsize = newsize; + } else { + /* File opened in ELF_C_WRITE mode. */ + assert(e->e_rawfile == NULL); + } + + /* + * Reset flags, remove existing section descriptors and + * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr() + * and elf_getscn() will function correctly. + */ + + e->e_flags &= ~ELF_F_DIRTY; + + STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn) + _libelf_release_scn(scn); + + if (e->e_class == ELFCLASS32) { + free(e->e_u.e_elf.e_ehdr.e_ehdr32); + if (e->e_u.e_elf.e_phdr.e_phdr32) + free(e->e_u.e_elf.e_phdr.e_phdr32); + + e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL; + e->e_u.e_elf.e_phdr.e_phdr32 = NULL; + } else { + free(e->e_u.e_elf.e_ehdr.e_ehdr64); + if (e->e_u.e_elf.e_phdr.e_phdr64) + free(e->e_u.e_elf.e_phdr.e_phdr64); + + e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL; + e->e_u.e_elf.e_phdr.e_phdr64 = NULL; + } + + /* Free the temporary buffer. */ + if (newfile) + free(newfile); + + return (rc); + + error: + free(newfile); + + return ((off_t) -1); +} + +/* + * Update an ELF object. + */ + +off_t +elf_update(Elf *e, Elf_Cmd c) +{ + int ec; + off_t rc; + struct _Elf_Extent_List extents; + + rc = (off_t) -1; + + if (e == NULL || e->e_kind != ELF_K_ELF || + (c != ELF_C_NULL && c != ELF_C_WRITE)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (rc); + } + + if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) { + LIBELF_SET_ERROR(CLASS, 0); + return (rc); + } + + if (e->e_version == EV_NONE) + e->e_version = EV_CURRENT; + + if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (rc); + } + + SLIST_INIT(&extents); + + if ((rc = _libelf_resync_elf(e, &extents)) < 0) + goto done; + + if (c == ELF_C_NULL) + goto done; + + if (e->e_fd < 0) { + rc = (off_t) -1; + LIBELF_SET_ERROR(SEQUENCE, 0); + goto done; + } + + rc = _libelf_write_elf(e, rc, &extents); + +done: + _libelf_release_extents(&extents); + return (rc); +} diff --git a/contrib/elftoolchain/libelf/elf_version.3 b/contrib/elftoolchain/libelf/elf_version.3 new file mode 100644 index 0000000..b09fb47 --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_version.3 @@ -0,0 +1,95 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: elf_version.3 2123 2011-11-09 15:40:09Z jkoshy $ +.\" +.Dd November 9, 2011 +.Os +.Dt ELF_VERSION 3 +.Sh NAME +.Nm elf_version +.Nd retrieve or set ELF library operating version +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft unsigned int +.Fn elf_version "unsigned int version" +.Sh DESCRIPTION +The +.Fn elf_version +function is used to query the current operating version of the ELF +library, and to inform the ELF library about the application's desired +operating version. +.Pp +If the argument +.Ar version +is +.Dv EV_NONE , +the +.Fn elf_version +function returns the currently configured operating version for the +ELF library. +.Pp +If the argument +.Ar version +is not +.Dv EV_NONE , +and if argument +.Ar version +is supported by the ELF library, function +.Fn elf_version +sets the library's operating version to +.Ar version , +and returns the previous value of the operating version. +If argument +.Ar version +cannot be supported, then the +.Fn elf_version +function returns +.Dv EV_NONE . +.Sh RETURN VALUES +The +.Fn elf_version +function returns the currently configured ELF library version, or +.Dv EV_NONE +if an unsupported version is requested. +.Sh EXAMPLES +An application program would inform the ELF library about its desired +operating version and check for an error using the following code +snippet: +.Bd -literal -offset indent +if (elf_version(EV_CURRENT) == EV_NONE) + err(EXIT_FAILURE, "ELF library too old"); +.Ed +.Sh ERRORS +Function +.Fn elf_version +may fail with the following error: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er "ELF_E_VERSION" +An unsupported library version number was requested. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/elf_version.c b/contrib/elftoolchain/libelf/elf_version.c new file mode 100644 index 0000000..3aa466a --- /dev/null +++ b/contrib/elftoolchain/libelf/elf_version.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: elf_version.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +unsigned int +elf_version(unsigned int v) +{ + unsigned int old; + + if ((old = LIBELF_PRIVATE(version)) == EV_NONE) + old = EV_CURRENT; + + if (v == EV_NONE) + return old; + if (v > EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return EV_NONE; + } + + LIBELF_PRIVATE(version) = v; + return (old); +} diff --git a/contrib/elftoolchain/libelf/gelf.3 b/contrib/elftoolchain/libelf/gelf.3 new file mode 100644 index 0000000..a5d68ce --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf.3 @@ -0,0 +1,201 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd September 1, 2006 +.Os +.Dt GELF 3 +.Sh NAME +.Nm GElf +.Nd class-independent API for ELF manipulation +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Sh DESCRIPTION +This manual page describes a class independent API for manipulating +ELF objects. +This API allows an application to operate on ELF descriptors without +needing to the know the ELF class of the descriptor. +.Pp +The GElf API may be used alongside the ELF API without restriction. +.Ss GElf Data Structures +The GElf API defines the following class-independent data structures: +.Bl -tag -width GElf_Sxword +.It Vt GElf_Addr +A representation of ELF addresses. +.It Vt GElf_Dyn +A class-independent representation of ELF +.Sy .dynamic +section entries. +.It Vt GElf_Ehdr +A class-independent representation of an ELF Executable Header. +.It Vt GElf_Half +An unsigned 16 bit quantity. +.It Vt GElf_Off +A class-independent representation of a ELF offset. +.It Vt GElf_Phdr +A class-independent representation of an ELF Program Header Table +entry. +.It Vt GElf_Rel +A class-independent representation of an ELF relocation entry. +.It Vt GElf_Rela +A class-independent representation of an ELF relocation entry with +addend. +.It Vt GElf_Shdr +A class-independent representation of an ELF Section Header Table +entry. +.It Vt GElf_Sword +A signed 32 bit quantity. +.It Vt GElf_Sxword +A signed 64 bit quantity. +.It Vt GElf_Sym +A class-independent representation of an ELF symbol table entry. +.It Vt GElf_Word +An unsigned 32 bit quantity. +.It Vt GElf_Xword +An unsigned 64 bit quantity. +.El +.Pp +These data structures are sized to be compatible with the +corresponding 64 bit ELF structures, and have the same internal +structure as their 64 bit class-dependent counterparts. +Class-dependent ELF structures are described in +.Xr elf 5 . +.Ss GElf Programming Model +GElf functions always return a +.Em copy +of the underlying (class-dependent) ELF data structure. +The programming model with GElf is as follows: +.Bl -enum +.It +An application will retrieve data from an ELF descriptor using a +.Fn gelf_get_* +function. +This will copy out data into a private +.Vt GElf_* +data structure. +.It +The application will work with its private copy of the GElf +structure. +.It +Once done, the application copies the new values back to the +underlying ELF data structure using the +.Fn gelf_update_* +functions. +.It +The application will then use the +.Fn elf_flag* +APIs to indicate to the ELF library that an ELF data structure is dirty. +.El +.Pp +When updating an underlying 32 bit ELF data structure, the GElf +routines will signal an error if a GElf value is out of range +for the underlying ELF data type. +.Ss Namespace use +The GElf interface uses the following symbols: +.Bl -tag +.It GElf_* +Class-independent data types. +.It gelf_* +For functions defined in the API set. +.El +.Ss GElf Programming APIs +This section provides an overview of the GElf programming APIs. +Further information is provided in the manual page of each function +listed here. +.Bl -tag +.It "Allocating ELF Data Structures" +.Bl -tag -compact +.It Fn gelf_newehdr +Allocate a new ELF Executable Header. +.It Fn gelf_newphdr +Allocate a new ELF Program Header Table. +.El +.It "Data Translation" +.Bl -tag -compact +.It Fn gelf_xlatetof +Translate the native representation of an ELF data structure to its +file representation. +.It Fn gelf_xlatetom +Translate from the file representation of an ELF data structure to a +native representation. +.El +.It "Retrieving ELF Data" +.Bl -tag -compact +.It Fn gelf_getdyn +Retrieve an ELF +.Sy .dynamic +table entry. +.It Fn gelf_getehdr +Retrieve an ELF Executable Header from the underlying ELF descriptor. +.It Fn gelf_getphdr +Retrieve an ELF Program Header Table entry from the underlying ELF descriptor. +.It Fn gelf_getrel +Retrieve an ELF relocation entry. +.It Fn gelf_getrela +Retrieve an ELF relocation entry with addend. +.It Fn gelf_getshdr +Retrieve an ELF Section Header Table entry from the underlying ELF descriptor. +.It Fn gelf_getsym +Retrieve an ELF symbol table entry. +.El +.It Queries +.Bl -tag -compact +.It Fn gelf_checksum +Retrieves the ELF checksum for an ELF descriptor. +.It Fn gelf_fsize +Retrieves the size of the file representation of an ELF type. +.It Fn gelf_getclass +Retrieves the ELF class of an ELF descriptor. +.El +.It "Updating ELF Data" +.Bl -tag -compact -width ".Fn gelf_update_shdr" +.It Fn gelf_update_dyn +Copy back an ELF +.Sy .dynamic +Table entry. +.It Fn gelf_update_phdr +Copy back an ELF Program Header Table entry. +.It Fn gelf_update_rel +Copy back an ELF relocation entry. +.It Fn gelf_update_rela +Copy back an ELF relocation with addend entry. +.It Fn gelf_update_shdr +Copy back an ELF Section Header Table entry. +.It Fn gelf_update_sym +Copy back an ELF symbol table entry. +.El +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf 5 +.Sh HISTORY +The GELF(3) API first appeared in System V Release 4. +This implementation of the API first appeared in +.Fx 7.0 . +.Sh AUTHORS +The GElf API was implemented by +.An "Joseph Koshy" +.Aq jkoshy@FreeBSD.org . diff --git a/contrib/elftoolchain/libelf/gelf.h b/contrib/elftoolchain/libelf/gelf.h new file mode 100644 index 0000000..0a7dc24 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf.h @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: gelf.h 1168 2010-09-04 01:03:25Z jkoshy $ + */ + +#ifndef _GELF_H_ +#define _GELF_H_ + +#include <sys/cdefs.h> + +#include <libelf.h> + +typedef Elf64_Addr GElf_Addr; /* Addresses */ +typedef Elf64_Half GElf_Half; /* Half words (16 bit) */ +typedef Elf64_Off GElf_Off; /* Offsets */ +typedef Elf64_Sword GElf_Sword; /* Signed words (32 bit) */ +typedef Elf64_Sxword GElf_Sxword; /* Signed long words (64 bit) */ +typedef Elf64_Word GElf_Word; /* Unsigned words (32 bit) */ +typedef Elf64_Xword GElf_Xword; /* Unsigned long words (64 bit) */ + +typedef Elf64_Dyn GElf_Dyn; /* ".dynamic" section entries */ +typedef Elf64_Ehdr GElf_Ehdr; /* ELF header */ +typedef Elf64_Phdr GElf_Phdr; /* Program header */ +typedef Elf64_Shdr GElf_Shdr; /* Section header */ +typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ +typedef Elf64_Rel GElf_Rel; /* Relocation entries */ +typedef Elf64_Rela GElf_Rela; /* Relocation entries with addend */ + +typedef Elf64_Cap GElf_Cap; /* SW/HW capabilities */ +typedef Elf64_Move GElf_Move; /* Move entries */ +typedef Elf64_Syminfo GElf_Syminfo; /* Symbol information */ + +#define GELF_M_INFO ELF64_M_INFO +#define GELF_M_SIZE ELF64_M_SIZE +#define GELF_M_SYM ELF64_M_SYM + +#define GELF_R_INFO ELF64_R_INFO +#define GELF_R_SYM ELF64_R_SYM +#define GELF_R_TYPE ELF64_R_TYPE +#define GELF_R_TYPE_DATA ELF64_R_TYPE_DATA +#define GELF_R_TYPE_ID ELF64_R_TYPE_ID +#define GELF_R_TYPE_INFO ELF64_R_TYPE_INFO + +#define GELF_ST_BIND ELF64_ST_BIND +#define GELF_ST_INFO ELF64_ST_INFO +#define GELF_ST_TYPE ELF64_ST_TYPE +#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY + +__BEGIN_DECLS +long gelf_checksum(Elf *_elf); +size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, + unsigned int _version); +int gelf_getclass(Elf *_elf); +GElf_Dyn *gelf_getdyn(Elf_Data *_data, int _index, GElf_Dyn *_dst); +GElf_Ehdr *gelf_getehdr(Elf *_elf, GElf_Ehdr *_dst); +GElf_Phdr *gelf_getphdr(Elf *_elf, int _index, GElf_Phdr *_dst); +GElf_Rel *gelf_getrel(Elf_Data *_src, int _index, GElf_Rel *_dst); +GElf_Rela *gelf_getrela(Elf_Data *_src, int _index, GElf_Rela *_dst); +GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); +GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); +GElf_Sym *gelf_getsymshndx(Elf_Data *_src, Elf_Data *_shindexsrc, + int _index, GElf_Sym *_dst, Elf32_Word *_shindexdst); +void * gelf_newehdr(Elf *_elf, int _class); +void * gelf_newphdr(Elf *_elf, size_t _phnum); +int gelf_update_dyn(Elf_Data *_dst, int _index, GElf_Dyn *_src); +int gelf_update_ehdr(Elf *_elf, GElf_Ehdr *_src); +int gelf_update_phdr(Elf *_elf, int _index, GElf_Phdr *_src); +int gelf_update_rel(Elf_Data *_dst, int _index, GElf_Rel *_src); +int gelf_update_rela(Elf_Data *_dst, int _index, GElf_Rela *_src); +int gelf_update_shdr(Elf_Scn *_dst, GElf_Shdr *_src); +int gelf_update_sym(Elf_Data *_dst, int _index, GElf_Sym *_src); +int gelf_update_symshndx(Elf_Data *_symdst, Elf_Data *_shindexdst, + int _index, GElf_Sym *_symsrc, Elf32_Word _shindexsrc); +Elf_Data *gelf_xlatetof(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); +Elf_Data *gelf_xlatetom(Elf *_elf, Elf_Data *_dst, const Elf_Data *_src, unsigned int _encode); + +GElf_Cap *gelf_getcap(Elf_Data *_data, int _index, GElf_Cap *_cap); +GElf_Move *gelf_getmove(Elf_Data *_src, int _index, GElf_Move *_dst); +GElf_Syminfo *gelf_getsyminfo(Elf_Data *_src, int _index, GElf_Syminfo *_dst); +int gelf_update_cap(Elf_Data *_dst, int _index, GElf_Cap *_src); +int gelf_update_move(Elf_Data *_dst, int _index, GElf_Move *_src); +int gelf_update_syminfo(Elf_Data *_dst, int _index, GElf_Syminfo *_src); +__END_DECLS + +#endif /* _GELF_H_ */ diff --git a/contrib/elftoolchain/libelf/gelf_cap.c b/contrib/elftoolchain/libelf/gelf_cap.c new file mode 100644 index 0000000..a1c1417 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_cap.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_cap.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Cap * +gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Cap *cap32; + Elf64_Cap *cap64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; + + dst->c_tag = cap32->c_tag; + dst->c_un.c_val = (Elf64_Xword) cap32->c_un.c_val; + + } else { + + cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; + + *dst = *cap64; + } + + return (dst); +} + +int +gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Cap *cap32; + Elf64_Cap *cap64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gc == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_CAP) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + cap32 = (Elf32_Cap *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(cap32, gc, c_tag); + LIBELF_COPY_U32(cap32, gc, c_un.c_val); + } else { + cap64 = (Elf64_Cap *) d->d_data.d_buf + ndx; + + *cap64 = *gc; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_checksum.3 b/contrib/elftoolchain/libelf/gelf_checksum.3 new file mode 100644 index 0000000..e5f845f --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_checksum.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_checksum.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_CHECKSUM 3 +.Sh NAME +.Nm elf32_checksum , +.Nm elf64_checksum , +.Nm gelf_checksum +.Nd return the checksum of an ELF object +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft long +.Fn elf32_checksum "Elf *elf" +.Ft long +.Fn elf64_checksum "Elf *elf" +.In gelf.h +.Ft long +.Fn gelf_checksum "Elf *elf" +.Sh DESCRIPTION +These functions return a simple checksum of the ELF object described +by their argument +.Ar elf . +The checksum is computed in way that allows its value to remain +unchanged in presence of modifications to the ELF object by utilities +like +.Xr strip 1 . +.Pp +Function +.Fn elf32_checksum +returns a checksum for an ELF descriptor +.Ar elf +of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_checksum +returns a checksum for an ELF descriptor +.Ar elf +of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_checksum +provides a class-independent way retrieving the checksum +for ELF object +.Ar elf . +.Sh RETURN VALUES +These functions return the checksum of the ELF object, or zero in case +an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +The ELF descriptor +.Ar elf +was not opened for reading or updating. +.It Bq Er ELF_E_CLASS +For functions +.Fn elf32_checksum +and +.Fn elf64_checksum , +ELF descriptor +.Ar elf +did not match the class of the called function. +.It Bq Er ELF_E_HEADER +The ELF object specified by argument +.Ar elf +had a malformed executable header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during processing. +.It Bq Er ELF_E_SECTION +The ELF object specified by argument +.Ar elf +contained a section with a malformed section header. +.It Bq Er ELF_E_VERSION +The ELF object was of an unsupported version. +.El +.Sh SEE ALSO +.Xr strip 1 , +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_checksum.c b/contrib/elftoolchain/libelf/gelf_checksum.c new file mode 100644 index 0000000..af707da --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_checksum.c @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +long +elf32_checksum(Elf *e) +{ + return (_libelf_checksum(e, ELFCLASS32)); +} + +long +elf64_checksum(Elf *e) +{ + return (_libelf_checksum(e, ELFCLASS64)); +} + +long +gelf_checksum(Elf *e) +{ + int ec; + if (e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0L); + } + return (_libelf_checksum(e, ec)); +} diff --git a/contrib/elftoolchain/libelf/gelf_dyn.c b/contrib/elftoolchain/libelf/gelf_dyn.c new file mode 100644 index 0000000..2631026 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_dyn.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_dyn.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Dyn * +gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Dyn *dyn32; + Elf64_Dyn *dyn64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; + + dst->d_tag = dyn32->d_tag; + dst->d_un.d_val = (Elf64_Xword) dyn32->d_un.d_val; + + } else { + + dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; + + *dst = *dyn64; + } + + return (dst); +} + +int +gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + Elf32_Dyn *dyn32; + Elf64_Dyn *dyn64; + uint32_t sh_type; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || ds == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_DYN) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + dyn32 = (Elf32_Dyn *) d->d_data.d_buf + ndx; + + LIBELF_COPY_S32(dyn32, ds, d_tag); + LIBELF_COPY_U32(dyn32, ds, d_un.d_val); + } else { + dyn64 = (Elf64_Dyn *) d->d_data.d_buf + ndx; + + *dyn64 = *ds; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_ehdr.c b/contrib/elftoolchain/libelf/gelf_ehdr.c new file mode 100644 index 0000000..1efd817 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_ehdr.c @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <libelf.h> +#include <limits.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_ehdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); + +Elf32_Ehdr * +elf32_getehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS32, 0)); +} + +Elf64_Ehdr * +elf64_getehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS64, 0)); +} + +GElf_Ehdr * +gelf_getehdr(Elf *e, GElf_Ehdr *d) +{ + int ec; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (d == NULL || e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL) + return (NULL); + + (void) memcpy(d->e_ident, eh32->e_ident, + sizeof(eh32->e_ident)); + d->e_type = eh32->e_type; + d->e_machine = eh32->e_machine; + d->e_version = eh32->e_version; + d->e_entry = eh32->e_entry; + d->e_phoff = eh32->e_phoff; + d->e_shoff = eh32->e_shoff; + d->e_flags = eh32->e_flags; + d->e_ehsize = eh32->e_ehsize; + d->e_phentsize = eh32->e_phentsize; + d->e_phnum = eh32->e_phnum; + d->e_shentsize = eh32->e_shentsize; + d->e_shnum = eh32->e_shnum; + d->e_shstrndx = eh32->e_shstrndx; + + return (d); + } + + assert(ec == ELFCLASS64); + + if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL) + return (NULL); + *d = *eh64; + + return (d); +} + +Elf32_Ehdr * +elf32_newehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS32, 1)); +} + +Elf64_Ehdr * +elf64_newehdr(Elf *e) +{ + return (_libelf_ehdr(e, ELFCLASS64, 1)); +} + +void * +gelf_newehdr(Elf *e, int ec) +{ + if (e != NULL && + (ec == ELFCLASS32 || ec == ELFCLASS64)) + return (_libelf_ehdr(e, ec, 1)); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +int +gelf_update_ehdr(Elf *e, GElf_Ehdr *s) +{ + int ec; + void *ehdr; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (0); + + (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + eh64 = (Elf64_Ehdr *) ehdr; + *eh64 = *s; + return (1); + } + + eh32 = (Elf32_Ehdr *) ehdr; + + (void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident)); + + eh32->e_type = s->e_type; + eh32->e_machine = s->e_machine; + eh32->e_version = s->e_version; + LIBELF_COPY_U32(eh32, s, e_entry); + LIBELF_COPY_U32(eh32, s, e_phoff); + LIBELF_COPY_U32(eh32, s, e_shoff); + eh32->e_flags = s->e_flags; + eh32->e_ehsize = s->e_ehsize; + eh32->e_phentsize = s->e_phentsize; + eh32->e_phnum = s->e_phnum; + eh32->e_shentsize = s->e_shentsize; + eh32->e_shnum = s->e_shnum; + eh32->e_shstrndx = s->e_shstrndx; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_fsize.3 b/contrib/elftoolchain/libelf/gelf_fsize.3 new file mode 100644 index 0000000..ac7996f --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_fsize.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_fsize.3 317 2009-03-06 17:29:22Z jkoshy $ +.\" +.Dd February 5, 2008 +.Os +.Dt GELF_FSIZE 3 +.Sh NAME +.Nm gelf_fsize , +.Nm elf32_fsize , +.Nm elf64_fsize +.Nd return the size of a file type +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft size_t +.Fn elf32_fsize "Elf_Type type" "size_t count" "unsigned int version" +.Ft size_t +.Fn elf64_fsize "Elf_Type type" "size_t count" "unsigned int version" +.In gelf.h +.Ft size_t +.Fn gelf_fsize "Elf *elf" "Elf_Type type" "size_t count" "unsigned int version" +.Sh DESCRIPTION +These functions return the size in bytes of the file representation of +.Ar count +numbers of objects of ELF type +.Ar type . +For ELF types that are of variable length, these functions return a +size of one byte. +.Pp +Functions +.Fn elf32_fsize +and +.Fn elf64_fsize +return sizes for files of class +.Dv ELFCLASS32 +and +.Dv ELFCLASS64 +respectively. +Function +.Fn gelf_fsize +returns the size for the class of ELF descriptor +.Ar elf . +.Sh RETURN VALUES +These functions return a non-zero value in case of success, or zero in +case of an error. +.Sh ERRORS +These functions may fail with: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL in a call to +.Fn gelf_fsize . +.It Bq Er ELF_E_ARGUMENT +ELF descriptor +.Ar elf +had an unknown ELF class. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar type +contained an illegal value. +.It Bq Er ELF_E_UNIMPL +Support for ELF type +.Ar type +has not been implemented. +.It Bq Er ELF_E_VERSION +Argument +.Ar version +is not a supported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_fsize.c b/contrib/elftoolchain/libelf/gelf_fsize.c new file mode 100644 index 0000000..7eeac69 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_fsize.c @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_fsize.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +size_t +elf32_fsize(Elf_Type t, size_t c, unsigned int v) +{ + return (_libelf_fsize(t, ELFCLASS32, v, c)); +} + +size_t +elf64_fsize(Elf_Type t, size_t c, unsigned int v) +{ + return (_libelf_fsize(t, ELFCLASS64, v, c)); +} + +size_t +gelf_fsize(Elf *e, Elf_Type t, size_t c, unsigned int v) +{ + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_class == ELFCLASS32 || e->e_class == ELFCLASS64) + return (_libelf_fsize(t, e->e_class, v, c)); + + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); +} diff --git a/contrib/elftoolchain/libelf/gelf_getcap.3 b/contrib/elftoolchain/libelf/gelf_getcap.3 new file mode 100644 index 0000000..ed8eb02 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getcap.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getcap.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETCAP 3 +.Sh NAME +.Nm gelf_getcap , +.Nm gelf_update_cap +.Nd read and update ELF capability information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Cap *" +.Fn gelf_getcap "Elf_Data *data" "int ndx" "GElf_Cap *cap" +.Ft int +.Fn gelf_update_cap "Elf_Data *data" "int ndx" "GElf_Cap *cap" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Cap +or +.Vt Elf64_Cap +information. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_cap . +Argument +.Ar ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Cap +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getcap +retrieves the class-dependent entry at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar cap +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_cap +converts the class-independent entry pointed to +by argument +.Ar cap +to class-dependent form, and writes it to the entry at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_cap +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getcap +returns the value of argument +.Ar cap +if successful, or NULL in case of an error. +Function +.Fn gelf_update_cap +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar cap +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section of type +.Dv SHT_SUNW_cap . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getclass.3 b/contrib/elftoolchain/libelf/gelf_getclass.3 new file mode 100644 index 0000000..3504569 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getclass.3 @@ -0,0 +1,61 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getclass.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd July 3, 2006 +.Os +.Dt GELF_GETCLASS 3 +.Sh NAME +.Nm gelf_getclass +.Nd retrieve the class of an ELF descriptor +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft int +.Fn gelf_getclass "Elf *elf" +.Sh DESCRIPTION +Function +.Fn gelf_getclass +returns the ELF class of the descriptor supplied in argument +.Ar elf . +.Sh RETURN VALUES +Function +.Fn gelf_getclass +will return one of +.Dv ELFCLASS32 +or +.Dv ELFCLASS64 +if the argument +.Ar elf +is a descriptor for an ELF file. +The value +.Dv ELFCLASSNONE +is returned if argument +.Ar elf +was null, or if it was not a descriptor for an ELF file. +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_kind 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getclass.c b/contrib/elftoolchain/libelf/gelf_getclass.c new file mode 100644 index 0000000..214e602 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getclass.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_getclass.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +int +gelf_getclass(Elf *e) +{ + return (e != NULL ? e->e_class : ELFCLASSNONE); +} diff --git a/contrib/elftoolchain/libelf/gelf_getdyn.3 b/contrib/elftoolchain/libelf/gelf_getdyn.3 new file mode 100644 index 0000000..f8c1778 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getdyn.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getdyn.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETDYN 3 +.Sh NAME +.Nm gelf_getdyn , +.Nm gelf_update_dyn +.Nd read and update ELF dynamic entries +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Dyn *" +.Fn gelf_getdyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" +.Ft int +.Fn gelf_update_dyn "Elf_Data *data" "int ndx" "GElf_Dyn *dyn" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Dyn +or +.Vt Elf64_Dyn +information in the +.Sy dynamic +table of an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_DYNAMIC . +Argument +.Ar ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Dyn +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getdyn +retrieves the class-dependent entry at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar dyn +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_dyn +converts the class-independent entry pointed to +by argument +.Ar dyn +to class-dependent form, and writes it to the entry at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_dyn +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getdyn +returns the value of argument +.Ar dyn +if successful, or NULL in case of an error. +Function +.Fn gelf_update_dyn +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar dyn +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section of type +.Dv SHT_DYNAMIC . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getehdr.3 b/contrib/elftoolchain/libelf/gelf_getehdr.3 new file mode 100644 index 0000000..56bdcd4 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getehdr.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getehdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd December 16, 2006 +.Os +.Dt GELF_GETEHDR 3 +.Sh NAME +.Nm elf32_getehdr , +.Nm elf64_getehdr , +.Nm gelf_getehdr +.Nd retrieve the object file header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Ehdr *" +.Fn elf32_getehdr "Elf *elf" +.Ft "Elf64_Ehdr *" +.Fn elf64_getehdr "Elf *elf" +.In gelf.h +.Ft "GElf_Ehdr *" +.Fn gelf_getehdr "Elf *elf" "GElf_Ehdr *dst" +.Sh DESCRIPTION +These functions retrieve the ELF object file +header from the ELF descriptor +.Ar elf +and return a translated header descriptor to their callers. +.Pp +Functions +.Fn elf32_getehdr +and +.Fn elf64_getehdr +return a pointer to the appropriate class-specific header descriptor +if it exists in the file referenced by descriptor +.Ar elf . +These functions return +.Dv NULL +if an ELF header was not found in file +.Ar elf . +.Pp +Function +.Fn gelf_getehdr +stores a translated copy of the header for ELF file +.Ar elf +into the descriptor pointed to by argument +.Ar dst . +It returns argument +.Ar dst +if successful or +.Dv NULL +in case of failure. +.Sh RETURN VALUES +These functions return a pointer to a translated header descriptor +if successful, or NULL on failure. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF file. +.It Bq Er ELF_E_ARGUMENT +The elf class of descriptor +.Ar elf +was not recognized. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar dst +was null. +.It Bq Er ELF_E_CLASS +The ELF class of descriptor +.Ar elf +did not match that of the API function being called. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Ar elf +does not have an associated header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during execution. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Ar elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_E_VERSION +The ELF descriptor +.Ar elf +had an unsupported ELF version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_newehdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf_flagehdr 3 , +.Xr elf_getident 3 , +.Xr gelf 3 , +.Xr gelf_newehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_getmove.3 b/contrib/elftoolchain/libelf/gelf_getmove.3 new file mode 100644 index 0000000..871a040 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getmove.3 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getmove.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETMOVE 3 +.Sh NAME +.Nm gelf_getmove , +.Nm gelf_update_move +.Nd read and update Elf Move information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Move *" +.Fn gelf_getmove "Elf_Data *data" "int ndx" "GElf_Move *move" +.Ft int +.Fn gelf_update_move "Elf_Data *data" "int ndx" "GElf_Move *move" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Move +and +.Vt Elf64_Move +structures in an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_move . +Argument +.Ar ndx +is the index of the move record being retrieved or updated. +The class-independent +.Vt GElf_Move +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getmove +retrieves class-dependent move record at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar move +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_move +converts the class-independent move information pointed to +by argument +.Ar move +to class-dependent form, and writes it to the move record at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_move +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getmove +returns the value of argument +.Ar move +if successful, or NULL in case of an error. +Function +.Fn gelf_update_move +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar move +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of records in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section containing move information. +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getphdr.3 b/contrib/elftoolchain/libelf/gelf_getphdr.3 new file mode 100644 index 0000000..f2d38aa --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getphdr.3 @@ -0,0 +1,141 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getphdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd October 21, 2007 +.Os +.Dt GELF_GETPHDR 3 +.Sh NAME +.Nm elf32_getphdr , +.Nm elf64_getphdr , +.Nm gelf_getphdr +.Nd retrieve an ELF program header table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Phdr *" +.Fn elf32_getphdr "Elf *elf" +.Ft "Elf64_Phdr *" +.Fn elf64_getphdr "Elf *elf" +.In gelf.h +.Ft "GElf_Phdr *" +.Fn gelf_getphdr "Elf *elf" "int index" "GElf_Phdr *dst" +.Sh DESCRIPTION +These functions retrieve and translate ELF program header information +from an ELF descriptor, if this information exists. +.Pp +Functions +.Fn elf32_getphdr +and +.Fn elf64_getphdr +return a pointer to an array of translated +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors respectively. +These descriptors are described in +.Xr elf 5 . +The number of entries in this array may be determined using the +.Xr elf_getphnum 3 +function. +.Pp +Function +.Fn gelf_getphdr +will retrieve the program header table entry at index +.Ar index +from ELF descriptor +.Ar elf. +The translated program header table entry will be written to the +address pointed to be argument +.Ar dst . +.Pp +Applications may inform the library of modifications to a program header table entry +by using the +.Xr elf_flagphdr 3 +API. +Applications using the +.Xr gelf 3 +interface need to use the +.Xr gelf_update_phdr 3 +API to copy modifications to a program header entry back to the underlying +ELF descriptor. +.Sh RETURN VALUES +The functions a valid pointer if successful, or NULL in case an error +was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar dst +was NULL. +.It Bq Er ELF_E_ARGUMENT +Index +.Ar index +was out of range. +.It Bq Er ELF_E_CLASS +The class of ELF descriptor +.Ar elf +did not match the expected class of the function being called. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Ar elf +did not possess an executable header. +.It Bq Er ELF_E_HEADER +ELF descriptor +.Ar elf +had a corrupt executable header. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Ar elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_VERSION +ELF descriptor +.Ar elf +was of an unsupported version. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf32_newphdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf64_newphdr 3 , +.Xr elf_flagphdr 3 , +.Xr elf_getphnum 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr gelf_newphdr 3 , +.Xr gelf_update_phdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_getrel.3 b/contrib/elftoolchain/libelf/gelf_getrel.3 new file mode 100644 index 0000000..c7566e6 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getrel.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getrel.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETREL 3 +.Sh NAME +.Nm gelf_getrel , +.Nm gelf_update_rel +.Nd read and update ELF relocation entries +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Rel *" +.Fn gelf_getrel "Elf_Data *data" "int ndx" "GElf_Rel *rel" +.Ft int +.Fn gelf_update_rel "Elf_Data *data" "int ndx" "GElf_Rel *rel" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Rel +or +.Vt Elf64_Rel +structures in an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_REL . +Argument +.Ar ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Rel +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getrel +retrieves the class-dependent entry at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar rel +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_rel +converts the class-independent entry pointed to +by argument +.Ar rel +to class-dependent form, and writes it to the entry at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_rel +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getrel +returns the value of argument +.Ar rel +if successful, or NULL in case of an error. +Function +.Fn gelf_update_rel +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar rel +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section of type +.Dv SHT_REL . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getrela.3 b/contrib/elftoolchain/libelf/gelf_getrela.3 new file mode 100644 index 0000000..c77d52a --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getrela.3 @@ -0,0 +1,121 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getrela.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETRELA 3 +.Sh NAME +.Nm gelf_getrela , +.Nm gelf_update_rela +.Nd read and update ELF relocation entries with addends +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Rela *" +.Fn gelf_getrela "Elf_Data *data" "int ndx" "GElf_Rela *rela" +.Ft int +.Fn gelf_update_rela "Elf_Data *data" "int ndx" "GElf_Rela *rela" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Rela +or +.Vt Elf64_Rela +structures in an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_RELA . +Argument +.Ar ndx +is the index of the entry being retrieved or updated. +The class-independent +.Vt GElf_Rela +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getrela +retrieves the class-dependent entry at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar rela +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_rela +converts the class-independent entry pointed to +by argument +.Ar rela +to class-dependent form, and writes it to the entry at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_rela +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getrela +returns the value of argument +.Ar rela +if successful, or NULL in case of an error. +Function +.Fn gelf_update_rela +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar rela +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of entries in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section of type +.Dv SHT_RELA . +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/gelf_getshdr.3 b/contrib/elftoolchain/libelf/gelf_getshdr.3 new file mode 100644 index 0000000..e92d414 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getshdr.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getshdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 27, 2006 +.Os +.Dt GELF_GETSHDR 3 +.Sh NAME +.Nm elf32_getshdr , +.Nm elf64_getshdr , +.Nm gelf_getshdr +.Nd retrieve the class-dependent section header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Shdr *" +.Fn elf32_getshdr "Elf_Scn *scn" +.Ft "Elf64_Shdr *" +.Fn elf64_getshdr "Elf_Scn *scn" +.In gelf.h +.Ft "GElf_Shdr *" +.Fn gelf_getshdr "Elf_Scn *scn" "GElf_Shdr *shdr" +.Sh DESCRIPTION +These functions return a pointer to the ELF Section Header data +structure associated with section descriptor +.Ar scn . +.Pp +Function +.Fn elf32_getshdr +retrieves a pointer to an +.Vt Elf32_Shdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_getshdr +retrieves a pointer to an +.Vt Elf64_Shdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_getshdr +copies the values in the section header associated with argument +.Ar scn +to the structure pointed to be argument +.Ar dst . +The +.Vt GElf_Shdr +data structure is described in +.Xr gelf 3 . +.Sh RETURN VALUES +Functions +.Fn elf32_getshdr +and +.Fn elf64_getshdr +return a valid pointer to the appropriate section header on success +or NULL if an error was encountered. +.Pp +Function +.Fn gelf_getshdr +returns argument +.Ar dst +if successful, or NULL if an error was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar scn +or +.Ar shdr +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar scn +was not associated a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +The ELF class associated with the section descriptor +.Ar scn +did not match the class expected by the API. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_update_shdr 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsym.3 b/contrib/elftoolchain/libelf/gelf_getsym.3 new file mode 100644 index 0000000..98d886f --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsym.3 @@ -0,0 +1,125 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getsym.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETSYM 3 +.Sh NAME +.Nm gelf_getsym , +.Nm gelf_update_sym +.Nd read and update symbol information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Sym *" +.Fn gelf_getsym "Elf_Data *data" "int ndx" "GElf_Sym *sym" +.Ft int +.Fn gelf_update_sym "Elf_Data *data" "int ndx" "GElf_Sym *sym" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Sym +and +.Vt Elf64_Sym +structures in an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB , +.Dv SHT_DYNSYM +or +.Dv SHT_GNU_versym . +Argument +.Ar ndx +is the index of the symbol being retrieved or updated. +The class-independent +.Vt GElf_Sym +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsym +retrieves class-dependent symbol information at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar sym +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_sym +converts the class-independent symbol information pointed to +by argument +.Ar sym +to class-dependent form, and writes it to the symbol entry at index +.Ar ndx +in the data buffer described by argument +.Ar data . +Function +.Fn gelf_update_sym +signals an error if any of the values in the class-independent +representation exceeds the representable limits of the target +type. +.Sh RETURN VALUES +Function +.Fn gelf_getsym +returns the value of argument +.Ar sym +if successful, or NULL in case of an error. +Function +.Fn gelf_update_sym +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar sym +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of symbols in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section containing symbol information. +.It Bq Er ELF_E_RANGE +A value was not representable in the target type. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsyminfo 3 , +.Xr gelf_update_syminfo 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsyminfo.3 b/contrib/elftoolchain/libelf/gelf_getsyminfo.3 new file mode 100644 index 0000000..a1169f8 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsyminfo.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getsyminfo.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 29, 2006 +.Os +.Dt GELF_GETSYMINFO 3 +.Sh NAME +.Nm gelf_getsyminfo , +.Nm gelf_update_syminfo +.Nd read and update symbol information +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Syminfo *" +.Fn gelf_getsyminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" +.Ft int +.Fn gelf_update_syminfo "Elf_Data *data" "int ndx" "GElf_Syminfo *syminfo" +.Sh DESCRIPTION +These convenience functions are used to retrieve and update class-dependent +.Vt Elf32_Syminfo +and +.Vt Elf64_Syminfo +records in an ELF object. +.Pp +Argument +.Ar data +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SUNW_syminfo . +Argument +.Ar ndx +is the index of the record being retrieved or updated. +The class-independent +.Vt GElf_Syminfo +structure is described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsyminfo +retrieves class-dependent record at index +.Ar ndx +in data buffer +.Ar data +and copies it to the destination pointed to by argument +.Ar syminfo +after translation to class-independent form. +.Pp +Function +.Fn gelf_update_syminfo +converts the class-independent record pointed to +by argument +.Ar syminfo +to class-dependent form, and writes it to the record at index +.Ar ndx +in the data buffer described by argument +.Ar data . +.Sh RETURN VALUES +Function +.Fn gelf_getsyminfo +returns the value of argument +.Ar syminfo +if successful, or NULL in case of an error. +Function +.Fn gelf_update_syminfo +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar data +or +.Ar syminfo +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero or larger than the number of symbols in the data +descriptor. +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar data +was not associated with a section containing symbol information. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsym 3 , +.Xr gelf_update_sym 3 diff --git a/contrib/elftoolchain/libelf/gelf_getsymshndx.3 b/contrib/elftoolchain/libelf/gelf_getsymshndx.3 new file mode 100644 index 0000000..b635aac --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_getsymshndx.3 @@ -0,0 +1,162 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_getsymshndx.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd November 5, 2006 +.Os +.Dt GELF_GETSYMSHNDX 3 +.Sh NAME +.Nm gelf_getsymshndx , +.Nm gelf_update_symshndx +.Nd read and update symbol information using extended section indices +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft "GElf_Sym *" +.Fo gelf_getsymshndx +.Fa "Elf_Data *symdata" +.Fa "Elf_Data *xndxdata" +.Fa "int ndx" +.Fa "GElf_Sym *sym" +.Fa "Elf32_Word *xndxptr" +.Fc +.Ft int +.Fo gelf_update_symshndx +.Fa "Elf_Data *symdata" +.Fa "Elf_Data *xndxdata" +.Fa "int ndx" +.Fa "GElf_Sym *sym" +.Fa "Elf32_Word xndx" +.Fc +.Sh DESCRIPTION +These functions are analogous to +.Fn gelf_getsym +and +.Fn gelf_update_sym +respectively, but are capable of handling symbol tables using extended +section numbering. +.Pp +Argument +.Ar symdata +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB . +Argument +.Ar xndxdata +is an +.Vt Elf_Data +descriptor associated with a section of type +.Dv SHT_SYMTAB_SHNDX . +Argument +.Ar ndx +is the index of the symbol table entry being retrieved or updated. +Argument +.Ar sym +is a pointer to a class-independent +.Vt GElf_Sym +structure. +.Vt GElf_Sym +structures are described in detail in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_getsymshndx +retrieves symbol information at index +.Ar ndx +from the data descriptor specified by argument +.Ar symdata +and stores in class-independent form in argument +.Ar sym . +In addition it retrieves the extended section index for the +symbol from data buffer +.Ar xndxdata +and stores it into the location pointed to by argument +.Ar xndxptr . +.Pp +Function +.Fn gelf_update_symshndx +updates the underlying symbol table entry in data +descriptor +.Ar symdata +with the information in argument +.Ar sym . +In addition it sets the extended section index in +data buffer +.Ar xndxdata +to the value of argument +.Ar xndx . +.Sh RETURN VALUES +Function +.Fn gelf_getsymshndx +returns the value of argument +.Ar sym +if successful, or NULL in case of an error. +.Pp +Function +.Fn gelf_update_symshndx +returns a non-zero value if successful, or zero in case of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar symdata , +.Ar xndxdata , +.Ar xndxptr +or +.Ar sym +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +was less than zero, or too large for either of descriptors +.Ar symdata +or +.Ar xndxdata . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar symdata +was not associated with a section of type +.Dv SHT_SYMTAB . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar xndxdata +was not associated with a section of type +.Dv SHT_SYMTAB_SHNDX . +.It Bq Er ELF_E_ARGUMENT +Data descriptor +.Ar symdata +and +.Ar xndxdata +were associated with different ELF objects. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , +.Xr gelf_getsym 3 , +.Xr gelf_update_sym 3 diff --git a/contrib/elftoolchain/libelf/gelf_move.c b/contrib/elftoolchain/libelf/gelf_move.c new file mode 100644 index 0000000..d9e8993 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_move.c @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_move.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Move * +gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Move *move32; + Elf64_Move *move64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + move32 = (Elf32_Move *) d->d_data.d_buf + ndx; + + dst->m_value = move32->m_value; + dst->m_info = (Elf64_Xword) move32->m_info; + dst->m_poffset = (Elf64_Xword) move32->m_poffset; + dst->m_repeat = move32->m_repeat; + dst->m_stride = move32->m_stride; + } else { + + move64 = (Elf64_Move *) d->d_data.d_buf + ndx; + + *dst = *move64; + } + + return (dst); +} + +int +gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Move *move32; + Elf64_Move *move64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gm == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_MOVE) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + move32 = (Elf32_Move *) d->d_data.d_buf + ndx; + + move32->m_value = gm->m_value; + LIBELF_COPY_U32(move32, gm, m_info); + LIBELF_COPY_U32(move32, gm, m_poffset); + move32->m_repeat = gm->m_repeat; + move32->m_stride = gm->m_stride; + + } else { + move64 = (Elf64_Move *) d->d_data.d_buf + ndx; + + *move64 = *gm; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_newehdr.3 b/contrib/elftoolchain/libelf/gelf_newehdr.3 new file mode 100644 index 0000000..180fea9 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_newehdr.3 @@ -0,0 +1,185 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_newehdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd October 22, 2007 +.Os +.Dt GELF_NEWEHDR 3 +.Sh NAME +.Nm elf32_newehdr , +.Nm elf64_newehdr , +.Nm gelf_newehdr +.Nd retrieve or allocate the object file header +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Ehdr *" +.Fn elf32_newehdr "Elf *elf" +.Ft "Elf64_Ehdr *" +.Fn elf64_newehdr "Elf *elf" +.In gelf.h +.Ft "void *" +.Fn gelf_newehdr "Elf *elf" "int elfclass" +.Sh DESCRIPTION +These functions retrieve the ELF header from the ELF descriptor +.Ar elf , +allocating a new header if needed. +File data structures are translated to their in-memory representations +as described in +.Xr elf 3 . +.Pp +Function +.Fn elf32_newehdr +returns a pointer to a 32 bit +.Vt Elf32_Ehdr +structure. +Function +.Fn elf64_newehdr +returns a pointer to a 64 bit +.Vt Elf64_Ehdr structure. +.Pp +When argument +.Ar elfclass +has value +.Dv ELFCLASS32 , +function +.Fn gelf_newehdr +returns the value returned by +.Fn elf32_newehdr "elf" . +When argument +.Ar elfclass +has value +.Dv ELFCLASS64 +it returns the value returned by +.Fn elf64_newehdr "elf" . +.Pp +If a fresh header structure is allocated, the members of the +structure are initialized as follows: +.Bl -tag -width indent +.It Va "e_ident[EI_MAG0..EI_MAG3]" +Identification bytes at offsets +.Dv EI_MAG0 , +.Dv EI_MAG1 , +.Dv EI_MAG2 +and +.Dv EI_MAG3 +are set to the ELF signature. +.It Va "e_ident[EI_CLASS]" +The identification byte at offset +.Dv EI_CLASS +is set to the ELF class associated with the function being called +or to argument +.Ar elfclass +for function +.Fn gelf_newehdr . +.It Va "e_ident[EI_DATA]" +The identification byte at offset +.Dv EI_DATA +is set to +.Dv ELFDATANONE . +.It Va "e_ident[EI_VERSION]" +The identification byte at offset +.Dv EI_VERSION +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . +.It Va e_machine +is set to +.Dv EM_NONE . +.It Va e_type +is set to +.Dv ELF_K_NONE . +.It Va e_version +is set to the ELF library's operating version set by a prior call to +.Xr elf_version 3 . +.El +.Pp +Other members of the header are set to zero. +The application is responsible for changing these values +as needed before calling +.Fn elf_update . +.Pp +If successful, these three functions set the +.Dv ELF_F_DIRTY +flag on ELF descriptor +.Ar elf . +.Sh RETURN VALUES +These functions return a pointer to a translated header descriptor +if successful, or NULL on failure. +.Sh ERRORS +These functions can fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +The argument +.Ar elf +was null. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elfclass +had an unsupported value. +.It Bq Er ELF_E_ARGUMENT +The class of the ELF descriptor +.Ar elf +did not match that of the requested operation. +.It Bq Er ELF_E_ARGUMENT +For function +.Fn gelf_newehdr , +the class of argument +.Ar elf +was not +.Dv ELFCLASSNONE +and did not match the argument +.Ar elfclass . +.It Bq Er ELF_E_CLASS +The ELF class of descriptor +.Ar elf +did not match that of the API function being called. +.It Bq Er ELF_E_HEADER +A malformed ELF header was detected. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected during execution. +.It Bq Er ELF_E_SECTION +The ELF descriptor in argument +.Ar elf +did not adhere to the conventions used for extended numbering. +.It Bq Er ELF_E_VERSION +The ELF descriptor +.Ar elf +had an unsupported ELF version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getehdr 3 , +.Xr elf64_getehdr 3 , +.Xr elf_flagdata 3 , +.Xr elf_getident 3 , +.Xr elf_update 3 , +.Xr elf_version 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_newphdr.3 b/contrib/elftoolchain/libelf/gelf_newphdr.3 new file mode 100644 index 0000000..931385e --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_newphdr.3 @@ -0,0 +1,133 @@ +.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_newphdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd October 22, 2007 +.Os +.Dt GELF_NEWPHDR 3 +.Sh NAME +.Nm elf32_newphdr , +.Nm elf64_newphdr , +.Nm gelf_newphdr +.Nd allocate an ELF program header table +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Phdr *" +.Fn elf32_newphdr "Elf *elf" "size_t count" +.Ft "Elf64_Phdr *" +.Fn elf64_newphdr "Elf *elf" "size_t count" +.In gelf.h +.Ft "void *" +.Fn gelf_newphdr "Elf *elf" "size_t count" +.Sh DESCRIPTION +These functions allocate an ELF Program Header table +for an ELF descriptor. +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors are described further in +.Xr elf 5 . +.Pp +Functions +.Fn elf32_newphdr +and +.Fn elf64_newphdr +allocate a table of +.Ar count +.Vt Elf32_Phdr +and +.Vt Elf64_Phdr +descriptors respectively, +discarding any existing program header table +already present in the ELF descriptor +.Ar elf . +A value of zero for argument +.Ar count +may be used to delete an existing program header table +from an ELF descriptor. +.Pp +Function +.Fn gelf_newphdr +will return a table of +.Vt Elf32_Phdr +or +.Vt Elf64_Phdr +with +.Ar count +elements depending on the ELF class of ELF descriptor +.Ar elf . +.Pp +The functions set the +.Dv ELF_F_DIRTY +flag on the program header table. +All members of the returned array of Phdr structures +will be initialized to zero. +.Pp +After a successful call to these functions, the pointer returned +by a prior call to +.Fn elf32_getphdr +or +.Fn elf64_getphdr +on the same descriptor +.Ar elf +will no longer be valid. +.Sh RETURN VALUES +The functions a valid pointer if successful, or NULL in case an error +was encountered. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_CLASS +ELF descriptor +.Ar elf +was of an unrecognized class. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.It Bq Er ELF_E_SEQUENCE +An executable header was not allocated for ELF descriptor +.Ar elf +before using these APIs. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf32_getphdr 3 , +.Xr elf32_newehdr 3 , +.Xr elf64_getphdr 3 , +.Xr elf64_newehdr 3 , +.Xr elf_flagphdr 3 , +.Xr elf_getphnum 3 , +.Xr gelf 3 , +.Xr gelf_getphdr 3 , +.Xr gelf_newehdr 3 , +.Xr elf 5 diff --git a/contrib/elftoolchain/libelf/gelf_phdr.c b/contrib/elftoolchain/libelf/gelf_phdr.c new file mode 100644 index 0000000..ade82db --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_phdr.c @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> +#include <libelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_phdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); + +Elf32_Phdr * +elf32_getphdr(Elf *e) +{ + return (_libelf_getphdr(e, ELFCLASS32)); +} + +Elf64_Phdr * +elf64_getphdr(Elf *e) +{ + return (_libelf_getphdr(e, ELFCLASS64)); +} + +GElf_Phdr * +gelf_getphdr(Elf *e, int index, GElf_Phdr *d) +{ + int ec; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + Elf32_Phdr *ep32; + Elf64_Phdr *ep64; + + if (d == NULL || e == NULL || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) || + (e->e_kind != ELF_K_ELF) || index < 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL || + ((ep32 = _libelf_getphdr(e, ELFCLASS32)) == NULL)) + return (NULL); + + if (index >= eh32->e_phnum) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ep32 += index; + + d->p_type = ep32->p_type; + d->p_offset = ep32->p_offset; + d->p_vaddr = (Elf64_Addr) ep32->p_vaddr; + d->p_paddr = (Elf64_Addr) ep32->p_paddr; + d->p_filesz = (Elf64_Xword) ep32->p_filesz; + d->p_memsz = (Elf64_Xword) ep32->p_memsz; + d->p_flags = ep32->p_flags; + d->p_align = (Elf64_Xword) ep32->p_align; + + } else { + if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL || + (ep64 = _libelf_getphdr(e, ELFCLASS64)) == NULL) + return (NULL); + + if (index >= eh64->e_phnum) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ep64 += index; + + *d = *ep64; + } + + return (d); +} + +Elf32_Phdr * +elf32_newphdr(Elf *e, size_t count) +{ + return (_libelf_newphdr(e, ELFCLASS32, count)); +} + +Elf64_Phdr * +elf64_newphdr(Elf *e, size_t count) +{ + return (_libelf_newphdr(e, ELFCLASS64, count)); +} + +void * +gelf_newphdr(Elf *e, size_t count) +{ + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + return (_libelf_newphdr(e, e->e_class, count)); +} + +int +gelf_update_phdr(Elf *e, int ndx, GElf_Phdr *s) +{ + int ec, phnum; + void *ehdr; + Elf32_Phdr *ph32; + Elf64_Phdr *ph64; + + if (s == NULL || e == NULL || e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (0); + + if (ec == ELFCLASS32) + phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; + else + phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; + + if (ndx < 0 || ndx > phnum) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + (void) elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + ph64 = e->e_u.e_elf.e_phdr.e_phdr64 + ndx; + *ph64 = *s; + return (1); + } + + ph32 = e->e_u.e_elf.e_phdr.e_phdr32 + ndx; + + ph32->p_type = s->p_type; + ph32->p_flags = s->p_flags; + LIBELF_COPY_U32(ph32, s, p_offset); + LIBELF_COPY_U32(ph32, s, p_vaddr); + LIBELF_COPY_U32(ph32, s, p_paddr); + LIBELF_COPY_U32(ph32, s, p_filesz); + LIBELF_COPY_U32(ph32, s, p_memsz); + LIBELF_COPY_U32(ph32, s, p_align); + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_rel.c b/contrib/elftoolchain/libelf/gelf_rel.c new file mode 100644 index 0000000..eb05717 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_rel.c @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_rel.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Rel * +gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rel *rel32; + Elf64_Rel *rel64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_REL, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; + + dst->r_offset = (Elf64_Addr) rel32->r_offset; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rel32->r_info), + ELF32_R_TYPE(rel32->r_info)); + + } else { + + rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; + + *dst = *rel64; + } + + return (dst); +} + +int +gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rel *rel32; + Elf64_Rel *rel64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dr == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_REL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_REL, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(rel32, dr, r_offset); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), + ELF64_R_TYPE(dr->r_info)); + } else { + rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; + + *rel64 = *dr; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_rela.c b/contrib/elftoolchain/libelf/gelf_rela.c new file mode 100644 index 0000000..cb61bdc --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_rela.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_rela.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Rela * +gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rela *rela32; + Elf64_Rela *rela64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; + + dst->r_offset = (Elf64_Addr) rela32->r_offset; + dst->r_info = ELF64_R_INFO( + (Elf64_Xword) ELF32_R_SYM(rela32->r_info), + ELF32_R_TYPE(rela32->r_info)); + dst->r_addend = (Elf64_Sxword) rela32->r_addend; + + } else { + + rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; + + *dst = *rela64; + } + + return (dst); +} + +int +gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Rela *rela32; + Elf64_Rela *rela64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dr == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_RELA) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; + + LIBELF_COPY_U32(rela32, dr, r_offset); + + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { + LIBELF_SET_ERROR(RANGE, 0); + return (0); + } + rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info), + ELF64_R_TYPE(dr->r_info)); + + LIBELF_COPY_S32(rela32, dr, r_addend); + } else { + rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; + + *rela64 = *dr; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_shdr.c b/contrib/elftoolchain/libelf/gelf_shdr.c new file mode 100644 index 0000000..d402489 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_shdr.c @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <libelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_shdr.c 2268 2011-12-03 17:05:11Z jkoshy $"); + +Elf32_Shdr * +elf32_getshdr(Elf_Scn *s) +{ + return (_libelf_getshdr(s, ELFCLASS32)); +} + +Elf64_Shdr * +elf64_getshdr(Elf_Scn *s) +{ + return (_libelf_getshdr(s, ELFCLASS64)); +} + +GElf_Shdr * +gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) +{ + int ec; + void *sh; + Elf32_Shdr *sh32; + Elf64_Shdr *sh64; + + if (d == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) + return (NULL); + + ec = s->s_elf->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) { + sh32 = (Elf32_Shdr *) sh; + + d->sh_name = sh32->sh_name; + d->sh_type = sh32->sh_type; + d->sh_flags = (Elf64_Xword) sh32->sh_flags; + d->sh_addr = (Elf64_Addr) sh32->sh_addr; + d->sh_offset = (Elf64_Off) sh32->sh_offset; + d->sh_size = (Elf64_Xword) sh32->sh_size; + d->sh_link = sh32->sh_link; + d->sh_info = sh32->sh_info; + d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; + d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; + } else { + sh64 = (Elf64_Shdr *) sh; + *d = *sh64; + } + + return (d); +} + +int +gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *s) +{ + int ec; + Elf *e; + Elf32_Shdr *sh32; + + + if (s == NULL || scn == NULL || (e = scn->s_elf) == NULL || + e->e_kind != ELF_K_ELF || + ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (e->e_cmd == ELF_C_READ) { + LIBELF_SET_ERROR(MODE, 0); + return (0); + } + + (void) elf_flagscn(scn, ELF_C_SET, ELF_F_DIRTY); + + if (ec == ELFCLASS64) { + scn->s_shdr.s_shdr64 = *s; + return (1); + } + + sh32 = &scn->s_shdr.s_shdr32; + + sh32->sh_name = s->sh_name; + sh32->sh_type = s->sh_type; + LIBELF_COPY_U32(sh32, s, sh_flags); + LIBELF_COPY_U32(sh32, s, sh_addr); + LIBELF_COPY_U32(sh32, s, sh_offset); + LIBELF_COPY_U32(sh32, s, sh_size); + sh32->sh_link = s->sh_link; + sh32->sh_info = s->sh_info; + LIBELF_COPY_U32(sh32, s, sh_addralign); + LIBELF_COPY_U32(sh32, s, sh_entsize); + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_sym.c b/contrib/elftoolchain/libelf/gelf_sym.c new file mode 100644 index 0000000..4a490d9 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_sym.c @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <limits.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_sym.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Sym * +gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Sym *sym32; + Elf64_Sym *sym64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; + + dst->st_name = sym32->st_name; + dst->st_value = (Elf64_Addr) sym32->st_value; + dst->st_size = (Elf64_Xword) sym32->st_size; + dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info), + ELF32_ST_TYPE(sym32->st_info)); + dst->st_other = sym32->st_other; + dst->st_shndx = sym32->st_shndx; + } else { + + sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; + + *dst = *sym64; + } + + return (dst); +} + +int +gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + Elf32_Sym *sym32; + Elf64_Sym *sym64; + struct _Libelf_Data *d; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gs == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; + + sym32->st_name = gs->st_name; + sym32->st_info = gs->st_info; + sym32->st_other = gs->st_other; + sym32->st_shndx = gs->st_shndx; + + LIBELF_COPY_U32(sym32, gs, st_value); + LIBELF_COPY_U32(sym32, gs, st_size); + } else { + sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; + + *sym64 = *gs; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_syminfo.c b/contrib/elftoolchain/libelf/gelf_syminfo.c new file mode 100644 index 0000000..bb2063d --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_syminfo.c @@ -0,0 +1,151 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_syminfo.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +GElf_Syminfo * +gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *d; + Elf32_Syminfo *syminfo32; + Elf64_Syminfo *syminfo64; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || dst == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + + syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; + + dst->si_boundto = syminfo32->si_boundto; + dst->si_flags = syminfo32->si_flags; + + } else { + + syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; + + *dst = *syminfo64; + } + + return (dst); +} + +int +gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *d; + Elf32_Syminfo *syminfo32; + Elf64_Syminfo *syminfo64; + + d = (struct _Libelf_Data *) ed; + + if (d == NULL || ndx < 0 || gs == NULL || + (scn = d->d_scn) == NULL || + (e = scn->s_elf) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_SYMINFO) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= d->d_data.d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + if (ec == ELFCLASS32) { + syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; + + syminfo32->si_boundto = gs->si_boundto; + syminfo32->si_flags = gs->si_flags; + + } else { + syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; + + *syminfo64 = *gs; + } + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_symshndx.c b/contrib/elftoolchain/libelf/gelf_symshndx.c new file mode 100644 index 0000000..9cf3b75 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_symshndx.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_symshndx.c 2283 2011-12-04 04:07:24Z jkoshy $"); + +GElf_Sym * +gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, + Elf32_Word *shindex) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *ld, *lid; + + ld = (struct _Libelf_Data *) d; + lid = (struct _Libelf_Data *) id; + + if (gelf_getsym(d, ndx, dst) == 0) + return (NULL); + + if (lid == NULL || (scn = lid->d_scn) == NULL || + (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf) || + shindex == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || + id->d_type != ELF_T_WORD) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); + + assert(msz > 0); + + if (msz * ndx >= id->d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + *shindex = ((Elf32_Word *) id->d_buf)[ndx]; + + return (dst); +} + +int +gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, + Elf32_Word xindex) +{ + int ec; + Elf *e; + size_t msz; + Elf_Scn *scn; + uint32_t sh_type; + struct _Libelf_Data *ld, *lid; + + ld = (struct _Libelf_Data *) d; + lid = (struct _Libelf_Data *) id; + + if (gelf_update_sym(d, ndx, gs) == 0) + return (0); + + if (lid == NULL || (scn = lid->d_scn) == NULL || + (e = scn->s_elf) == NULL || (e != ld->d_scn->s_elf)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + ec = e->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) + sh_type = scn->s_shdr.s_shdr32.sh_type; + else + sh_type = scn->s_shdr.s_shdr64.sh_type; + + if (_libelf_xlate_shtype(sh_type) != ELF_T_WORD || + d->d_type != ELF_T_WORD) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); + assert(msz > 0); + + if (msz * ndx >= id->d_size) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0); + } + + *(((Elf32_Word *) id->d_buf) + ndx) = xindex; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/gelf_update_ehdr.3 b/contrib/elftoolchain/libelf/gelf_update_ehdr.3 new file mode 100644 index 0000000..f5e041d --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_update_ehdr.3 @@ -0,0 +1,123 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_update_ehdr.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd August 27, 2006 +.Os +.Dt GELF_UPDATE_EHDR 3 +.Sh NAME +.Nm gelf_update_ehdr , +.Nm gelf_update_phdr , +.Nm gelf_update_shdr +.Nd update underlying ELF data structures +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In gelf.h +.Ft int +.Fn gelf_update_ehdr "Elf *elf" "GElf_Ehdr *ehdr" +.Ft int +.Fn gelf_update_phdr "Elf *elf" "int ndx" "GElf_Phdr *phdr" +.Ft int +.Fn gelf_update_shdr "Elf_Scn *scn" "GElf_Shdr *shdr" +.Sh DESCRIPTION +These functions are used to update ELF data structures on the underlying +ELF descriptor. +Class-dependent data structures in the underlying ELF descriptor +are updated using the data in the class-independent GElf descriptors +and the underlying ELF data structures are marked +.Dq dirty . +The conversion process signals an error if the values being copied +to the target ELF data structure would exceed representation +limits. +GElf descriptors are described in +.Xr gelf 3 . +.Pp +Function +.Fn gelf_update_ehdr +updates the ELF Executable Header with the values in the +class-independent executable header +.Ar ehdr . +.Pp +Function +.Fn gelf_update_phdr +updates the ELF Program Header structure at index +.Ar ndx +with the values in the class-independent program header +.Ar phdr . +.Pp +Function +.Fn gelf_update_shdr +updates the ELF Section Header structure associated with section +descriptor +.Ar scn +with the values in argument +.Ar shdr . +.Sh RETURN VALUES +These functions return a non-zero integer on success, or zero in case +of an error. +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar elf , +.Ar ehdr , +.Ar phdr , +.Ar scn , +or +.Ar shdr +were NULL. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +was not a descriptor for an ELF object. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar elf +had an unsupported ELF class. +.It Bq Er ELF_E_ARGUMENT +Argument +.Ar ndx +exceeded the number of entries in the program header table. +.It Bq Er ELF_E_ARGUMENT +Section descriptor +.Ar scn +was not associated with an ELF descriptor. +.It Bq Er ELF_E_MODE +ELF descriptor +.Ar elf +was not opened for writing or updating. +.It Bq Er ELF_E_RESOURCE +An out of memory condition was detected. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_flagelf 3 , +.Xr elf_flagphdr 3 , +.Xr elf_flagshdr 3 , +.Xr gelf 3 , +.Xr gelf_getehdr 3 , +.Xr gelf_getphdr 3 , +.Xr gelf_getshdr 3 diff --git a/contrib/elftoolchain/libelf/gelf_xlate.c b/contrib/elftoolchain/libelf/gelf_xlate.c new file mode 100644 index 0000000..15f30ee --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_xlate.c @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> +#include <libelf.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: gelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +Elf_Data * +elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); +} + +Elf_Data * +elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOFILE); +} + +Elf_Data * +elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOMEMORY); +} + +Elf_Data * +elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) +{ + return _libelf_xlate(dst, src, encoding, ELFCLASS64, ELF_TOMEMORY); +} + +Elf_Data * +gelf_xlatetom(Elf *e, Elf_Data *dst, const Elf_Data *src, + unsigned int encoding) +{ + if (e != NULL) + return (_libelf_xlate(dst, src, encoding, e->e_class, + ELF_TOMEMORY)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} + +Elf_Data * +gelf_xlatetof(Elf *e, Elf_Data *dst, const Elf_Data *src, + unsigned int encoding) +{ + if (e != NULL) + return (_libelf_xlate(dst, src, encoding, e->e_class, + ELF_TOFILE)); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/gelf_xlatetof.3 b/contrib/elftoolchain/libelf/gelf_xlatetof.3 new file mode 100644 index 0000000..ca90002 --- /dev/null +++ b/contrib/elftoolchain/libelf/gelf_xlatetof.3 @@ -0,0 +1,247 @@ +.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. 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 Joseph Koshy ``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 Joseph Koshy 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. +.\" +.\" $Id: gelf_xlatetof.3 189 2008-07-20 10:38:08Z jkoshy $ +.\" +.Dd July 24, 2006 +.Os +.Dt GELF_XLATETOF 3 +.Sh NAME +.Nm elf32_xlate , +.Nm elf64_xlate , +.Nm gelf_xlate +.Nd translate data between files and memory +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf_Data *" +.Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Ft "Elf_Data *" +.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Ft "Elf_Data *" +.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Ft "Elf_Data *" +.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.In gelf.h +.Ft "Elf_Data *" +.Fo gelf_xlatetof +.Fa "Elf *elf" +.Fa "Elf_Data *dst" +.Fa "Elf_Data *src" +.Fa "unsigned int encode" +.Fc +.Ft "Elf_Data *" +.Fo gelf_xlatetom +.Fa "Elf *elf" +.Fa "Elf_Data *dst" +.Fa "Elf_Data *src" +.Fa "unsigned int encode" +.Fc +.Sh DESCRIPTION +These functions translate between the file and memory representations +of ELF data structures. +The in-memory representation of an ELF data structure would confirm to +the byte ordering and data alignment restrictions dictated by the host +processor. +A file representation of the same data structure could use a non-native byte +ordering and in addition may be laid out differently with the file. +.Pp +Functions +.Fn elf32_xlatetom , +.Fn elf64_xlatetom , +and +.Fn gelf_xlatetom +translate data from file representations to native, in-memory representations. +Functions +.Fn elf32_xlatetof , +.Fn elf64_xlatetof , +and +.Fn gelf_xlatetof +translate data from in-memory representations to file representations. +.Pp +Argument +.Ar src +denotes an +.Vt Elf_Data +descriptor describing the source to be translated. +The following elements of the descriptor need to be set before +invoking these functions: +.Bl -hang -offset indent +.It Va d_buf +Set to a valid pointer value denoting the beginning of the data area +to be translated. +.It Va d_size +Set to the total size in bytes of the source data area to be +translated. +.It Va d_type +Set to the type of the source data being translated. +This value is one of the values defined in the +.Vt Elf_Type +enumeration. +The +.Vt Elf_Type +enumeration is described in +.Xr elf 3 . +.It Va d_version +Set to the version number of the ELF data structures being +translated. +Currently only version +.Dv EV_CURRENT +is supported. +.El +.Pp +Argument +.Ar dst +describes the destination buffer. +The following elements of the +.Vt Elf_Data +descriptor need to be set before invoking these functions: +.Bl -hang -offset indent +.It Va d_buf +Set to a valid pointer value that denotes the start of the destination +buffer that will hold translated data. +This value may be the same as that of the source buffer, in which case +an in-place conversion will be attempted. +.It Va d_size +Set to the size of the destination buffer in bytes. +This value will be modified if the function call succeeds. +.It Va d_version +Set to the desired version number of the destination. +Currently only version +.Dv EV_CURRENT +is supported. +.El +.Pp +These translations routines allow the source and destination buffers +to coincide, in which case an in-place translation will be done +if the destination is large enough to hold the translated data. +Other kinds of overlap between the source and destination buffers +are not permitted. +.Pp +On successful completion of the translation request the following +fields of the +.Ar dst +descriptor would be modified: +.Bl -hang -offset indent +.It Va d_size +Set to the size in bytes of the translated data. +.It Va d_type +Set to the +.Va d_type +value of the source data descriptor. +.El +.Pp +Argument +.Ar encode +specifies the encoding in which the file objects are represented. +It must be one of: +.Bl -hang -offset indent +.It Dv ELFDATANONE +File objects use the library's native byte ordering. +.It Dv ELFDATA2LSB +File objects use a little-endian ordering. +.It Dv ELFDATA2MSB +File objects use a big-endian ordering. +.El +.Pp +The functions +.Fn gelf_xlatetof +and +.Fn gelf_xlatetom +select the appropriate 32 or 64 bit translations based on the class of argument +.Ar elf . +.Sh RETURN VALUES +These functions return argument +.Ar dst +if successful, or NULL in case of an error. +.Sh EXAMPLES +TODO +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width "[ELF_E_RESOURCE]" +.It Bq Er ELF_E_ARGUMENT +One of arguments +.Ar src , +.Ar dst +or +.Ar elf +was NULL. +.It Bq Er ELF_E_ARGUMENT +Arguments +.Ar src +and +.Ar dst +were equal. +.It Bq Er ELF_E_ARGUMENT +The desired encoding parameter was not one of +.Dv ELFDATANONE , +.Dv ELFDATA2LSB +or +.Dv ELFDATA2MSB . +.It Bq Er ELF_E_ARGUMENT +The +.Ar d_type +field of argument +.Ar src +specified an unsupported type. +.It Bq Er ELF_E_DATA +The +.Ar src +argument specified a buffer size that was not an integral multiple of +its underlying type. +.It Bq Er ELF_E_DATA +The +.Ar dst +argument specified a buffer size that was too small. +.It Bq Er ELF_E_DATA +Argument +.Ar dst +specified a destination buffer that overlaps with the source +buffer. +.It Bq Er ELF_E_DATA +The destination buffer for a conversion to memory had an alignment +inappropriate for the underlying ELF type. +.It Bq Er ELF_E_DATA +The source buffer for a conversion to file had an alignment +inappropriate for the underlying ELF type. +.It Bq Er ELF_E_UNIMPL +The version numbers for arguments +.Ar dst +and +.Ar src +were not identical. +.It Bq Er ELF_E_UNIMPL +The argument +.Ar src +requested conversion for a type which is not currently +supported. +.It Bq Er ELF_E_VERSION +Argument +.Ar src +specified an unsupported version number. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getdata 3 , +.Xr gelf 3 diff --git a/contrib/elftoolchain/libelf/libelf.h b/contrib/elftoolchain/libelf/libelf.h new file mode 100644 index 0000000..d3219d7 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf.h @@ -0,0 +1,252 @@ +/*- + * Copyright (c) 2006,2008-2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $Id: libelf.h 2366 2011-12-29 06:12:14Z jkoshy $ + */ + +#ifndef _LIBELF_H_ +#define _LIBELF_H_ + +#include <sys/types.h> + +#include <elfdefinitions.h> + +/* Library private data structures */ +typedef struct _Elf Elf; +typedef struct _Elf_Scn Elf_Scn; + +/* File types */ +typedef enum { + ELF_K_NONE = 0, + ELF_K_AR, /* `ar' archives */ + ELF_K_COFF, /* COFF files (unsupported) */ + ELF_K_ELF, /* ELF files */ + ELF_K_NUM +} Elf_Kind; + +#define ELF_K_FIRST ELF_K_NONE +#define ELF_K_LAST ELF_K_NUM + +/* Data types */ +typedef enum { + ELF_T_ADDR, + ELF_T_BYTE, + ELF_T_CAP, + ELF_T_DYN, + ELF_T_EHDR, + ELF_T_HALF, + ELF_T_LWORD, + ELF_T_MOVE, + ELF_T_MOVEP, + ELF_T_NOTE, + ELF_T_OFF, + ELF_T_PHDR, + ELF_T_REL, + ELF_T_RELA, + ELF_T_SHDR, + ELF_T_SWORD, + ELF_T_SXWORD, + ELF_T_SYMINFO, + ELF_T_SYM, + ELF_T_VDEF, + ELF_T_VNEED, + ELF_T_WORD, + ELF_T_XWORD, + ELF_T_GNUHASH, /* GNU style hash tables. */ + ELF_T_NUM +} Elf_Type; + +#define ELF_T_FIRST ELF_T_ADDR +#define ELF_T_LAST ELF_T_GNUHASH + +/* Commands */ +typedef enum { + ELF_C_NULL = 0, + ELF_C_CLR, + ELF_C_FDDONE, + ELF_C_FDREAD, + ELF_C_RDWR, + ELF_C_READ, + ELF_C_SET, + ELF_C_WRITE, + ELF_C_NUM +} Elf_Cmd; + +#define ELF_C_FIRST ELF_C_NULL +#define ELF_C_LAST ELF_C_NUM + +/* + * An `Elf_Data' structure describes data in an + * ELF section. + */ +typedef struct _Elf_Data { + /* + * `Public' members that are part of the ELF(3) API. + */ + uint64_t d_align; + void *d_buf; + uint64_t d_off; + uint64_t d_size; + Elf_Type d_type; + unsigned int d_version; +} Elf_Data; + +/* + * An `Elf_Arhdr' structure describes an archive + * header. + */ +typedef struct { + time_t ar_date; + char *ar_name; /* archive member name */ + gid_t ar_gid; + mode_t ar_mode; + char *ar_rawname; /* 'raw' member name */ + size_t ar_size; + uid_t ar_uid; + + /* + * Members that are not part of the public API. + */ + int ar_flags; +} Elf_Arhdr; + +/* + * An `Elf_Arsym' describes an entry in the archive + * symbol table. + */ +typedef struct { + off_t as_off; /* byte offset to member's header */ + unsigned long as_hash; /* elf_hash() value for name */ + char *as_name; /* null terminated symbol name */ +} Elf_Arsym; + +/* + * Error numbers. + */ + +enum Elf_Error { + ELF_E_NONE, /* No error */ + ELF_E_ARCHIVE, /* Malformed ar(1) archive */ + ELF_E_ARGUMENT, /* Invalid argument */ + ELF_E_CLASS, /* Mismatched ELF class */ + ELF_E_DATA, /* Invalid data descriptor */ + ELF_E_HEADER, /* Missing or malformed ELF header */ + ELF_E_IO, /* I/O error */ + ELF_E_LAYOUT, /* Layout constraint violation */ + ELF_E_MODE, /* Wrong mode for ELF descriptor */ + ELF_E_RANGE, /* Value out of range */ + ELF_E_RESOURCE, /* Resource exhaustion */ + ELF_E_SECTION, /* Invalid section descriptor */ + ELF_E_SEQUENCE, /* API calls out of sequence */ + ELF_E_UNIMPL, /* Feature is unimplemented */ + ELF_E_VERSION, /* Unknown API version */ + ELF_E_NUM /* Max error number */ +}; + +/* + * Flags defined by the API. + */ + +#define ELF_F_LAYOUT 0x001U /* application will layout the file */ +#define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ + +/* ELF(3) API extensions. */ +#define ELF_F_ARCHIVE 0x100U /* archive creation */ +#define ELF_F_ARCHIVE_SYSV 0x200U /* SYSV style archive */ + +__BEGIN_DECLS +Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); +int elf_cntl(Elf *_elf, Elf_Cmd _cmd); +int elf_end(Elf *_elf); +const char *elf_errmsg(int _error); +int elf_errno(void); +void elf_fill(int _fill); +unsigned int elf_flagarhdr(Elf_Arhdr *_arh, Elf_Cmd _cmd, + unsigned int _flags); +unsigned int elf_flagdata(Elf_Data *_data, Elf_Cmd _cmd, + unsigned int _flags); +unsigned int elf_flagehdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagelf(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagphdr(Elf *_elf, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagscn(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); +unsigned int elf_flagshdr(Elf_Scn *_scn, Elf_Cmd _cmd, unsigned int _flags); +Elf_Arhdr *elf_getarhdr(Elf *_elf); +Elf_Arsym *elf_getarsym(Elf *_elf, size_t *_ptr); +off_t elf_getbase(Elf *_elf); +Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); +char *elf_getident(Elf *_elf, size_t *_ptr); +int elf_getphdrnum(Elf *_elf, size_t *_dst); +int elf_getphnum(Elf *_elf, size_t *_dst); /* Deprecated */ +Elf_Scn *elf_getscn(Elf *_elf, size_t _index); +int elf_getshdrnum(Elf *_elf, size_t *_dst); +int elf_getshnum(Elf *_elf, size_t *_dst); /* Deprecated */ +int elf_getshdrstrndx(Elf *_elf, size_t *_dst); +int elf_getshstrndx(Elf *_elf, size_t *_dst); /* Deprecated */ +unsigned long elf_hash(const char *_name); +Elf_Kind elf_kind(Elf *_elf); +Elf *elf_memory(char *_image, size_t _size); +size_t elf_ndxscn(Elf_Scn *_scn); +Elf_Data *elf_newdata(Elf_Scn *_scn); +Elf_Scn *elf_newscn(Elf *_elf); +Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); +Elf_Cmd elf_next(Elf *_elf); +Elf *elf_open(int _fd); +Elf *elf_openmemory(char *_image, size_t _size); +off_t elf_rand(Elf *_elf, off_t _off); +Elf_Data *elf_rawdata(Elf_Scn *_scn, Elf_Data *_data); +char *elf_rawfile(Elf *_elf, size_t *_size); +int elf_setshstrndx(Elf *_elf, size_t _shnum); +char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); +off_t elf_update(Elf *_elf, Elf_Cmd _cmd); +unsigned int elf_version(unsigned int _version); + +long elf32_checksum(Elf *_elf); +size_t elf32_fsize(Elf_Type _type, size_t _count, + unsigned int _version); +Elf32_Ehdr *elf32_getehdr(Elf *_elf); +Elf32_Phdr *elf32_getphdr(Elf *_elf); +Elf32_Shdr *elf32_getshdr(Elf_Scn *_scn); +Elf32_Ehdr *elf32_newehdr(Elf *_elf); +Elf32_Phdr *elf32_newphdr(Elf *_elf, size_t _count); +Elf_Data *elf32_xlatetof(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +Elf_Data *elf32_xlatetom(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); + +long elf64_checksum(Elf *_elf); +size_t elf64_fsize(Elf_Type _type, size_t _count, + unsigned int _version); +Elf64_Ehdr *elf64_getehdr(Elf *_elf); +Elf64_Phdr *elf64_getphdr(Elf *_elf); +Elf64_Shdr *elf64_getshdr(Elf_Scn *_scn); +Elf64_Ehdr *elf64_newehdr(Elf *_elf); +Elf64_Phdr *elf64_newphdr(Elf *_elf, size_t _count); +Elf_Data *elf64_xlatetof(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +Elf_Data *elf64_xlatetom(Elf_Data *_dst, const Elf_Data *_src, + unsigned int _enc); +__END_DECLS + +#endif /* _LIBELF_H_ */ diff --git a/contrib/elftoolchain/libelf/libelf_align.c b/contrib/elftoolchain/libelf/libelf_align.c new file mode 100644 index 0000000..9550c5b --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_align.c @@ -0,0 +1,137 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <sys/types.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_align.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +struct align { + int a32; + int a64; +}; + +#ifdef __GNUC__ +#define MALIGN(N) { \ + .a32 = __alignof__(Elf32_##N), \ + .a64 = __alignof__(Elf64_##N) \ + } +#define MALIGN64(V) { \ + .a32 = 0, \ + .a64 = __alignof__(Elf64_##V) \ + } +#define MALIGN_WORD() { \ + .a32 = __alignof__(int32_t), \ + .a64 = __alignof__(int64_t) \ + } +#else +#error Need the __alignof__ builtin. +#endif +#define UNSUPPORTED() { \ + .a32 = 0, \ + .a64 = 0 \ + } + +static struct align malign[ELF_T_NUM] = { + [ELF_T_ADDR] = MALIGN(Addr), + [ELF_T_BYTE] = { .a32 = 1, .a64 = 1 }, + [ELF_T_CAP] = MALIGN(Cap), + [ELF_T_DYN] = MALIGN(Dyn), + [ELF_T_EHDR] = MALIGN(Ehdr), + [ELF_T_HALF] = MALIGN(Half), + [ELF_T_LWORD] = MALIGN(Lword), + [ELF_T_MOVE] = MALIGN(Move), + [ELF_T_MOVEP] = UNSUPPORTED(), + [ELF_T_NOTE] = MALIGN(Nhdr), + [ELF_T_OFF] = MALIGN(Off), + [ELF_T_PHDR] = MALIGN(Phdr), + [ELF_T_REL] = MALIGN(Rel), + [ELF_T_RELA] = MALIGN(Rela), + [ELF_T_SHDR] = MALIGN(Shdr), + [ELF_T_SWORD] = MALIGN(Sword), + [ELF_T_SXWORD] = MALIGN64(Sxword), + [ELF_T_SYM] = MALIGN(Sym), + [ELF_T_SYMINFO] = MALIGN(Syminfo), + [ELF_T_VDEF] = MALIGN(Verdef), + [ELF_T_VNEED] = MALIGN(Verneed), + [ELF_T_WORD] = MALIGN(Word), + [ELF_T_XWORD] = MALIGN64(Xword), + [ELF_T_GNUHASH] = MALIGN_WORD() +}; + +int +_libelf_malign(Elf_Type t, int elfclass) +{ + if (t >= ELF_T_NUM || (int) t < 0) + return (0); + + return (elfclass == ELFCLASS32 ? malign[t].a32 : + malign[t].a64); +} + +#define FALIGN(A32,A64) { .a32 = (A32), .a64 = (A64) } + +static struct align falign[ELF_T_NUM] = { + [ELF_T_ADDR] = FALIGN(4,8), + [ELF_T_BYTE] = FALIGN(1,1), + [ELF_T_CAP] = FALIGN(4,8), + [ELF_T_DYN] = FALIGN(4,8), + [ELF_T_EHDR] = FALIGN(4,8), + [ELF_T_HALF] = FALIGN(2,2), + [ELF_T_LWORD] = FALIGN(8,8), + [ELF_T_MOVE] = FALIGN(8,8), + [ELF_T_MOVEP] = UNSUPPORTED(), + [ELF_T_NOTE] = FALIGN(4,4), + [ELF_T_OFF] = FALIGN(4,8), + [ELF_T_PHDR] = FALIGN(4,8), + [ELF_T_REL] = FALIGN(4,8), + [ELF_T_RELA] = FALIGN(4,8), + [ELF_T_SHDR] = FALIGN(4,8), + [ELF_T_SWORD] = FALIGN(4,4), + [ELF_T_SXWORD] = FALIGN(0,8), + [ELF_T_SYM] = FALIGN(4,8), + [ELF_T_SYMINFO] = FALIGN(2,2), + [ELF_T_VDEF] = FALIGN(4,4), + [ELF_T_VNEED] = FALIGN(4,4), + [ELF_T_WORD] = FALIGN(4,4), + [ELF_T_XWORD] = FALIGN(0,8), + [ELF_T_GNUHASH] = FALIGN(4,8) +}; + +int +_libelf_falign(Elf_Type t, int elfclass) +{ + if (t >= ELF_T_NUM || (int) t < 0) + return (0); + + return (elfclass == ELFCLASS32 ? falign[t].a32 : + falign[t].a64); +} diff --git a/contrib/elftoolchain/libelf/libelf_allocate.c b/contrib/elftoolchain/libelf/libelf_allocate.c new file mode 100644 index 0000000..9a5df6b --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_allocate.c @@ -0,0 +1,212 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +/* + * Internal APIs + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <errno.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_allocate.c 2272 2011-12-03 17:07:31Z jkoshy $"); + +Elf * +_libelf_allocate_elf(void) +{ + Elf *e; + + if ((e = malloc(sizeof(*e))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return NULL; + } + + e->e_activations = 1; + e->e_hdr.e_rawhdr = NULL; + e->e_byteorder = ELFDATANONE; + e->e_class = ELFCLASSNONE; + e->e_cmd = ELF_C_NULL; + e->e_fd = -1; + e->e_flags = 0; + e->e_kind = ELF_K_NONE; + e->e_parent = NULL; + e->e_rawfile = NULL; + e->e_rawsize = 0; + e->e_version = LIBELF_PRIVATE(version); + + (void) memset(&e->e_u, 0, sizeof(e->e_u)); + + return (e); +} + +void +_libelf_init_elf(Elf *e, Elf_Kind kind) +{ + assert(e != NULL); + assert(e->e_kind == ELF_K_NONE); + + e->e_kind = kind; + + switch (kind) { + case ELF_K_ELF: + STAILQ_INIT(&e->e_u.e_elf.e_scn); + break; + default: + break; + } +} + +#define FREE(P) do { \ + if (P) \ + free(P); \ + } while (0) + + +Elf * +_libelf_release_elf(Elf *e) +{ + Elf_Arhdr *arh; + + switch (e->e_kind) { + case ELF_K_AR: + FREE(e->e_u.e_ar.e_symtab); + break; + + case ELF_K_ELF: + switch (e->e_class) { + case ELFCLASS32: + FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); + FREE(e->e_u.e_elf.e_phdr.e_phdr32); + break; + case ELFCLASS64: + FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); + FREE(e->e_u.e_elf.e_phdr.e_phdr64); + break; + } + + assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); + + if (e->e_flags & LIBELF_F_AR_HEADER) { + arh = e->e_hdr.e_arhdr; + FREE(arh->ar_name); + FREE(arh->ar_rawname); + free(arh); + } + + break; + + default: + break; + } + + free(e); + + return (NULL); +} + +struct _Libelf_Data * +_libelf_allocate_data(Elf_Scn *s) +{ + struct _Libelf_Data *d; + + if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + d->d_scn = s; + + return (d); +} + +struct _Libelf_Data * +_libelf_release_data(struct _Libelf_Data *d) +{ + + if (d->d_flags & LIBELF_F_DATA_MALLOCED) + free(d->d_data.d_buf); + + free(d); + + return (NULL); +} + +Elf_Scn * +_libelf_allocate_scn(Elf *e, size_t ndx) +{ + Elf_Scn *s; + + if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, errno); + return (NULL); + } + + s->s_elf = e; + s->s_ndx = ndx; + + STAILQ_INIT(&s->s_data); + STAILQ_INIT(&s->s_rawdata); + + STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); + + return (s); +} + +Elf_Scn * +_libelf_release_scn(Elf_Scn *s) +{ + Elf *e; + struct _Libelf_Data *d, *td; + + assert(s != NULL); + + STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { + STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); + d = _libelf_release_data(d); + } + + STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { + assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); + STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); + d = _libelf_release_data(d); + } + + e = s->s_elf; + + assert(e != NULL); + + STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); + + free(s); + + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_ar.c b/contrib/elftoolchain/libelf/libelf_ar.c new file mode 100644 index 0000000..c990d6d --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ar.c @@ -0,0 +1,461 @@ +/*- + * Copyright (c) 2006,2008,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <ctype.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> + +#include "_libelf.h" +#include "_libelf_ar.h" + +ELFTC_VCSID("$Id: libelf_ar.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +#define LIBELF_NALLOC_SIZE 16 + +/* + * `ar' archive handling. + * + * `ar' archives start with signature `ARMAG'. Each archive member is + * preceded by a header containing meta-data for the member. This + * header is described in <ar.h> (struct ar_hdr). The header always + * starts on an even address. File data is padded with "\n" + * characters to keep this invariant. + * + * Special considerations for `ar' archives: + * + * There are two variants of the `ar' archive format: traditional BSD + * and SVR4. These differ in the way long file names are treated, and + * in the layout of the archive symbol table. + * + * The `ar' header only has space for a 16 character file name. + * + * In the SVR4 format, file names are terminated with a '/', so this + * effectively leaves 15 characters for the actual file name. Longer + * file names stored in a separate 'string table' and referenced + * indirectly from the name field. The string table itself appears as + * an archive member with name "// ". An `indirect' file name in an + * `ar' header matches the pattern "/[0-9]*". The digits form a + * decimal number that corresponds to a byte offset into the string + * table where the actual file name of the object starts. Strings in + * the string table are padded to start on even addresses. + * + * In the BSD format, file names can be upto 16 characters. File + * names shorter than 16 characters are padded to 16 characters using + * (ASCII) space characters. File names with embedded spaces and file + * names longer than 16 characters are stored immediately after the + * archive header and the name field set to a special indirect name + * matching the pattern "#1/[0-9]+". The digits form a decimal number + * that corresponds to the actual length of the file name following + * the archive header. The content of the archive member immediately + * follows the file name, and the size field of the archive member + * holds the sum of the sizes of the member and of the appended file + * name. + * + * Archives may also have a symbol table (see ranlib(1)), mapping + * program symbols to object files inside the archive. + * + * In the SVR4 format, a symbol table uses a file name of "/ " in its + * archive header. The symbol table is structured as: + * - a 4-byte count of entries stored as a binary value, MSB first + * - 'n' 4-byte offsets, stored as binary values, MSB first + * - 'n' NUL-terminated strings, for ELF symbol names, stored unpadded. + * + * In the BSD format, the symbol table uses a file name of "__.SYMDEF". + * It is structured as two parts: + * - The first part is an array of "ranlib" structures preceded by + * the size of the array in bytes. Each "ranlib" structure + * describes one symbol. Each structure contains an offset into + * the string table for the symbol name, and a file offset into the + * archive for the member defining the symbol. + * - The second part is a string table containing NUL-terminated + * strings, preceded by the size of the string table in bytes. + * + * If the symbol table and string table are is present in an archive + * they must be the very first objects and in that order. + */ + + +/* + * Retrieve an archive header descriptor. + */ + +Elf_Arhdr * +_libelf_ar_gethdr(Elf *e) +{ + Elf *parent; + char *namelen; + Elf_Arhdr *eh; + size_t n, nlen; + struct ar_hdr *arh; + + if ((parent = e->e_parent) == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert((e->e_flags & LIBELF_F_AR_HEADER) == 0); + + arh = (struct ar_hdr *) (uintptr_t) e->e_hdr.e_rawhdr; + + assert((uintptr_t) arh >= (uintptr_t) parent->e_rawfile + SARMAG); + assert((uintptr_t) arh <= (uintptr_t) parent->e_rawfile + + parent->e_rawsize - sizeof(struct ar_hdr)); + + if ((eh = malloc(sizeof(Elf_Arhdr))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + e->e_hdr.e_arhdr = eh; + e->e_flags |= LIBELF_F_AR_HEADER; + + eh->ar_name = eh->ar_rawname = NULL; + + if ((eh->ar_name = _libelf_ar_get_translated_name(arh, parent)) == + NULL) + goto error; + + if (_libelf_ar_get_number(arh->ar_uid, sizeof(arh->ar_uid), 10, + &n) == 0) + goto error; + eh->ar_uid = (uid_t) n; + + if (_libelf_ar_get_number(arh->ar_gid, sizeof(arh->ar_gid), 10, + &n) == 0) + goto error; + eh->ar_gid = (gid_t) n; + + if (_libelf_ar_get_number(arh->ar_mode, sizeof(arh->ar_mode), 8, + &n) == 0) + goto error; + eh->ar_mode = (mode_t) n; + + if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, + &n) == 0) + goto error; + + /* + * Get the true size of the member if extended naming is being used. + */ + if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { + namelen = arh->ar_name + + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nlen) == 0) + goto error; + n -= nlen; + } + + eh->ar_size = n; + + if ((eh->ar_rawname = _libelf_ar_get_raw_name(arh)) == NULL) + goto error; + + eh->ar_flags = 0; + + return (eh); + + error: + if (eh) { + if (eh->ar_name) + free(eh->ar_name); + if (eh->ar_rawname) + free(eh->ar_rawname); + free(eh); + } + + e->e_flags &= ~LIBELF_F_AR_HEADER; + e->e_hdr.e_rawhdr = (char *) arh; + + return (NULL); +} + +Elf * +_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) +{ + Elf *e; + char *member, *namelen; + size_t nsz, sz; + off_t next; + struct ar_hdr *arh; + + assert(elf->e_kind == ELF_K_AR); + + next = elf->e_u.e_ar.e_next; + + /* + * `next' is only set to zero by elf_next() when the last + * member of an archive is processed. + */ + if (next == (off_t) 0) + return (NULL); + + assert((next & 1) == 0); + + arh = (struct ar_hdr *) (elf->e_rawfile + next); + + /* + * Retrieve the size of the member. + */ + if (_libelf_ar_get_number(arh->ar_size, sizeof(arh->ar_size), 10, + &sz) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + /* + * Adjust the size field for members in BSD archives using + * extended naming. + */ + if (IS_EXTENDED_BSD_NAME(arh->ar_name)) { + namelen = arh->ar_name + + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + if (_libelf_ar_get_number(namelen, sizeof(arh->ar_name) - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &nsz) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + member = (char *) (arh + 1) + nsz; + sz -= nsz; + } else + member = (char *) (arh + 1); + + + if ((e = elf_memory((char *) member, sz)) == NULL) + return (NULL); + + e->e_fd = fd; + e->e_cmd = c; + e->e_hdr.e_rawhdr = (char *) arh; + + elf->e_u.e_ar.e_nchildren++; + e->e_parent = elf; + + return (e); +} + +/* + * A BSD-style ar(1) symbol table has the following layout: + * + * - A count of bytes used by the following array of 'ranlib' + * structures, stored as a 'long'. + * - An array of 'ranlib' structures. Each array element is + * two 'long's in size. + * - A count of bytes used for the following symbol table. + * - The symbol table itself. + */ + +/* + * A helper macro to read in a 'long' value from the archive. We use + * memcpy() since the source pointer may be misaligned with respect to + * the natural alignment for a C 'long'. + */ +#define GET_LONG(P, V)do { \ + memcpy(&(V), (P), sizeof(long)); \ + (P) += sizeof(long); \ + } while (0) + +Elf_Arsym * +_libelf_ar_process_bsd_symtab(Elf *e, size_t *count) +{ + Elf_Arsym *symtab, *sym; + unsigned char *end, *p, *p0, *s, *s0; + const unsigned int entrysize = 2 * sizeof(long); + long arraysize, fileoffset, n, nentries, stroffset, strtabsize; + + assert(e != NULL); + assert(count != NULL); + assert(e->e_u.e_ar.e_symtab == NULL); + + symtab = NULL; + + /* + * The BSD symbol table always contains the count fields even + * if there are no entries in it. + */ + if (e->e_u.e_ar.e_rawsymtabsz < 2 * sizeof(long)) + goto symtaberror; + + p = p0 = (unsigned char *) e->e_u.e_ar.e_rawsymtab; + end = p0 + e->e_u.e_ar.e_rawsymtabsz; + + /* + * Retrieve the size of the array of ranlib descriptors and + * check it for validity. + */ + GET_LONG(p, arraysize); + + if (p0 + arraysize >= end || (arraysize % entrysize != 0)) + goto symtaberror; + + /* + * Check the value of the string table size. + */ + s = p + arraysize; + GET_LONG(s, strtabsize); + + s0 = s; /* Start of string table. */ + if (s0 + strtabsize > end) + goto symtaberror; + + nentries = arraysize / entrysize; + + /* + * Allocate space for the returned Elf_Arsym array. + */ + if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries + 1))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + /* Read in symbol table entries. */ + for (n = 0, sym = symtab; n < nentries; n++, sym++) { + GET_LONG(p, stroffset); + GET_LONG(p, fileoffset); + + s = s0 + stroffset; + + if (s >= end) + goto symtaberror; + + sym->as_off = fileoffset; + sym->as_hash = elf_hash((char *) s); + sym->as_name = (char *) s; + } + + /* Fill up the sentinel entry. */ + sym->as_name = NULL; + sym->as_hash = ~0UL; + sym->as_off = (off_t) 0; + + /* Remember the processed symbol table. */ + e->e_u.e_ar.e_symtab = symtab; + + *count = e->e_u.e_ar.e_symtabsz = nentries + 1; + + return (symtab); + +symtaberror: + if (symtab) + free(symtab); + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} + +/* + * An SVR4-style ar(1) symbol table has the following layout: + * + * - The first 4 bytes are a binary count of the number of entries in the + * symbol table, stored MSB-first. + * - Then there are 'n' 4-byte binary offsets, also stored MSB first. + * - Following this, there are 'n' null-terminated strings. + */ + +#define GET_WORD(P, V) do { \ + (V) = 0; \ + (V) = (P)[0]; (V) <<= 8; \ + (V) += (P)[1]; (V) <<= 8; \ + (V) += (P)[2]; (V) <<= 8; \ + (V) += (P)[3]; \ + } while (0) + +#define INTSZ 4 + + +Elf_Arsym * +_libelf_ar_process_svr4_symtab(Elf *e, size_t *count) +{ + size_t n, nentries, off; + Elf_Arsym *symtab, *sym; + unsigned char *p, *s, *end; + + assert(e != NULL); + assert(count != NULL); + assert(e->e_u.e_ar.e_symtab == NULL); + + symtab = NULL; + + if (e->e_u.e_ar.e_rawsymtabsz < INTSZ) + goto symtaberror; + + p = (unsigned char *) e->e_u.e_ar.e_rawsymtab; + end = p + e->e_u.e_ar.e_rawsymtabsz; + + GET_WORD(p, nentries); + p += INTSZ; + + if (nentries == 0 || p + nentries * INTSZ >= end) + goto symtaberror; + + /* Allocate space for a nentries + a sentinel. */ + if ((symtab = malloc(sizeof(Elf_Arsym) * (nentries+1))) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + s = p + (nentries * INTSZ); /* start of the string table. */ + + for (n = nentries, sym = symtab; n > 0; n--) { + + if (s >= end) + goto symtaberror; + + off = 0; + + GET_WORD(p, off); + + sym->as_off = off; + sym->as_hash = elf_hash((char *) s); + sym->as_name = (char *) s; + + p += INTSZ; + sym++; + + for (; s < end && *s++ != '\0';) /* skip to next string */ + ; + } + + /* Fill up the sentinel entry. */ + sym->as_name = NULL; + sym->as_hash = ~0UL; + sym->as_off = (off_t) 0; + + *count = e->e_u.e_ar.e_symtabsz = nentries + 1; + e->e_u.e_ar.e_symtab = symtab; + + return (symtab); + +symtaberror: + if (symtab) + free(symtab); + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_ar_util.c b/contrib/elftoolchain/libelf/libelf_ar_util.c new file mode 100644 index 0000000..958fbbf --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ar_util.c @@ -0,0 +1,359 @@ +/*- + * Copyright (c) 2006,2009,2010 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> +#include <stdlib.h> +#include <string.h> + +#include "_libelf.h" +#include "_libelf_ar.h" + +ELFTC_VCSID("$Id: libelf_ar_util.c 2365 2011-12-29 04:36:44Z jkoshy $"); + +/* + * Convert a string bounded by `start' and `start+sz' (exclusive) to a + * number in the specified base. + */ +int +_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) +{ + int c, v; + size_t r; + const char *e; + + assert(base <= 10); + + e = s + sz; + + /* skip leading blanks */ + for (;s < e && (c = *s) == ' '; s++) + ; + + r = 0L; + for (;s < e; s++) { + if ((c = *s) == ' ') + break; + if (c < '0' || c > '9') + return (0); + v = c - '0'; + if (v >= base) /* Illegal digit. */ + break; + r *= base; + r += v; + } + + *ret = r; + + return (1); +} + +/* + * Return the translated name for an archive member. + */ +char * +_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) +{ + char c, *s; + size_t len, offset; + const char *buf, *p, *q, *r; + const size_t bufsize = sizeof(arh->ar_name); + + assert(arh != NULL); + assert(ar->e_kind == ELF_K_AR); + assert((const char *) arh >= ar->e_rawfile && + (const char *) arh < ar->e_rawfile + ar->e_rawsize); + + buf = arh->ar_name; + + /* + * Check for extended naming. + * + * If the name matches the pattern "^/[0-9]+", it is an + * SVR4-style extended name. If the name matches the pattern + * "#1/[0-9]+", the entry uses BSD style extended naming. + */ + if (buf[0] == '/' && (c = buf[1]) >= '0' && c <= '9') { + /* + * The value in field ar_name is a decimal offset into + * the archive string table where the actual name + * resides. + */ + if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, + &offset) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + if (offset > ar->e_u.e_ar.e_rawstrtabsz) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + p = q = ar->e_u.e_ar.e_rawstrtab + offset; + r = ar->e_u.e_ar.e_rawstrtab + ar->e_u.e_ar.e_rawstrtabsz; + + for (; p < r && *p != '/'; p++) + ; + len = p - q + 1; /* space for the trailing NUL */ + + if ((s = malloc(len)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(s, q, len - 1); + s[len - 1] = '\0'; + + return (s); + } else if (IS_EXTENDED_BSD_NAME(buf)) { + r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE; + + if (_libelf_ar_get_number(r, bufsize - + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, + &len) == 0) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + + /* + * Allocate space for the file name plus a + * trailing NUL. + */ + if ((s = malloc(len + 1)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + /* + * The file name follows the archive header. + */ + q = (const char *) (arh + 1); + + (void) strncpy(s, q, len); + s[len] = '\0'; + + return (s); + } + + /* + * A 'normal' name. + * + * Skip back over trailing blanks from the end of the field. + * In the SVR4 format, a '/' is used as a terminator for + * non-special names. + */ + for (q = buf + bufsize - 1; q >= buf && *q == ' '; --q) + ; + + if (q >= buf) { + if (*q == '/') { + /* + * SVR4 style names: ignore the trailing + * character '/', but only if the name is not + * one of the special names "/" and "//". + */ + if (q > buf + 1 || + (q == (buf + 1) && *buf != '/')) + q--; + } + + len = q - buf + 2; /* Add space for a trailing NUL. */ + } else { + /* The buffer only had blanks. */ + buf = ""; + len = 1; + } + + if ((s = malloc(len)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(s, buf, len - 1); + s[len - 1] = '\0'; + + return (s); +} + +/* + * Return the raw name for an archive member, inclusive of any + * formatting characters. + */ +char * +_libelf_ar_get_raw_name(const struct ar_hdr *arh) +{ + char *rawname; + const size_t namesz = sizeof(arh->ar_name); + + if ((rawname = malloc(namesz + 1)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + (void) strncpy(rawname, arh->ar_name, namesz); + rawname[namesz] = '\0'; + return (rawname); +} + +/* + * Open an 'ar' archive. + */ +Elf * +_libelf_ar_open(Elf *e, int reporterror) +{ + size_t sz; + int scanahead; + char *s, *end; + struct ar_hdr arh; + + _libelf_init_elf(e, ELF_K_AR); + + e->e_u.e_ar.e_nchildren = 0; + e->e_u.e_ar.e_next = (off_t) -1; + + /* + * Look for special members. + */ + + s = e->e_rawfile + SARMAG; + end = e->e_rawfile + e->e_rawsize; + + assert(e->e_rawsize > 0); + + /* + * We use heuristics to determine the flavor of the archive we + * are examining. + * + * SVR4 flavor archives use the name "/ " and "// " for + * special members. + * + * In BSD flavor archives the symbol table, if present, is the + * first archive with name "__.SYMDEF". + */ + +#define READ_AR_HEADER(S, ARH, SZ, END) \ + do { \ + if ((S) + sizeof((ARH)) > (END)) \ + goto error; \ + (void) memcpy(&(ARH), (S), sizeof((ARH))); \ + if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \ + goto error; \ + if (_libelf_ar_get_number((ARH).ar_size, \ + sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ + goto error; \ + } while (0) + + READ_AR_HEADER(s, arh, sz, end); + + /* + * Handle special archive members for the SVR4 format. + */ + if (arh.ar_name[0] == '/') { + + assert(sz > 0); + + e->e_flags |= LIBELF_F_AR_VARIANT_SVR4; + + scanahead = 0; + + /* + * The symbol table (file name "/ ") always comes before the + * string table (file name "// "). + */ + if (arh.ar_name[1] == ' ') { + /* "/ " => symbol table. */ + scanahead = 1; /* The string table to follow. */ + + s += sizeof(arh); + e->e_u.e_ar.e_rawsymtab = s; + e->e_u.e_ar.e_rawsymtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + + } else if (arh.ar_name[1] == '/' && arh.ar_name[2] == ' ') { + /* "// " => string table for long file names. */ + s += sizeof(arh); + e->e_u.e_ar.e_rawstrtab = s; + e->e_u.e_ar.e_rawstrtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + + /* + * If the string table hasn't been seen yet, look for + * it in the next member. + */ + if (scanahead) { + READ_AR_HEADER(s, arh, sz, end); + + /* "// " => string table for long file names. */ + if (arh.ar_name[0] == '/' && arh.ar_name[1] == '/' && + arh.ar_name[2] == ' ') { + + s += sizeof(arh); + + e->e_u.e_ar.e_rawstrtab = s; + e->e_u.e_ar.e_rawstrtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + } + } else if (strncmp(arh.ar_name, LIBELF_AR_BSD_SYMTAB_NAME, + sizeof(LIBELF_AR_BSD_SYMTAB_NAME) - 1) == 0) { + /* + * BSD style archive symbol table. + */ + s += sizeof(arh); + e->e_u.e_ar.e_rawsymtab = s; + e->e_u.e_ar.e_rawsymtabsz = sz; + + sz = LIBELF_ADJUST_AR_SIZE(sz); + s += sz; + } + + /* + * Update the 'next' offset, so that a subsequent elf_begin() + * works as expected. + */ + e->e_u.e_ar.e_next = (off_t) (s - e->e_rawfile); + + return (e); + +error: + if (!reporterror) { + e->e_kind = ELF_K_NONE; + return (e); + } + + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); +} diff --git a/contrib/elftoolchain/libelf/libelf_checksum.c b/contrib/elftoolchain/libelf/libelf_checksum.c new file mode 100644 index 0000000..8f84aa4 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_checksum.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +static unsigned long +_libelf_sum(unsigned long c, const unsigned char *s, size_t size) +{ + if (s == NULL || size == 0) + return (c); + + while (size--) + c += *s++; + + return (c); +} + +unsigned long +_libelf_checksum(Elf *e, int elfclass) +{ + size_t shn; + Elf_Scn *scn; + Elf_Data *d; + unsigned long checksum; + GElf_Ehdr eh; + GElf_Shdr shdr; + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (0L); + } + + if (e->e_class != elfclass) { + LIBELF_SET_ERROR(CLASS, 0); + return (0L); + } + + if (gelf_getehdr(e, &eh) == NULL) + return (0); + + /* + * Iterate over all sections in the ELF file, computing the + * checksum along the way. + * + * The first section is always SHN_UNDEF and can be skipped. + * Non-allocatable sections are skipped, as are sections that + * could be affected by utilities such as strip(1). + */ + + checksum = 0; + for (shn = 1; shn < e->e_u.e_elf.e_nscn; shn++) { + if ((scn = elf_getscn(e, shn)) == NULL) + return (0); + if (gelf_getshdr(scn, &shdr) == NULL) + return (0); + if ((shdr.sh_flags & SHF_ALLOC) == 0 || + shdr.sh_type == SHT_DYNAMIC || + shdr.sh_type == SHT_DYNSYM) + continue; + + d = NULL; + while ((d = elf_rawdata(scn, d)) != NULL) + checksum = _libelf_sum(checksum, + (unsigned char *) d->d_buf, d->d_size); + } + + /* + * Return a 16-bit checksum compatible with Solaris. + */ + return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); +} diff --git a/contrib/elftoolchain/libelf/libelf_convert.m4 b/contrib/elftoolchain/libelf/libelf_convert.m4 new file mode 100644 index 0000000..0e0e4fd --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_convert.m4 @@ -0,0 +1,1086 @@ +/*- + * Copyright (c) 2006-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +divert(-1) + +# Generate conversion routines for converting between in-memory and +# file representations of Elf data structures. +# +# These conversions use the type information defined in `elf_types.m4'. + +include(SRCDIR`/elf_types.m4') + +# For the purposes of generating conversion code, ELF types may be +# classified according to the following characteristics: +# +# 1. Whether the ELF type can be directly mapped to an integral C +# language type. For example, the ELF_T_WORD type maps directly to +# a 'uint32_t', but ELF_T_GNUHASH lacks a matching C type. +# +# 2. Whether the type has word size dependent variants. For example, +# ELT_T_EHDR is represented using C types Elf32_Ehdr and El64_Ehdr, +# and the ELF_T_ADDR and ELF_T_OFF types have integral C types that +# can be 32- or 64- bit wide. +# +# 3. Whether the ELF types has a fixed representation or not. For +# example, the ELF_T_SYM type has a fixed size file representation, +# some types like ELF_T_NOTE and ELF_T_GNUHASH use a variable size +# representation. +# +# We use m4 macros to generate conversion code for ELF types that have +# a fixed size representation. Conversion functions for the remaining +# types are coded by hand. +# +#* Handling File and Memory Representations +# +# `In-memory' representations of an Elf data structure use natural +# alignments and native byte ordering. This allows pointer arithmetic +# and casting to work as expected. On the other hand, the `file' +# representation of an ELF data structure could possibly be packed +# tighter than its `in-memory' representation, and could be of a +# differing byte order. Reading ELF objects that are members of `ar' +# archives present an additional complication: `ar' pads file data to +# even addresses, so file data structures in an archive member +# residing inside an `ar' archive could be at misaligned memory +# addresses when brought into memory. +# +# In summary, casting the `char *' pointers that point to memory +# representations (i.e., source pointers for the *_tof() functions and +# the destination pointers for the *_tom() functions), is safe, as +# these pointers should be correctly aligned for the memory type +# already. However, pointers to file representations have to be +# treated as being potentially unaligned and no casting can be done. + +# NOCVT(TYPE) -- Do not generate the cvt[] structure entry for TYPE +define(`NOCVT',`define(`NOCVT_'$1,1)') + +# NOFUNC(TYPE) -- Do not generate a conversion function for TYPE +define(`NOFUNC',`define(`NOFUNC_'$1,1)') + +# IGNORE(TYPE) -- Completely ignore the type. +define(`IGNORE',`NOCVT($1)NOFUNC($1)') + +# Mark ELF types that should not be processed by the M4 macros below. + +# Types for which we use functions with non-standard names. +IGNORE(`BYTE') # Uses a wrapper around memcpy(). +IGNORE(`NOTE') # Not a fixed size type. + +# Types for which we supply hand-coded functions. +NOFUNC(`GNUHASH') # A type with complex internal structure. +NOFUNC(`VDEF') # See MAKE_VERSION_CONVERTERS below. +NOFUNC(`VNEED') # .. + +# Unimplemented types. +IGNORE(`MOVEP') + +# ELF types that don't exist in a 32-bit world. +NOFUNC(`XWORD32') +NOFUNC(`SXWORD32') + +# `Primitive' ELF types are those that are an alias for an integral +# type. As they have no internal structure, they can be copied using +# a `memcpy()', and byteswapped in straightforward way. +# +# Mark all ELF types that directly map to integral C types. +define(`PRIM_ADDR', 1) +define(`PRIM_BYTE', 1) +define(`PRIM_HALF', 1) +define(`PRIM_LWORD', 1) +define(`PRIM_OFF', 1) +define(`PRIM_SWORD', 1) +define(`PRIM_SXWORD', 1) +define(`PRIM_WORD', 1) +define(`PRIM_XWORD', 1) + +# Note the primitive types that are size-dependent. +define(`SIZEDEP_ADDR', 1) +define(`SIZEDEP_OFF', 1) + +# Generate conversion functions for primitive types. +# +# Macro use: MAKEPRIMFUNCS(ELFTYPE,CTYPE,TYPESIZE,SYMSIZE) +# `$1': Name of the ELF type. +# `$2': C structure name suffix. +# `$3': ELF class specifier for types, one of [`32', `64']. +# `$4': Additional ELF class specifier, one of [`', `32', `64']. +# +# Generates a pair of conversion functions. +define(`MAKEPRIMFUNCS',` +static int +_libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; + size_t c; + + (void) dsz; + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*s)); + return (1); + } + + for (c = 0; c < count; c++) { + t = *s++; + SWAP_$1$4(t); + WRITE_$1$4(dst,t); + } + + return (1); +} + +static int +_libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; + size_t c; + + if (dsz < count * sizeof(Elf$3_$2)) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count * sizeof(*d)); + return (1); + } + + for (c = 0; c < count; c++) { + READ_$1$4(src,t); + SWAP_$1$4(t); + *d++ = t; + } + + return (1); +} +') + +# +# Handling composite ELF types +# + +# SWAP_FIELD(FIELDNAME,ELFTYPE) -- Generate code to swap one field. +define(`SWAP_FIELD', + `ifdef(`SIZEDEP_'$2, + `SWAP_$2'SZ()`(t.$1); + ', + `SWAP_$2(t.$1); + ')') + +# SWAP_MEMBERS(STRUCT) -- Iterate over a structure definition. +define(`SWAP_MEMBERS', + `ifelse($#,1,`/**/', + `SWAP_FIELD($1)SWAP_MEMBERS(shift($@))')') + +# SWAP_STRUCT(CTYPE,SIZE) -- Generate code to swap an ELF structure. +define(`SWAP_STRUCT', + `pushdef(`SZ',$2)/* Swap an Elf$2_$1 */ + SWAP_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + +# WRITE_FIELD(ELFTYPE,FIELDNAME) -- Generate code to write one field. +define(`WRITE_FIELD', + `ifdef(`SIZEDEP_'$2, + `WRITE_$2'SZ()`(dst,t.$1); + ', + `WRITE_$2(dst,t.$1); + ')') + +# WRITE_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. +define(`WRITE_MEMBERS', + `ifelse($#,1,`/**/', + `WRITE_FIELD($1)WRITE_MEMBERS(shift($@))')') + +# WRITE_STRUCT(CTYPE,SIZE) -- Generate code to write out an ELF structure. +define(`WRITE_STRUCT', + `pushdef(`SZ',$2)/* Write an Elf$2_$1 */ + WRITE_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + +# READ_FIELD(ELFTYPE,CTYPE) -- Generate code to read one field. +define(`READ_FIELD', + `ifdef(`SIZEDEP_'$2, + `READ_$2'SZ()`(s,t.$1); + ', + `READ_$2(s,t.$1); + ')') + +# READ_MEMBERS(ELFTYPELIST) -- Iterate over a structure definition. +define(`READ_MEMBERS', + `ifelse($#,1,`/**/', + `READ_FIELD($1)READ_MEMBERS(shift($@))')') + +# READ_STRUCT(CTYPE,SIZE) -- Generate code to read an ELF structure. +define(`READ_STRUCT', + `pushdef(`SZ',$2)/* Read an Elf$2_$1 */ + READ_MEMBERS(Elf$2_$1_DEF)popdef(`SZ')') + + +# MAKECOMPFUNCS -- Generate converters for composite ELF structures. +# +# When converting data to file representation, the source pointer will +# be naturally aligned for a data structure's in-memory +# representation. When converting data to memory, the destination +# pointer will be similarly aligned. +# +# For in-place conversions, when converting to file representations, +# the source buffer is large enough to hold `file' data. When +# converting from file to memory, we need to be careful to work +# `backwards', to avoid overwriting unconverted data. +# +# Macro use: +# `$1': Name of the ELF type. +# `$2': C structure name suffix. +# `$3': ELF class specifier, one of [`', `32', `64'] +define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',` +static int +_libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$3_$2 t, *s; + size_t c; + + (void) dsz; + + s = (Elf$3_$2 *) (uintptr_t) src; + for (c = 0; c < count; c++) { + t = *s++; + if (byteswap) { + SWAP_STRUCT($2,$3) + } + WRITE_STRUCT($2,$3) + } + + return (1); +} + +static int +_libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$3_$2 t, *d; + char *s,*s0; + size_t fsz; + + fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT); + d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1); + s0 = (char *) src + (count - 1) * fsz; + + if (dsz < count * sizeof(Elf$3_$2)) + return (0); + + while (count--) { + s = s0; + READ_STRUCT($2,$3) + if (byteswap) { + SWAP_STRUCT($2,$3) + } + *d-- = t; s0 -= fsz; + } + + return (1); +} +')') + +# MAKE_TYPE_CONVERTER(ELFTYPE,CTYPE) +# +# Make type convertor functions from the type definition +# of the ELF type: +# - Skip convertors marked as `NOFUNC'. +# - Invoke `MAKEPRIMFUNCS' or `MAKECOMPFUNCS' as appropriate. +define(`MAKE_TYPE_CONVERTER', + `ifdef(`NOFUNC_'$1,`', + `ifdef(`PRIM_'$1, + `ifdef(`SIZEDEP_'$1, + `MAKEPRIMFUNCS($1,$2,32,32)dnl + MAKEPRIMFUNCS($1,$2,64,64)', + `MAKEPRIMFUNCS($1,$2,64)')', + `MAKECOMPFUNCS($1,$2,32)dnl + MAKECOMPFUNCS($1,$2,64)')')') + +# MAKE_TYPE_CONVERTERS(ELFTYPELIST) -- Generate conversion functions. +define(`MAKE_TYPE_CONVERTERS', + `ifelse($#,1,`', + `MAKE_TYPE_CONVERTER($1)MAKE_TYPE_CONVERTERS(shift($@))')') + + +# +# Macros to generate entries for the table of convertors. +# + +# CONV(ELFTYPE,SIZE,DIRECTION) +# +# Generate the name of a convertor function. +define(`CONV', + `ifdef(`NOFUNC_'$1$2, + `.$3$2 = NULL', + `ifdef(`PRIM_'$1, + `ifdef(`SIZEDEP_'$1, + `.$3$2 = _libelf_cvt_$1$2_$3', + `.$3$2 = _libelf_cvt_$1_$3')', + `.$3$2 = _libelf_cvt_$1$2_$3')')') + +# CONVERTER_NAME(ELFTYPE) +# +# Generate the contents of one `struct cvt' instance. +define(`CONVERTER_NAME', + `ifdef(`NOCVT_'$1,`', + ` [ELF_T_$1] = { + CONV($1,32,tof), + CONV($1,32,tom), + CONV($1,64,tof), + CONV($1,64,tom) + }, + +')') + +# CONVERTER_NAMES(ELFTYPELIST) +# +# Generate the `struct cvt[]' array. +define(`CONVERTER_NAMES', + `ifelse($#,1,`', + `CONVERTER_NAME($1)CONVERTER_NAMES(shift($@))')') + +# +# Handling ELF version sections. +# + +# _FSZ(FIELD,BASETYPE) - return the file size for a field. +define(`_FSZ', + `ifelse($2,`HALF',2, + $2,`WORD',4)') + +# FSZ(STRUCT) - determine the file size of a structure. +define(`FSZ', + `ifelse($#,1,0, + `eval(_FSZ($1) + FSZ(shift($@)))')') + +# MAKE_VERSION_CONVERTERS(TYPE,BASE,AUX,PFX) -- Generate conversion +# functions for versioning structures. +define(`MAKE_VERSION_CONVERTERS', + `MAKE_VERSION_CONVERTER($1,$2,$3,$4,32) + MAKE_VERSION_CONVERTER($1,$2,$3,$4,64)') + +# MAKE_VERSION_CONVERTOR(TYPE,CBASE,CAUX,PFX,SIZE) -- Generate a +# conversion function. +define(`MAKE_VERSION_CONVERTER',` +static int +_libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$5_$2 t; + Elf$5_$3 a; + const size_t verfsz = FSZ(Elf$5_$2_DEF); + const size_t auxfsz = FSZ(Elf$5_$3_DEF); + const size_t vermsz = sizeof(Elf$5_$2); + const size_t auxmsz = sizeof(Elf$5_$3); + char * const dstend = dst + dsz; + char * const srcend = src + count; + char *dtmp, *dstaux, *srcaux; + Elf$5_Word aux, anext, cnt, vnext; + + for (dtmp = dst, vnext = ~0; + vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; + dtmp += vnext, src += vnext) { + + /* Read in an Elf$5_$2 structure. */ + t = *((Elf$5_$2 *) (uintptr_t) src); + + aux = t.$4_aux; + cnt = t.$4_cnt; + vnext = t.$4_next; + + if (byteswap) { + SWAP_STRUCT($2, $5) + } + + dst = dtmp; + WRITE_STRUCT($2, $5) + + if (aux < verfsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; + cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && + srcaux + auxmsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + /* Read in an Elf$5_$3 structure. */ + a = *((Elf$5_$3 *) (uintptr_t) srcaux); + anext = a.$4a_next; + + if (byteswap) { + pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') + } + + dst = dstaux; + pushdef(`t',`a')WRITE_STRUCT($3, $5)popdef(`t') + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +} + +static int +_libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + Elf$5_$2 t, *dp; + Elf$5_$3 a, *ap; + const size_t verfsz = FSZ(Elf$5_$2_DEF); + const size_t auxfsz = FSZ(Elf$5_$3_DEF); + const size_t vermsz = sizeof(Elf$5_$2); + const size_t auxmsz = sizeof(Elf$5_$3); + char * const dstend = dst + dsz; + char * const srcend = src + count; + char *dstaux, *s, *srcaux, *stmp; + Elf$5_Word aux, anext, cnt, vnext; + + for (stmp = src, vnext = ~0; + vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; + stmp += vnext, dst += vnext) { + + /* Read in a $1 structure. */ + s = stmp; + READ_STRUCT($2, $5) + if (byteswap) { + SWAP_STRUCT($2, $5) + } + + dp = (Elf$5_$2 *) (uintptr_t) dst; + *dp = t; + + aux = t.$4_aux; + cnt = t.$4_cnt; + vnext = t.$4_next; + + if (aux < vermsz) + return (0); + + /* Process AUX entries. */ + for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; + cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && + srcaux + auxfsz <= srcend; + dstaux += anext, srcaux += anext, cnt--) { + + s = srcaux; + pushdef(`t',`a')READ_STRUCT($3, $5)popdef(`t') + + if (byteswap) { + pushdef(`t',`a')SWAP_STRUCT($3, $5)popdef(`t') + } + + anext = a.$4a_next; + + ap = ((Elf$5_$3 *) (uintptr_t) dstaux); + *ap = a; + } + + if (anext || cnt) + return (0); + } + + if (vnext) + return (0); + + return (1); +}') + +divert(0) + +/* + * C macros to byte swap integral quantities. + */ + +#define SWAP_BYTE(X) do { (void) (X); } while (0) +#define SWAP_IDENT(X) do { (void) (X); } while (0) +#define SWAP_HALF(X) do { \ + uint16_t _x = (uint16_t) (X); \ + uint16_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = _t; \ + } while (0) +#define SWAP_WORD(X) do { \ + uint32_t _x = (uint32_t) (X); \ + uint32_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = _t; \ + } while (0) +#define SWAP_ADDR32(X) SWAP_WORD(X) +#define SWAP_OFF32(X) SWAP_WORD(X) +#define SWAP_SWORD(X) SWAP_WORD(X) +#define SWAP_WORD64(X) do { \ + uint64_t _x = (uint64_t) (X); \ + uint64_t _t = _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ + (X) = _t; \ + } while (0) +#define SWAP_ADDR64(X) SWAP_WORD64(X) +#define SWAP_LWORD(X) SWAP_WORD64(X) +#define SWAP_OFF64(X) SWAP_WORD64(X) +#define SWAP_SXWORD(X) SWAP_WORD64(X) +#define SWAP_XWORD(X) SWAP_WORD64(X) + +/* + * C macros to write out various integral values. + * + * Note: + * - The destination pointer could be unaligned. + * - Values are written out in native byte order. + * - The destination pointer is incremented after the write. + */ +#define WRITE_BYTE(P,X) do { \ + char *const _p = (char *) (P); \ + _p[0] = (char) (X); \ + (P) = _p + 1; \ + } while (0) +#define WRITE_HALF(P,X) do { \ + uint16_t _t = (X); \ + char *const _p = (char *) (P); \ + const char *const _q = (char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + (P) = _p + 2; \ + } while (0) +#define WRITE_WORD(P,X) do { \ + uint32_t _t = (X); \ + char *const _p = (char *) (P); \ + const char *const _q = (char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + (P) = _p + 4; \ + } while (0) +#define WRITE_ADDR32(P,X) WRITE_WORD(P,X) +#define WRITE_OFF32(P,X) WRITE_WORD(P,X) +#define WRITE_SWORD(P,X) WRITE_WORD(P,X) +#define WRITE_WORD64(P,X) do { \ + uint64_t _t = (X); \ + char *const _p = (char *) (P); \ + const char *const _q = (char *) &_t; \ + _p[0] = _q[0]; \ + _p[1] = _q[1]; \ + _p[2] = _q[2]; \ + _p[3] = _q[3]; \ + _p[4] = _q[4]; \ + _p[5] = _q[5]; \ + _p[6] = _q[6]; \ + _p[7] = _q[7]; \ + (P) = _p + 8; \ + } while (0) +#define WRITE_ADDR64(P,X) WRITE_WORD64(P,X) +#define WRITE_LWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_OFF64(P,X) WRITE_WORD64(P,X) +#define WRITE_SXWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_XWORD(P,X) WRITE_WORD64(P,X) +#define WRITE_IDENT(P,X) do { \ + (void) memcpy((P), (X), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (0) + +/* + * C macros to read in various integral values. + * + * Note: + * - The source pointer could be unaligned. + * - Values are read in native byte order. + * - The source pointer is incremented appropriately. + */ + +#define READ_BYTE(P,X) do { \ + const char *const _p = \ + (const char *) (P); \ + (X) = _p[0]; \ + (P) = (P) + 1; \ + } while (0) +#define READ_HALF(P,X) do { \ + uint16_t _t; \ + char *const _q = (char *) &_t; \ + const char *const _p = \ + (const char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + (P) = (P) + 2; \ + (X) = _t; \ + } while (0) +#define READ_WORD(P,X) do { \ + uint32_t _t; \ + char *const _q = (char *) &_t; \ + const char *const _p = \ + (const char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + (P) = (P) + 4; \ + (X) = _t; \ + } while (0) +#define READ_ADDR32(P,X) READ_WORD(P,X) +#define READ_OFF32(P,X) READ_WORD(P,X) +#define READ_SWORD(P,X) READ_WORD(P,X) +#define READ_WORD64(P,X) do { \ + uint64_t _t; \ + char *const _q = (char *) &_t; \ + const char *const _p = \ + (const char *) (P); \ + _q[0] = _p[0]; \ + _q[1] = _p[1]; \ + _q[2] = _p[2]; \ + _q[3] = _p[3]; \ + _q[4] = _p[4]; \ + _q[5] = _p[5]; \ + _q[6] = _p[6]; \ + _q[7] = _p[7]; \ + (P) = (P) + 8; \ + (X) = _t; \ + } while (0) +#define READ_ADDR64(P,X) READ_WORD64(P,X) +#define READ_LWORD(P,X) READ_WORD64(P,X) +#define READ_OFF64(P,X) READ_WORD64(P,X) +#define READ_SXWORD(P,X) READ_WORD64(P,X) +#define READ_XWORD(P,X) READ_WORD64(P,X) +#define READ_IDENT(P,X) do { \ + (void) memcpy((X), (P), sizeof((X))); \ + (P) = (P) + EI_NIDENT; \ + } while (0) + +#define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) + +/*[*/ +MAKE_TYPE_CONVERTERS(ELF_TYPE_LIST) +MAKE_VERSION_CONVERTERS(VDEF,Verdef,Verdaux,vd) +MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) +/*]*/ + +/* + * Sections of type ELF_T_BYTE are never byteswapped, consequently a + * simple memcpy suffices for both directions of conversion. + */ + +static int +_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + (void) byteswap; + if (dsz < count) + return (0); + if (dst != src) + (void) memcpy(dst, src, count); + return (1); +} + +/* + * Sections of type ELF_T_GNUHASH start with a header containing 4 32-bit + * words. Bloom filter data comes next, followed by hash buckets and the + * hash chain. + * + * Bloom filter words are 64 bit wide on ELFCLASS64 objects and are 32 bit + * wide on ELFCLASS32 objects. The other objects in this section are 32 + * bits wide. + * + * Argument `srcsz' denotes the number of bytes to be converted. In the + * 32-bit case we need to translate `srcsz' to a count of 32-bit words. + */ + +static int +_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz, + int byteswap) +{ + return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz, + int byteswap) +{ + return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t), + byteswap)); +} + +static int +_libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz, + int byteswap) +{ + size_t sz; + uint64_t t64, *bloom64; + Elf_GNU_Hash_Header *gh; + uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; + uint32_t *buckets, *chains; + + sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ + if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) + return (0); + + /* Read in the section header and byteswap if needed. */ + READ_WORD(src, nbuckets); + READ_WORD(src, symndx); + READ_WORD(src, maskwords); + READ_WORD(src, shift2); + + srcsz -= sz; + + if (byteswap) { + SWAP_WORD(nbuckets); + SWAP_WORD(symndx); + SWAP_WORD(maskwords); + SWAP_WORD(shift2); + } + + /* Check source buffer and destination buffer sizes. */ + sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); + if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; + gh->gh_nbuckets = nbuckets; + gh->gh_symndx = symndx; + gh->gh_maskwords = maskwords; + gh->gh_shift2 = shift2; + + dsz -= sizeof(Elf_GNU_Hash_Header); + dst += sizeof(Elf_GNU_Hash_Header); + + bloom64 = (uint64_t *) (uintptr_t) dst; + + /* Copy bloom filter data. */ + for (n = 0; n < maskwords; n++) { + READ_XWORD(src, t64); + if (byteswap) + SWAP_XWORD(t64); + bloom64[n] = t64; + } + + /* The hash buckets follows the bloom filter. */ + dst += maskwords * sizeof(uint64_t); + buckets = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nbuckets; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + buckets[n] = t32; + } + + dst += nbuckets * sizeof(uint32_t); + + /* The hash chain follows the hash buckets. */ + dsz -= sz; + srcsz -= sz; + + if (dsz < srcsz) /* Destination lacks space. */ + return (0); + + nchains = srcsz / sizeof(uint32_t); + chains = (uint32_t *) (uintptr_t) dst; + + for (n = 0; n < nchains; n++) { + READ_WORD(src, t32); + if (byteswap) + SWAP_WORD(t32); + *chains++ = t32; + } + + return (1); +} + +static int +_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, + int byteswap) +{ + uint32_t *s32; + size_t sz, hdrsz; + uint64_t *s64, t64; + Elf_GNU_Hash_Header *gh; + uint32_t maskwords, n, nbuckets, nchains, t0, t1, t2, t3, t32; + + hdrsz = 4 * sizeof(uint32_t); /* Header is 4x32 bits. */ + if (dsz < hdrsz || srcsz < sizeof(Elf_GNU_Hash_Header)) + return (0); + + gh = (Elf_GNU_Hash_Header *) (uintptr_t) src; + + t0 = nbuckets = gh->gh_nbuckets; + t1 = gh->gh_symndx; + t2 = maskwords = gh->gh_maskwords; + t3 = gh->gh_shift2; + + src += sizeof(Elf_GNU_Hash_Header); + srcsz -= sizeof(Elf_GNU_Hash_Header); + dsz -= hdrsz; + + sz = gh->gh_nbuckets * sizeof(uint32_t) + gh->gh_maskwords * + sizeof(uint64_t); + + if (srcsz < sz || dsz < sz) + return (0); + + /* Write out the header. */ + if (byteswap) { + SWAP_WORD(t0); + SWAP_WORD(t1); + SWAP_WORD(t2); + SWAP_WORD(t3); + } + + WRITE_WORD(dst, t0); + WRITE_WORD(dst, t1); + WRITE_WORD(dst, t2); + WRITE_WORD(dst, t3); + + /* Copy the bloom filter and the hash table. */ + s64 = (uint64_t *) (uintptr_t) src; + for (n = 0; n < maskwords; n++) { + t64 = *s64++; + if (byteswap) + SWAP_XWORD(t64); + WRITE_WORD64(dst, t64); + } + + s32 = (uint32_t *) s64; + for (n = 0; n < nbuckets; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + srcsz -= sz; + dsz -= sz; + + /* Copy out the hash chains. */ + if (dsz < srcsz) + return (0); + + nchains = srcsz / sizeof(uint32_t); + for (n = 0; n < nchains; n++) { + t32 = *s32++; + if (byteswap) + SWAP_WORD(t32); + WRITE_WORD(dst, t32); + } + + return (1); +} + +/* + * Elf_Note structures comprise a fixed size header followed by variable + * length strings. The fixed size header needs to be byte swapped, but + * not the strings. + * + * Argument `count' denotes the total number of bytes to be converted. + * The destination buffer needs to be at least `count' bytes in size. + */ +static int +_libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz, hdrsz; + + if (dsz < count) /* Destination buffer is too small. */ + return (0); + + hdrsz = 3 * sizeof(uint32_t); + if (count < hdrsz) /* Source too small. */ + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + /* Process all notes in the section. */ + while (count > hdrsz) { + /* Read the note header. */ + READ_WORD(src, namesz); + READ_WORD(src, descsz); + READ_WORD(src, type); + + /* Translate. */ + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + /* Copy out the translated note header. */ + en = (Elf_Note *) (uintptr_t) dst; + en->n_namesz = namesz; + en->n_descsz = descsz; + en->n_type = type; + + dsz -= sizeof(Elf_Note); + dst += sizeof(Elf_Note); + count -= hdrsz; + + ROUNDUP2(namesz, 4); + ROUNDUP2(descsz, 4); + + sz = namesz + descsz; + + if (count < sz || dsz < sz) /* Buffers are too small. */ + return (0); + + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + + count -= sz; + dsz -= sz; + } + + return (1); +} + +static int +_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, + int byteswap) +{ + uint32_t namesz, descsz, type; + Elf_Note *en; + size_t sz; + + if (dsz < count) + return (0); + + if (!byteswap) { + (void) memcpy(dst, src, count); + return (1); + } + + while (count > sizeof(Elf_Note)) { + + en = (Elf_Note *) (uintptr_t) src; + namesz = en->n_namesz; + descsz = en->n_descsz; + type = en->n_type; + + SWAP_WORD(namesz); + SWAP_WORD(descsz); + SWAP_WORD(type); + + WRITE_WORD(dst, namesz); + WRITE_WORD(dst, descsz); + WRITE_WORD(dst, type); + + src += sizeof(Elf_Note); + + ROUNDUP2(namesz, 4); + ROUNDUP2(descsz, 4); + + sz = namesz + descsz; + + if (count < sz) + sz = count; + + (void) memcpy(dst, src, sz); + + src += sz; + dst += sz; + count -= sz; + } + + return (1); +} + +struct converters { + int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt, + int byteswap); + int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt, + int byteswap); + int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt, + int byteswap); + int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt, + int byteswap); +}; + + +static struct converters cvt[ELF_T_NUM] = { + /*[*/ +CONVERTER_NAMES(ELF_TYPE_LIST) + /*]*/ + + /* + * Types that need hand-coded converters follow. + */ + + [ELF_T_BYTE] = { + .tof32 = _libelf_cvt_BYTE_tox, + .tom32 = _libelf_cvt_BYTE_tox, + .tof64 = _libelf_cvt_BYTE_tox, + .tom64 = _libelf_cvt_BYTE_tox + }, + + [ELF_T_NOTE] = { + .tof32 = _libelf_cvt_NOTE_tof, + .tom32 = _libelf_cvt_NOTE_tom, + .tof64 = _libelf_cvt_NOTE_tof, + .tom64 = _libelf_cvt_NOTE_tom + } +}; + +int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) + (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) +{ + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + + if (t >= ELF_T_NUM || + (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || + (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) + return (NULL); + + return ((elfclass == ELFCLASS32) ? + (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : + (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); +} diff --git a/contrib/elftoolchain/libelf/libelf_data.c b/contrib/elftoolchain/libelf/libelf_data.c new file mode 100644 index 0000000..809002f --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_data.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_data.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +int +_libelf_xlate_shtype(uint32_t sht) +{ + switch (sht) { + case SHT_DYNAMIC: + return (ELF_T_DYN); + case SHT_DYNSYM: + return (ELF_T_SYM); + case SHT_FINI_ARRAY: + return (ELF_T_ADDR); + case SHT_GNU_HASH: + return (ELF_T_GNUHASH); + case SHT_GNU_LIBLIST: + return (ELF_T_WORD); + case SHT_GROUP: + return (ELF_T_WORD); + case SHT_HASH: + return (ELF_T_WORD); + case SHT_INIT_ARRAY: + return (ELF_T_ADDR); + case SHT_NOBITS: + return (ELF_T_BYTE); + case SHT_NOTE: + return (ELF_T_NOTE); + case SHT_PREINIT_ARRAY: + return (ELF_T_ADDR); + case SHT_PROGBITS: + return (ELF_T_BYTE); + case SHT_REL: + return (ELF_T_REL); + case SHT_RELA: + return (ELF_T_RELA); + case SHT_STRTAB: + return (ELF_T_BYTE); + case SHT_SYMTAB: + return (ELF_T_SYM); + case SHT_SYMTAB_SHNDX: + return (ELF_T_WORD); + case SHT_SUNW_dof: + return (ELF_T_BYTE); + case SHT_SUNW_move: + return (ELF_T_MOVE); + case SHT_SUNW_syminfo: + return (ELF_T_SYMINFO); + case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ + return (ELF_T_VDEF); + case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ + return (ELF_T_VNEED); + case SHT_SUNW_versym: /* == SHT_GNU_versym */ + return (ELF_T_HALF); + default: + return (-1); + } +} diff --git a/contrib/elftoolchain/libelf/libelf_ehdr.c b/contrib/elftoolchain/libelf/libelf_ehdr.c new file mode 100644 index 0000000..363a0a8 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_ehdr.c @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <libelf.h> +#include <stdlib.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_ehdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * Retrieve counts for sections, phdrs and the section string table index + * from section header #0 of the ELF object. + */ +static int +_libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, + uint16_t strndx) +{ + Elf_Scn *scn; + size_t fsz; + int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + uint32_t shtype; + + assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); + + fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); + assert(fsz > 0); + + if (e->e_rawsize < shoff + fsz) { /* raw file too small */ + LIBELF_SET_ERROR(HEADER, 0); + return (0); + } + + if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) + return (0); + + xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); + (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), + e->e_rawfile + shoff, (size_t) 1, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + +#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \ + scn->s_shdr.s_shdr64.M) + + if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { + LIBELF_SET_ERROR(SECTION, 0); + return (0); + } + + e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); + e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : + GET_SHDR_MEMBER(sh_info); + e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : + GET_SHDR_MEMBER(sh_link); +#undef GET_SHDR_MEMBER + + return (1); +} + +#define EHDR_INIT(E,SZ) do { \ + Elf##SZ##_Ehdr *eh = (E); \ + eh->e_ident[EI_MAG0] = ELFMAG0; \ + eh->e_ident[EI_MAG1] = ELFMAG1; \ + eh->e_ident[EI_MAG2] = ELFMAG2; \ + eh->e_ident[EI_MAG3] = ELFMAG3; \ + eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ + eh->e_ident[EI_DATA] = ELFDATANONE; \ + eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \ + eh->e_machine = EM_NONE; \ + eh->e_type = ELF_K_NONE; \ + eh->e_version = LIBELF_PRIVATE(version); \ + } while (0) + +void * +_libelf_ehdr(Elf *e, int ec, int allocate) +{ + void *ehdr; + size_t fsz, msz; + uint16_t phnum, shnum, strndx; + uint64_t shoff; + int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (e == NULL || e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (e->e_class != ELFCLASSNONE && e->e_class != ec) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if (e->e_version != EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return (NULL); + } + + if (e->e_class == ELFCLASSNONE) + e->e_class = ec; + + if (ec == ELFCLASS32) + ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; + else + ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; + + if (ehdr != NULL) /* already have a translated ehdr */ + return (ehdr); + + fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); + assert(fsz > 0); + + if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); + + assert(msz > 0); + + if ((ehdr = calloc((size_t) 1, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; + EHDR_INIT(ehdr,32); + } else { + e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; + EHDR_INIT(ehdr,64); + } + + if (allocate) + e->e_flags |= ELF_F_DIRTY; + + if (e->e_cmd == ELF_C_WRITE) + return (ehdr); + + xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); + (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + + /* + * If extended numbering is being used, read the correct + * number of sections and program header entries. + */ + if (ec == ELFCLASS32) { + phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; + shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; + shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; + strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; + } else { + phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; + shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; + shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; + strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; + } + + if (shnum >= SHN_LORESERVE || + (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || + strndx == SHN_XINDEX))) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ + e->e_u.e_elf.e_nphdr = phnum; + e->e_u.e_elf.e_nscn = shnum; + e->e_u.e_elf.e_strndx = strndx; + } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) + return (NULL); + + return (ehdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_extended.c b/contrib/elftoolchain/libelf/libelf_extended.c new file mode 100644 index 0000000..5343696 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_extended.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_extended.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * Retrieve section #0, allocating a new section if needed. + */ +static Elf_Scn * +_libelf_getscn0(Elf *e) +{ + Elf_Scn *s; + + if ((s = STAILQ_FIRST(&e->e_u.e_elf.e_scn)) != NULL) + return (s); + + return (_libelf_allocate_scn(e, (size_t) SHN_UNDEF)); +} + +int +_libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) +{ + Elf_Scn *scn; + + if (shnum >= SHN_LORESERVE) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_size = shnum; + else + scn->s_shdr.s_shdr64.sh_size = shnum; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + shnum = 0; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shnum = shnum; + else + ((Elf64_Ehdr *) eh)->e_shnum = shnum; + + + return (1); +} + +int +_libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) +{ + Elf_Scn *scn; + + if (shstrndx >= SHN_LORESERVE) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_link = shstrndx; + else + scn->s_shdr.s_shdr64.sh_link = shstrndx; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + shstrndx = SHN_XINDEX; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; + else + ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; + + return (1); +} + +int +_libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) +{ + Elf_Scn *scn; + + if (phnum >= PN_XNUM) { + if ((scn = _libelf_getscn0(e)) == NULL) + return (0); + + assert(scn->s_ndx == SHN_UNDEF); + + if (ec == ELFCLASS32) + scn->s_shdr.s_shdr32.sh_info = phnum; + else + scn->s_shdr.s_shdr64.sh_info = phnum; + + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); + + phnum = PN_XNUM; + } + + if (ec == ELFCLASS32) + ((Elf32_Ehdr *) eh)->e_phnum = phnum; + else + ((Elf64_Ehdr *) eh)->e_phnum = phnum; + + return (1); +} diff --git a/contrib/elftoolchain/libelf/libelf_fsize.m4 b/contrib/elftoolchain/libelf/libelf_fsize.m4 new file mode 100644 index 0000000..9942d27 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_fsize.m4 @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_fsize.m4 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +/* + * Create an array of file sizes from the elf_type definitions + */ + +divert(-1) +include(SRCDIR`/elf_types.m4') + +/* + * Translations from structure definitions to the size of their file + * representations. + */ + +/* `Basic' types. */ +define(`BYTE_SIZE', 1) +define(`IDENT_SIZE', `EI_NIDENT') + +/* Types that have variable length. */ +define(`GNUHASH_SIZE', 1) +define(`NOTE_SIZE', 1) +define(`VDEF_SIZE', 1) +define(`VNEED_SIZE', 1) + +/* Currently unimplemented types. */ +define(`MOVEP_SIZE', 0) + +/* Overrides for 32 bit types that do not exist. */ +define(`XWORD_SIZE32', 0) +define(`SXWORD_SIZE32', 0) + +/* + * FSZ{32,64} define the sizes of 32 and 64 bit file structures respectively. + */ + +define(`FSZ32',`_FSZ32($1_DEF)') +define(`_FSZ32', + `ifelse($#,1,0, + `_BSZ32($1)+_FSZ32(shift($@))')') +define(`_BSZ32',`$2_SIZE32') + +define(`FSZ64',`_FSZ64($1_DEF)') +define(`_FSZ64', + `ifelse($#,1,0, + `_BSZ64($1)+_FSZ64(shift($@))')') +define(`_BSZ64',`$2_SIZE64') + +/* + * DEFINE_ELF_FSIZES(TYPE,NAME) + * + * Shorthand for defining for 32 and 64 versions + * of elf type TYPE. + * + * If TYPE`'_SIZE is defined, use its value for both 32 bit and 64 bit + * sizes. + * + * Otherwise, look for a explicit 32/64 bit size definition for TYPE, + * TYPE`'_SIZE32 or TYPE`'_SIZE64. If this definition is present, there + * is nothing further to do. + * + * Otherwise, if an Elf{32,64}_`'NAME structure definition is known, + * compute an expression that adds up the sizes of the structure's + * constituents. + * + * If such a structure definition is not known, treat TYPE as a primitive + * (i.e., integral) type and use sizeof(Elf{32,64}_`'NAME) to get its + * file representation size. + */ + +define(`DEFINE_ELF_FSIZE', + `ifdef($1`_SIZE', + `define($1_SIZE32,$1_SIZE) + define($1_SIZE64,$1_SIZE)', + `ifdef($1`_SIZE32',`', + `ifdef(`Elf32_'$2`_DEF', + `define($1_SIZE32,FSZ32(Elf32_$2))', + `define($1_SIZE32,`sizeof(Elf32_'$2`)')')') + ifdef($1`_SIZE64',`', + `ifdef(`Elf64_'$2`_DEF', + `define($1_SIZE64,FSZ64(Elf64_$2))', + `define($1_SIZE64,`sizeof(Elf64_'$2`)')')')')') + +define(`DEFINE_ELF_FSIZES', + `ifelse($#,1,`', + `DEFINE_ELF_FSIZE($1) + DEFINE_ELF_FSIZES(shift($@))')') + +DEFINE_ELF_FSIZES(ELF_TYPE_LIST) +DEFINE_ELF_FSIZE(`IDENT',`') # `IDENT' is a pseudo type + +define(`FSIZE', + `[ELF_T_$1] = { .fsz32 = $1_SIZE32, .fsz64 = $1_SIZE64 }, +') +define(`FSIZES', + `ifelse($#,1,`', + `FSIZE($1) +FSIZES(shift($@))')') + +divert(0) + +struct fsize { + size_t fsz32; + size_t fsz64; +}; + +static struct fsize fsize[ELF_T_NUM] = { +FSIZES(ELF_TYPE_LIST) +}; + +size_t +_libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) +{ + size_t sz; + + sz = 0; + if (v != EV_CURRENT) + LIBELF_SET_ERROR(VERSION, 0); + else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) + LIBELF_SET_ERROR(ARGUMENT, 0); + else { + sz = ec == ELFCLASS64 ? fsize[t].fsz64 : fsize[t].fsz32; + if (sz == 0) + LIBELF_SET_ERROR(UNIMPL, 0); + } + + return (sz*c); +} diff --git a/contrib/elftoolchain/libelf/libelf_memory.c b/contrib/elftoolchain/libelf/libelf_memory.c new file mode 100644 index 0000000..892e909 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_memory.c @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <ar.h> +#include <assert.h> +#include <string.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); + +/* + * Create an ELF descriptor for a memory image, optionally reporting + * parse errors. + */ + +Elf * +_libelf_memory(char *image, size_t sz, int reporterror) +{ + Elf *e; + int e_class; + enum Elf_Error error; + unsigned int e_byteorder, e_version; + + assert(image != NULL); + assert(sz > 0); + + if ((e = _libelf_allocate_elf()) == NULL) + return (NULL); + + e->e_cmd = ELF_C_READ; + e->e_rawfile = image; + e->e_rawsize = sz; + +#undef LIBELF_IS_ELF +#define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ + (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ + (P)[EI_MAG3] == ELFMAG3) + + if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { + e_byteorder = image[EI_DATA]; + e_class = image[EI_CLASS]; + e_version = image[EI_VERSION]; + + error = ELF_E_NONE; + + if (e_version > EV_CURRENT) + error = ELF_E_VERSION; + else if ((e_byteorder != ELFDATA2LSB && e_byteorder != + ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class != + ELFCLASS64)) + error = ELF_E_HEADER; + + if (error != ELF_E_NONE) { + if (reporterror) { + LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0); + (void) _libelf_release_elf(e); + return (NULL); + } + } else { + _libelf_init_elf(e, ELF_K_ELF); + + e->e_byteorder = e_byteorder; + e->e_class = e_class; + e->e_version = e_version; + } + } else if (sz >= SARMAG && + strncmp(image, ARMAG, (size_t) SARMAG) == 0) + return (_libelf_ar_open(e, reporterror)); + + return (e); +} diff --git a/contrib/elftoolchain/libelf/libelf_msize.m4 b/contrib/elftoolchain/libelf/libelf_msize.m4 new file mode 100644 index 0000000..411019b --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_msize.m4 @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> +#include <string.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_msize.m4 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* WARNING: GENERATED FROM __file__. */ + +struct msize { + size_t msz32; + size_t msz64; +}; + +divert(-1) +include(SRCDIR`/elf_types.m4') + +/* + * ELF types whose memory representations have a variable size. + */ +define(BYTE_SIZE, 1) +define(GNUHASH_SIZE, 1) +define(NOTE_SIZE, 1) +define(VDEF_SIZE, 1) +define(VNEED_SIZE, 1) + +/* + * Unimplemented types. + */ +define(MOVEP_SIZE, 0) +define(SXWORD_SIZE32, 0) +define(XWORD_SIZE32, 0) + +define(`DEFINE_ELF_MSIZE', + `ifdef($1`_SIZE', + `define($1_SIZE32,$1_SIZE) + define($1_SIZE64,$1_SIZE)', + `ifdef($1`_SIZE32',`', + `define($1_SIZE32,sizeof(Elf32_$2))') + ifdef($1`_SIZE64',`', + `define($1_SIZE64,sizeof(Elf64_$2))')')') +define(`DEFINE_ELF_MSIZES', + `ifelse($#,1,`', + `DEFINE_ELF_MSIZE($1) + DEFINE_ELF_MSIZES(shift($@))')') + +DEFINE_ELF_MSIZES(ELF_TYPE_LIST) + +define(`MSIZE', + `[ELF_T_$1] = { .msz32 = $1_SIZE32, .msz64 = $1_SIZE64 }, +') +define(`MSIZES', + `ifelse($#,1,`', + `MSIZE($1) +MSIZES(shift($@))')') + +divert(0) + +static struct msize msize[ELF_T_NUM] = { +MSIZES(ELF_TYPE_LIST) +}; + +size_t +_libelf_msize(Elf_Type t, int elfclass, unsigned int version) +{ + size_t sz; + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); + + if (version != EV_CURRENT) { + LIBELF_SET_ERROR(VERSION, 0); + return (0); + } + + sz = (elfclass == ELFCLASS32) ? msize[t].msz32 : msize[t].msz64; + + return (sz); +} diff --git a/contrib/elftoolchain/libelf/libelf_open.c b/contrib/elftoolchain/libelf/libelf_open.c new file mode 100644 index 0000000..6d93c73 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_open.c @@ -0,0 +1,249 @@ +/*- + * Copyright (c) 2006,2008-2011 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <assert.h> +#include <errno.h> +#include <libelf.h> +#include <stdlib.h> +#include <unistd.h> + +#include "_libelf.h" + +#if ELFTC_HAVE_MMAP +#include <sys/mman.h> +#endif + +ELFTC_VCSID("$Id: libelf_open.c 2932 2013-03-30 01:26:04Z jkoshy $"); + +#define _LIBELF_INITSIZE (64*1024) + +/* + * Read from a device file, pipe or socket. + */ +static void * +_libelf_read_special_file(int fd, size_t *fsz) +{ + ssize_t readsz; + size_t bufsz, datasz; + unsigned char *buf, *t; + + datasz = 0; + readsz = 0; + bufsz = _LIBELF_INITSIZE; + if ((buf = malloc(bufsz)) == NULL) + goto resourceerror; + + /* + * Read data from the file descriptor till we reach EOF, or + * till an error is encountered. + */ + do { + /* Check if we need to expand the data buffer. */ + if (datasz == bufsz) { + bufsz *= 2; + if ((t = realloc(buf, bufsz)) == NULL) + goto resourceerror; + buf = t; + } + + do { + readsz = bufsz - datasz; + t = buf + datasz; + if ((readsz = read(fd, t, readsz)) <= 0) + break; + datasz += readsz; + } while (datasz < bufsz); + + } while (readsz > 0); + + if (readsz < 0) { + LIBELF_SET_ERROR(IO, errno); + goto error; + } + + assert(readsz == 0); + + /* + * Free up extra buffer space. + */ + if (bufsz > datasz) { + if (datasz > 0) { + if ((t = realloc(buf, datasz)) == NULL) + goto resourceerror; + buf = t; + } else { /* Zero bytes read. */ + LIBELF_SET_ERROR(ARGUMENT, 0); + free(buf); + buf = NULL; + } + } + + *fsz = datasz; + return (buf); + +resourceerror: + LIBELF_SET_ERROR(RESOURCE, 0); +error: + if (buf != NULL) + free(buf); + return (NULL); +} + +/* + * Read the contents of the file referenced by the file descriptor + * 'fd'. + */ + +Elf * +_libelf_open_object(int fd, Elf_Cmd c, int reporterror) +{ + Elf *e; + void *m; + mode_t mode; + size_t fsize; + struct stat sb; + unsigned int flags; + + assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); + + if (fstat(fd, &sb) < 0) { + LIBELF_SET_ERROR(IO, errno); + return (NULL); + } + + mode = sb.st_mode; + fsize = (size_t) sb.st_size; + + /* + * Reject unsupported file types. + */ + if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && + !S_ISSOCK(mode)) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + /* + * For ELF_C_WRITE mode, allocate and return a descriptor. + */ + if (c == ELF_C_WRITE) { + if ((e = _libelf_allocate_elf()) != NULL) { + _libelf_init_elf(e, ELF_K_ELF); + e->e_byteorder = LIBELF_PRIVATE(byteorder); + e->e_fd = fd; + e->e_cmd = c; + if (!S_ISREG(mode)) + e->e_flags |= LIBELF_F_SPECIAL_FILE; + } + + return (e); + } + + + /* + * ELF_C_READ and ELF_C_RDWR mode. + */ + m = NULL; + flags = 0; + if (S_ISREG(mode)) { + + /* + * Reject zero length files. + */ + if (fsize == 0) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + +#if ELFTC_HAVE_MMAP + /* + * Always map regular files in with 'PROT_READ' + * permissions. + * + * For objects opened in ELF_C_RDWR mode, when + * elf_update(3) is called, we remove this mapping, + * write file data out using write(2), and map the new + * contents back. + */ + m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0); + + if (m == MAP_FAILED) + m = NULL; + else + flags = LIBELF_F_RAWFILE_MMAP; +#endif + + /* + * Fallback to a read() if the call to mmap() failed, + * or if mmap() is not available. + */ + if (m == NULL) { + if ((m = malloc(fsize)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (read(fd, m, fsize) != (ssize_t) fsize) { + LIBELF_SET_ERROR(IO, errno); + free(m); + return (NULL); + } + + flags = LIBELF_F_RAWFILE_MALLOC; + } + } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) + flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; + else + return (NULL); + + if ((e = _libelf_memory(m, fsize, reporterror)) == NULL) { + assert((flags & LIBELF_F_RAWFILE_MALLOC) || + (flags & LIBELF_F_RAWFILE_MMAP)); + if (flags & LIBELF_F_RAWFILE_MALLOC) + free(m); +#if ELFTC_HAVE_MMAP + else + (void) munmap(m, fsize); +#endif + return (NULL); + } + + /* ar(1) archives aren't supported in RDWR mode. */ + if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { + (void) elf_end(e); + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + e->e_flags |= flags; + e->e_fd = fd; + e->e_cmd = c; + + return (e); +} diff --git a/contrib/elftoolchain/libelf/libelf_phdr.c b/contrib/elftoolchain/libelf/libelf_phdr.c new file mode 100644 index 0000000..f2eb697 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_phdr.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <gelf.h> +#include <libelf.h> +#include <stdlib.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_phdr.c 2931 2013-03-23 11:41:07Z jkoshy $"); + +void * +_libelf_getphdr(Elf *e, int ec) +{ + size_t phnum; + size_t fsz, msz; + uint64_t phoff; + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + void *ehdr, *phdr; + int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((phdr = (ec == ELFCLASS32 ? + (void *) e->e_u.e_elf.e_phdr.e_phdr32 : + (void *) e->e_u.e_elf.e_phdr.e_phdr64)) != NULL) + return (phdr); + + /* + * Check the PHDR related fields in the EHDR for sanity. + */ + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) + return (NULL); + + phnum = e->e_u.e_elf.e_nphdr; + + if (ec == ELFCLASS32) { + eh32 = (Elf32_Ehdr *) ehdr; + phoff = (uint64_t) eh32->e_phoff; + } else { + eh64 = (Elf64_Ehdr *) ehdr; + phoff = (uint64_t) eh64->e_phoff; + } + + fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); + + assert(fsz > 0); + + if ((uint64_t) e->e_rawsize < (phoff + fsz)) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); + + assert(msz > 0); + + if ((phdr = calloc(phnum, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) + e->e_u.e_elf.e_phdr.e_phdr32 = phdr; + else + e->e_u.e_elf.e_phdr.e_phdr64 = phdr; + + + xlator = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec); + (*xlator)(phdr, phnum * msz, e->e_rawfile + phoff, phnum, + e->e_byteorder != LIBELF_PRIVATE(byteorder)); + + return (phdr); +} + +void * +_libelf_newphdr(Elf *e, int ec, size_t count) +{ + void *ehdr, *newphdr, *oldphdr; + size_t msz; + + if (e == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) { + LIBELF_SET_ERROR(SEQUENCE, 0); + return (NULL); + } + + assert(e->e_class == ec); + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + assert(e->e_version == EV_CURRENT); + + msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version); + + assert(msz > 0); + + newphdr = NULL; + if (count > 0 && (newphdr = calloc(count, msz)) == NULL) { + LIBELF_SET_ERROR(RESOURCE, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr32) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr32 = (Elf32_Phdr *) newphdr; + } else { + if ((oldphdr = (void *) e->e_u.e_elf.e_phdr.e_phdr64) != NULL) + free(oldphdr); + e->e_u.e_elf.e_phdr.e_phdr64 = (Elf64_Phdr *) newphdr; + } + + e->e_u.e_elf.e_nphdr = count; + + elf_flagphdr(e, ELF_C_SET, ELF_F_DIRTY); + + return (newphdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_shdr.c b/contrib/elftoolchain/libelf/libelf_shdr.c new file mode 100644 index 0000000..fc48423 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_shdr.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <gelf.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_shdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +void * +_libelf_getshdr(Elf_Scn *s, int ec) +{ + Elf *e; + + if (s == NULL || (e = s->s_elf) == NULL || + e->e_kind != ELF_K_ELF) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if (ec == ELFCLASSNONE) + ec = e->e_class; + + if (ec != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + return ((void *) &s->s_shdr); +} diff --git a/contrib/elftoolchain/libelf/libelf_xlate.c b/contrib/elftoolchain/libelf/libelf_xlate.c new file mode 100644 index 0000000..eda6df8 --- /dev/null +++ b/contrib/elftoolchain/libelf/libelf_xlate.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 2006,2008 Joseph Koshy + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> + +#include <assert.h> +#include <libelf.h> + +#include "_libelf.h" + +ELFTC_VCSID("$Id: libelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); + +/* + * Translate to/from the file representation of ELF objects. + * + * Translation could potentially involve the following + * transformations: + * + * - an endianness conversion, + * - a change of layout, as the file representation of ELF objects + * can differ from their in-memory representation. + * - a change in representation due to a layout version change. + */ + +Elf_Data * +_libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, + int elfclass, int direction) +{ + int byteswap; + size_t cnt, dsz, fsz, msz; + uintptr_t sb, se, db, de; + + if (encoding == ELFDATANONE) + encoding = LIBELF_PRIVATE(byteorder); + + if ((encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) || + dst == NULL || src == NULL || dst == src) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); + assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + + if (dst->d_version != src->d_version) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (NULL); + } + + if (src->d_buf == NULL || dst->d_buf == NULL) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((int) src->d_type < 0 || src->d_type >= ELF_T_NUM) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((fsz = (elfclass == ELFCLASS32 ? elf32_fsize : elf64_fsize) + (src->d_type, (size_t) 1, src->d_version)) == 0) + return (NULL); + + msz = _libelf_msize(src->d_type, elfclass, src->d_version); + + assert(msz > 0); + + if (src->d_size % (direction == ELF_TOMEMORY ? fsz : msz)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + /* + * Determine the number of objects that need to be converted, and + * the space required for the converted objects in the destination + * buffer. + */ + if (direction == ELF_TOMEMORY) { + cnt = src->d_size / fsz; + dsz = cnt * msz; + } else { + cnt = src->d_size / msz; + dsz = cnt * fsz; + } + + if (dst->d_size < dsz) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + sb = (uintptr_t) src->d_buf; + se = sb + src->d_size; + db = (uintptr_t) dst->d_buf; + de = db + dst->d_size; + + /* + * Check for overlapping buffers. Note that db == sb is + * allowed. + */ + if (db != sb && de > sb && se > db) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + if ((direction == ELF_TOMEMORY ? db : sb) % + _libelf_malign(src->d_type, elfclass)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + dst->d_type = src->d_type; + dst->d_size = dsz; + + byteswap = encoding != LIBELF_PRIVATE(byteorder); + + if (src->d_size == 0 || + (db == sb && !byteswap && fsz == msz)) + return (dst); /* nothing more to do */ + + if (!(_libelf_get_translator(src->d_type, direction, elfclass)) + (dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { + LIBELF_SET_ERROR(DATA, 0); + return (NULL); + } + + return (dst); +} diff --git a/contrib/elftoolchain/libelf/os.FreeBSD.mk b/contrib/elftoolchain/libelf/os.FreeBSD.mk new file mode 100644 index 0000000..72834b7 --- /dev/null +++ b/contrib/elftoolchain/libelf/os.FreeBSD.mk @@ -0,0 +1,7 @@ +# +# Building for a FreeBSD target. +# +# $Id: os.FreeBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ + +# Symbol versioning support [FreeBSD 7.X and later] +VERSION_MAP= ${.CURDIR}/Version.map diff --git a/contrib/elftoolchain/libelf/os.NetBSD.mk b/contrib/elftoolchain/libelf/os.NetBSD.mk new file mode 100644 index 0000000..96b8335 --- /dev/null +++ b/contrib/elftoolchain/libelf/os.NetBSD.mk @@ -0,0 +1,7 @@ +# +# Build recipes for NetBSD. +# +# $Id: os.NetBSD.mk 710 2010-02-17 14:21:38Z jkoshy $ +# + +MKLINT= no # lint dies with a sigbus |