diff options
author | Ed Maste <emaste@FreeBSD.org> | 2014-12-22 20:32:23 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2014-12-22 20:32:23 +0000 |
commit | 5eccfb5cf5403e9e564066e0a75d80534b49e91d (patch) | |
tree | 78347950207dea134308b7c9d4843204e80507e0 | |
parent | 5265ace0e440a23fb522c516f4ee20f43eaed2b3 (diff) |
Import elftoolchain rev 3130vendor/elftoolchain/elftoolchain-r3130
From svn.code.sf.net/p/elftoolchain/code/trunk
Notes
Notes:
svn path=/vendor/elftoolchain/dist/; revision=276077
svn path=/vendor/elftoolchain/elftoolchain-r3130/; revision=276078; tag=vendor/elftoolchain/elftoolchain-r3130
168 files changed, 3849 insertions, 1492 deletions
@@ -19,6 +19,7 @@ operating systems. NetBSD_ v5.0.2 i386 OpenBSD_ v5.0 i386 Ubuntu_ GNU/Linux 10.04LTS i386 & x86_64 + Ubuntu_ GNU/Linux 12.04LTS i386 & x86_64 ================= ======== ======================= .. _DragonFly BSD: http://www.dragonflybsd.org/ @@ -114,6 +115,26 @@ Prerequisites - Building additional documentation is not currently supported under OpenBSD. +:OpenBSD 5.4: + - The following packages are pre-requisites for building the + sources on OpenBSD 5.4: + + =================== ===================================== + **Package** **Description** + =================== ===================================== + ``libarchive`` An archive access library. + =================== ===================================== + + The following command line may be used to install the necessary + pre-requisites:: + + # pkg_add libarchive + + - The test suites cannot currently be built under OpenBSD. + + - Building additional documentation is not currently supported + under OpenBSD. + :NetBSD 5.0.2: - The core libraries and utilities should build out of the box on a stock install of NetBSD. @@ -174,16 +195,16 @@ Prerequisites % sudo apt-get install pgf -:Ubuntu GNU/Linux 11.10: +:Ubuntu GNU/Linux 12.04: - The following packages are pre-requisites for building the - sources on Ubuntu GNU/Linux 11.10: + sources on Ubuntu GNU/Linux 12.04: =================== ===================================== **Package** **Description** =================== ===================================== ``bison`` Parser generator. + ``build-essential`` Basic build tools. ``flex`` Lexical analyser. - ``gcc`` C compiler. ``libarchive-dev`` Archive access library. ``libexpat1-dev`` An XML processing library. ``m4`` Macro processor. @@ -195,7 +216,7 @@ Prerequisites The following command line may be used to install the necessary pre-requisites:: - % sudo apt-get install bison flex gcc libarchive-dev \ + % sudo apt-get install bison build-essential flex libarchive-dev \ m4 pmake - To build and run the test suite: @@ -210,7 +231,7 @@ Prerequisites % sudo apt-get install libexpat1-dev python-yaml sharutils - Builds of additional documentation are not currently supported - under Ubuntu GNU/Linux 11.10. + under Ubuntu GNU/Linux 12.04. .. _Test Execution Toolkit: http://tetworks.opengroup.org/ .. _OpenGroup: http://www.opengroup.org/ @@ -276,7 +297,7 @@ website`_. .. _project website: http://elftoolchain.sourceforge.net/ -.. $Id: INSTALL 2777 2012-12-12 17:21:36Z jkoshy $ +.. $Id: INSTALL 3020 2014-04-17 15:52:31Z jkoshy $ .. Local Variables: .. mode: rst @@ -1,4 +1,4 @@ -# $Id: Makefile 2872 2013-01-07 13:57:54Z jkoshy $ +# $Id: Makefile 3016 2014-04-10 16:01:42Z jkoshy $ TOP= . @@ -15,7 +15,8 @@ SUBDIR += libdwarf SUBDIR += libelftc # Build the tools needed for the rest of the build. -SUBDIR += isa + +# SUBDIR += isa # ('isa' does not build on all platforms yet). # Build tools after the libraries. SUBDIR += addr2line diff --git a/ar/Makefile b/ar/Makefile index c20a9f7ffbd1..ddd811338d92 100644 --- a/ar/Makefile +++ b/ar/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2741 2012-12-10 18:47:00Z jkoshy $ +# $Id: Makefile 3107 2014-12-20 08:31:58Z kaiwang27 $ TOP= .. @@ -9,8 +9,8 @@ YSRC= acpyacc.y WARNS?= 5 -DPADD= ${LIBARCHIVE} ${LIBELFTC} ${LIBELF} -LDADD= -larchive -lelftc -lelf +DPADD= ${LIBARCHIVE} ${LIBELFTC} ${LIBELF} ${LIBZ} +LDADD= -larchive -lelftc -lelf -lz CFLAGS+=-I. -I${.CURDIR} diff --git a/ar/acpyacc.y b/ar/acpyacc.y index bbe26e021dbf..e1d02ec82513 100644 --- a/ar/acpyacc.y +++ b/ar/acpyacc.y @@ -253,13 +253,12 @@ arscp_open(char *fname) if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, 0, "archive_read_new failed"); - archive_read_support_compression_none(a); archive_read_support_format_ar(a); - AC(archive_read_open_file(a, fname, DEF_BLKSZ)); + AC(archive_read_open_filename(a, fname, DEF_BLKSZ)); if ((r = archive_read_next_header(a, &entry))) bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); AC(archive_read_close(a)); - ACV(archive_read_finish(a)); + ACV(archive_read_free(a)); if (r != ARCHIVE_OK) return; arscp_create(fname, fname); @@ -317,7 +316,7 @@ arscp_create(char *in, char *out) archive_write_set_format_ar_svr4(a); AC(archive_write_open_fd(a, ofd)); AC(archive_write_close(a)); - ACV(archive_write_finish(a)); + ACV(archive_write_free(a)); } /* Override the previous target, if any. */ diff --git a/ar/os.Linux.mk b/ar/os.Linux.mk new file mode 100644 index 000000000000..daed864eee9e --- /dev/null +++ b/ar/os.Linux.mk @@ -0,0 +1,9 @@ +.if ${OS_DISTRIBUTION} == "Ubuntu" +.if ${OS_DISTRIBUTION_VERSION} >= 14 +# Ubuntu Trusty Tahr and later. + +# Use the --nounput option to flex(1), to prevent unused functions from +# being generated. +LFLAGS += --nounput +.endif +.endif diff --git a/ar/read.c b/ar/read.c index 6c2affe57438..4e79ff2568ae 100644 --- a/ar/read.c +++ b/ar/read.c @@ -39,7 +39,7 @@ #include "ar.h" -ELFTC_VCSID("$Id: read.c 2229 2011-11-27 13:25:37Z jkoshy $"); +ELFTC_VCSID("$Id: read.c 3102 2014-10-29 21:09:01Z jkoshy $"); /* * Handle read modes: 'x', 't' and 'p'. @@ -68,9 +68,8 @@ ar_read_archive(struct bsdar *bsdar, int mode) if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, 0, "archive_read_new failed"); - archive_read_support_compression_none(a); archive_read_support_format_ar(a); - AC(archive_read_open_file(a, bsdar->filename, DEF_BLKSZ)); + AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ)); out = bsdar->output; @@ -188,5 +187,5 @@ ar_read_archive(struct bsdar *bsdar, int mode) } } AC(archive_read_close(a)); - ACV(archive_read_finish(a)); + ACV(archive_read_free(a)); } diff --git a/ar/write.c b/ar/write.c index f637d378f226..490b22fab07b 100644 --- a/ar/write.c +++ b/ar/write.c @@ -41,7 +41,7 @@ #include "ar.h" -ELFTC_VCSID("$Id: write.c 2496 2012-04-24 02:33:40Z jkoshy $"); +ELFTC_VCSID("$Id: write.c 3102 2014-10-29 21:09:01Z jkoshy $"); #define _ARMAG_LEN 8 /* length of the magic string */ #define _ARHDR_LEN 60 /* length of the archive header */ @@ -259,7 +259,6 @@ read_objs(struct bsdar *bsdar, const char *archive, int checkargv) if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, 0, "archive_read_new failed"); - archive_read_support_compression_none(a); archive_read_support_format_ar(a); AC(archive_read_open_filename(a, archive, DEF_BLKSZ)); for (;;) { @@ -349,7 +348,7 @@ read_objs(struct bsdar *bsdar, const char *archive, int checkargv) TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); } AC(archive_read_close(a)); - ACV(archive_read_finish(a)); + ACV(archive_read_free(a)); } /* @@ -732,7 +731,6 @@ write_objs(struct bsdar *bsdar) archive_write_set_format_ar_bsd(a); else archive_write_set_format_ar_svr4(a); - archive_write_set_compression_none(a); AC(archive_write_open_filename(a, bsdar->filename)); @@ -795,7 +793,7 @@ write_objs(struct bsdar *bsdar) } AC(archive_write_close(a)); - ACV(archive_write_finish(a)); + ACV(archive_write_free(a)); } /* diff --git a/brandelf/brandelf.1 b/brandelf/brandelf.1 index 5665b412bb41..5913360d87bd 100644 --- a/brandelf/brandelf.1 +++ b/brandelf/brandelf.1 @@ -26,9 +26,9 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD: src/usr.bin/brandelf/brandelf.1,v 1.17 2007/03/09 14:36:18 ru Exp $ -.\" $Id: brandelf.1 2245 2011-11-29 08:11:00Z jkoshy $ +.\" $Id: brandelf.1 3101 2014-10-27 22:24:40Z jkoshy $ .\" -.Dd November 29, 2011 +.Dd October 27, 2014 .Dt BRANDELF 1 .Os .Sh NAME @@ -90,7 +90,9 @@ Supported ABIs include and .Dq Li Tru64 . .It Fl v -Turns on verbose output. +This option is accepted for compatibility with other versions of +.Nm , +but is otherwise ignored. .It Fl V | Fl -version Print a version identifier and exit. .El diff --git a/brandelf/brandelf.c b/brandelf/brandelf.c index fac218750ee7..286b6ab12359 100644 --- a/brandelf/brandelf.c +++ b/brandelf/brandelf.c @@ -46,7 +46,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: brandelf.c 2324 2011-12-12 06:36:27Z jkoshy $"); +ELFTC_VCSID("$Id: brandelf.c 3101 2014-10-27 22:24:40Z jkoshy $"); static int elftype(const char *); static const char *iselftype(int); @@ -96,7 +96,7 @@ main(int argc, char **argv) Elf_Kind kind; int type = ELFOSABI_NONE; int retval = 0; - int ch, change = 0, verbose = 0, force = 0, listed = 0; + int ch, change = 0, force = 0, listed = 0; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "elf_version error"); @@ -124,7 +124,7 @@ main(int argc, char **argv) listed = 1; break; case 'v': - verbose = 1; + /* This flag is ignored. */ break; case 't': if (force) @@ -256,7 +256,6 @@ Usage: %s [options] file...\n\ -h | --help Print a usage message and exit.\n\ -l List known ELF ABI names.\n\ -t ABI Set the ELF ABI to the value named by \"ABI\".\n\ - -v Be verbose.\n\ -V | --version Print a version identifier and exit.\n" static void diff --git a/common/Makefile b/common/Makefile index d3df246e78fc..9551bcd20f34 100644 --- a/common/Makefile +++ b/common/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2606 2012-10-02 17:52:57Z jkoshy $ +# $Id: Makefile 3022 2014-04-17 18:05:58Z jkoshy $ TOP= .. @@ -12,4 +12,7 @@ all depend obj: clean clobber: rm -f ${CLEANFILES} +cleandepend: + rm -f .depend + .include "${TOP}/mk/elftoolchain.inc.mk" diff --git a/common/elfdefinitions.h b/common/elfdefinitions.h index 7bed9a19a0dc..f63dc7f2178d 100644 --- a/common/elfdefinitions.h +++ b/common/elfdefinitions.h @@ -23,7 +23,7 @@ * 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 $ + * $Id: elfdefinitions.h 3110 2014-12-20 08:32:46Z kaiwang27 $ */ /* @@ -770,6 +770,8 @@ _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_AARCH64, 183, \ + "AArch64 (64-bit ARM)") \ _ELF_DEFINE_EM(EM_AVR32, 185, \ "Atmel Corporation 32-bit microprocessor family") \ _ELF_DEFINE_EM(EM_STM8, 186, \ @@ -819,7 +821,8 @@ enum { EM__LAST__ }; -/* Older synonyms. */ +/* Other synonyms. */ +#define EM_AMD64 EM_X86_64 #define EM_ARC_A5 EM_ARC_COMPACT /* @@ -2112,11 +2115,11 @@ typedef struct { /* 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_Word l_name; /* The name of a shared object. */ + Elf64_Word l_time_stamp; /* 32-bit timestamp. */ + Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */ + Elf64_Word l_version; /* Interface version string index. */ + Elf64_Word l_flags; /* Flags (LL_*). */ } Elf64_Lib; #define _ELF_DEFINE_LL_FLAGS() \ @@ -2364,12 +2367,12 @@ typedef struct { /* 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_Word p_flags; /* Segment flags. */ + Elf64_Off p_offset; /* File offset to segment. */ + Elf64_Addr p_vaddr; /* Virtual address in memory. */ + Elf64_Addr p_paddr; /* Physical address (if relevant). */ + Elf64_Xword p_filesz; /* Size of segment in file. */ + Elf64_Xword p_memsz; /* Size of segment in memory. */ Elf64_Xword p_align; /* Alignment constraints. */ } Elf64_Phdr; @@ -2453,11 +2456,11 @@ typedef struct { 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 */ + unsigned char st_info; /* type and binding attributes */ + unsigned char st_other; /* visibility */ + Elf64_Half st_shndx; /* index of related section */ + Elf64_Addr st_value; /* value for the symbol */ + Elf64_Xword st_size; /* size of associated data */ } Elf64_Sym; #define ELF32_ST_BIND(I) ((I) >> 4) diff --git a/elfcopy/archive.c b/elfcopy/archive.c index a4f8017989ba..4735f02296e3 100644 --- a/elfcopy/archive.c +++ b/elfcopy/archive.c @@ -40,7 +40,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: archive.c 2370 2011-12-29 12:48:12Z jkoshy $"); +ELFTC_VCSID("$Id: archive.c 3102 2014-10-29 21:09:01Z jkoshy $"); #define _ARMAG_LEN 8 /* length of ar magic string */ #define _ARHDR_LEN 60 /* length of ar header */ @@ -350,12 +350,11 @@ ac_detect_ar(int ifd) r = -1; if ((a = archive_read_new()) == NULL) return (0); - archive_read_support_compression_none(a); archive_read_support_format_ar(a); if (archive_read_open_fd(a, ifd, 10240) == ARCHIVE_OK) r = archive_read_next_header(a, &entry); archive_read_close(a); - archive_read_finish(a); + archive_read_free(a); return (r == ARCHIVE_OK); } @@ -386,7 +385,6 @@ ac_read_objs(struct elfcopy *ecp, int ifd) err(EXIT_FAILURE, "lseek failed"); if ((a = archive_read_new()) == NULL) errx(EXIT_FAILURE, "%s", archive_error_string(a)); - archive_read_support_compression_none(a); archive_read_support_format_ar(a); AC(archive_read_open_fd(a, ifd, 10240)); for(;;) { @@ -435,7 +433,7 @@ ac_read_objs(struct elfcopy *ecp, int ifd) } } AC(archive_read_close(a)); - ACV(archive_read_finish(a)); + ACV(archive_read_free(a)); } static void @@ -449,7 +447,6 @@ ac_write_objs(struct elfcopy *ecp, int ofd) if ((a = archive_write_new()) == NULL) errx(EXIT_FAILURE, "%s", archive_error_string(a)); archive_write_set_format_ar_svr4(a); - archive_write_set_compression_none(a); AC(archive_write_open_fd(a, ofd)); /* Write the archive symbol table, even if it's empty. */ @@ -491,7 +488,7 @@ ac_write_objs(struct elfcopy *ecp, int ofd) } AC(archive_write_close(a)); - ACV(archive_write_finish(a)); + ACV(archive_write_free(a)); } static void diff --git a/elfcopy/main.c b/elfcopy/main.c index 3689f355fecd..0ba4e6864c86 100644 --- a/elfcopy/main.c +++ b/elfcopy/main.c @@ -40,7 +40,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: main.c 2970 2013-12-01 15:22:12Z kaiwang27 $"); +ELFTC_VCSID("$Id: main.c 3111 2014-12-20 08:33:01Z kaiwang27 $"); enum options { @@ -1109,7 +1109,8 @@ strip_main(struct elfcopy *ecp, int argc, char **argv) if (ecp->strip == 0 && ((ecp->flags & DISCARD_LOCAL) == 0) && - ((ecp->flags & DISCARD_LLABEL) == 0)) + ((ecp->flags & DISCARD_LLABEL) == 0) && + lookup_symop_list(ecp, NULL, SYMOP_STRIP) == NULL) ecp->strip = STRIP_ALL; if (optind == argc) strip_usage(); diff --git a/elfcopy/sections.c b/elfcopy/sections.c index d01659a935ee..c503666c8948 100644 --- a/elfcopy/sections.c +++ b/elfcopy/sections.c @@ -35,7 +35,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: sections.c 2358 2011-12-19 18:22:32Z kaiwang27 $"); +ELFTC_VCSID("$Id: sections.c 3126 2014-12-21 08:03:31Z kaiwang27 $"); static void add_gnu_debuglink(struct elfcopy *ecp); static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); @@ -372,6 +372,14 @@ create_scn(struct elfcopy *ecp) is_remove_reloc_sec(ecp, ish.sh_info)) continue; + /* + * Section groups should be removed if symbol table will + * be removed. (section group's signature stored in symbol + * table) + */ + if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL) + continue; + /* Get section flags set by user. */ sec_flags = get_section_flags(ecp, name); @@ -762,8 +770,8 @@ resync_sections(struct elfcopy *ecp) s->off = roundup(off, s->align); } else { if (s->loadable) - warnx("moving loadable section," - "is this intentional?"); + warnx("moving loadable section %s, " + "is this intentional?", s->name); s->off = roundup(off, s->align); } @@ -1139,12 +1147,6 @@ add_to_shstrtab(struct elfcopy *ecp, const char *name) struct section *s; s = ecp->shstrtab; - if (s->buf == NULL) { - insert_to_strtab(s, ""); - insert_to_strtab(s, ".symtab"); - insert_to_strtab(s, ".strtab"); - insert_to_strtab(s, ".shstrtab"); - } insert_to_strtab(s, name); } @@ -1206,6 +1208,11 @@ init_shstrtab(struct elfcopy *ecp) s->loadable = 0; s->type = SHT_STRTAB; s->vma = 0; + + insert_to_strtab(s, ""); + insert_to_strtab(s, ".symtab"); + insert_to_strtab(s, ".strtab"); + insert_to_strtab(s, ".shstrtab"); } void diff --git a/elfcopy/segments.c b/elfcopy/segments.c index c54cbfcbb07a..e48ad127bfd0 100644 --- a/elfcopy/segments.c +++ b/elfcopy/segments.c @@ -34,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: segments.c 2542 2012-08-12 16:14:15Z kaiwang27 $"); +ELFTC_VCSID("$Id: segments.c 3113 2014-12-20 08:33:29Z kaiwang27 $"); static void insert_to_inseg_list(struct segment *seg, struct section *sec); @@ -72,13 +72,15 @@ add_to_inseg_list(struct elfcopy *ecp, struct section *s) */ loadable = 0; STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { - if (s->off < seg->off) + if (s->off < seg->off || (s->vma < seg->addr && !s->pseudo)) continue; if (s->off + s->sz > seg->off + seg->fsz && s->type != SHT_NOBITS) continue; if (s->off + s->sz > seg->off + seg->msz) continue; + if (s->vma + s->sz > seg->addr + seg->msz) + continue; insert_to_inseg_list(seg, s); if (seg->type == PT_LOAD) @@ -96,7 +98,7 @@ adjust_addr(struct elfcopy *ecp) struct section *s, *s0; struct segment *seg; struct sec_action *sac; - uint64_t dl, lma, old_vma, start, end; + uint64_t dl, lma, start, end; int found, i; /* @@ -113,8 +115,6 @@ adjust_addr(struct elfcopy *ecp) s->lma += ecp->change_addr; if (!s->pseudo) { - old_vma = s->vma; - /* Apply global VMA adjustment. */ if (ecp->change_addr != 0) s->vma += ecp->change_addr; @@ -438,7 +438,7 @@ copy_phdr(struct elfcopy *ecp) seg->fsz = seg->msz = 0; for (i = 0; i < seg->nsec; i++) { s = seg->v_sec[i]; - seg->msz = s->off + s->sz - seg->off; + seg->msz = s->vma + s->sz - seg->addr; if (s->type != SHT_NOBITS) seg->fsz = seg->msz; } diff --git a/elfcopy/symbols.c b/elfcopy/symbols.c index f2a722736c83..573a18f25e79 100644 --- a/elfcopy/symbols.c +++ b/elfcopy/symbols.c @@ -34,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: symbols.c 2971 2013-12-01 15:22:21Z kaiwang27 $"); +ELFTC_VCSID("$Id: symbols.c 3019 2014-04-17 14:53:40Z jkoshy $"); /* Symbol table buffer structure. */ struct symbuf { @@ -300,7 +300,7 @@ generate_symbols(struct elfcopy *ecp) GElf_Sym sym; Elf_Data* id; Elf_Scn *is; - size_t ishstrndx, namelen, ndx, nsyms, sc, symndx; + size_t ishstrndx, namelen, ndx, sc, symndx; int ec, elferr, i; if (elf_getshstrndx(ecp->ein, &ishstrndx) == 0) @@ -320,7 +320,6 @@ generate_symbols(struct elfcopy *ecp) st_buf->lcap = 64; st_buf->lsz = 1; /* '\0' at start. */ st_buf->gsz = 0; - nsyms = 0; ecp->symtab->sz = 0; ecp->strtab->sz = 0; diff --git a/libdwarf/Makefile b/libdwarf/Makefile index 81b5657a2f72..d0a5443e6fb9 100644 --- a/libdwarf/Makefile +++ b/libdwarf/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2937 2013-04-27 04:48:23Z jkoshy $ +# $Id: Makefile 3097 2014-09-02 22:10:18Z kaiwang27 $ TOP= ${.CURDIR}/.. @@ -42,6 +42,7 @@ SRCS= \ dwarf_pubtypes.c \ dwarf_ranges.c \ dwarf_reloc.c \ + dwarf_sections.c \ dwarf_seterror.c \ dwarf_str.c \ dwarf_types.c \ @@ -115,6 +116,7 @@ MAN= dwarf.3 \ dwarf_add_weakname.3 \ dwarf_attr.3 \ dwarf_attrlist.3 \ + dwarf_attroffset.3 \ dwarf_attrval_signed.3 \ dwarf_child.3 \ dwarf_dealloc.3 \ @@ -154,6 +156,7 @@ MAN= dwarf.3 \ dwarf_get_cie_info.3 \ dwarf_get_cie_of_fde.3 \ dwarf_get_cu_die_offset.3 \ + dwarf_get_die_infotypes_flag.3 \ dwarf_get_elf.3 \ dwarf_get_fde_at_pc.3 \ dwarf_get_fde_info_for_all_regs.3 \ @@ -175,6 +178,7 @@ MAN= dwarf.3 \ dwarf_get_relocation_info.3 \ dwarf_get_relocation_info_count.3 \ dwarf_get_section_bytes.3 \ + dwarf_get_section_max_offsets.3 \ dwarf_get_str.3 \ dwarf_get_types.3 \ dwarf_get_vars.3 \ @@ -192,6 +196,7 @@ MAN= dwarf.3 \ dwarf_new_expr.3 \ dwarf_new_fde.3 \ dwarf_next_cu_header.3 \ + dwarf_next_types_section.3 \ dwarf_object_init.3 \ dwarf_producer_init.3 \ dwarf_producer_set_isa.3 \ @@ -220,7 +225,9 @@ MLINKS+= \ 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_offdie_b.3 \ dwarf_child.3 dwarf_siblingof.3 \ + dwarf_child.3 dwarf_siblingof_b.3 \ dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \ dwarf_dealloc.3 dwarf_funcs_dealloc.3 \ dwarf_dealloc.3 dwarf_globals_dealloc.3 \ @@ -234,6 +241,7 @@ MLINKS+= \ 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_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset_b.3 \ dwarf_finish.3 dwarf_object_finish.3 \ dwarf_formref.3 dwarf_global_formref.3 \ dwarf_formudata.3 dwarf_formsdata.3 \ @@ -273,6 +281,7 @@ MLINKS+= \ 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_section_max_offsets.3 dwarf_get_section_max_offsets_b.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 \ @@ -291,6 +300,7 @@ MLINKS+= \ dwarf_highpc.3 dwarf_bitoffset.3 \ dwarf_highpc.3 dwarf_bitsize.3 \ dwarf_highpc.3 dwarf_bytesize.3 \ + dwarf_highpc.3 dwarf_highpc_b.3 \ dwarf_highpc.3 dwarf_lowpc.3 \ dwarf_highpc.3 dwarf_srclang.3 \ dwarf_lineno.3 dwarf_lineaddr.3 \ @@ -302,6 +312,9 @@ MLINKS+= \ 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_loclist_from_expr.3 dwarf_loclist_from_expr_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_b.3 \ + dwarf_next_cu_header.3 dwarf_next_cu_header_c.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 \ diff --git a/libdwarf/Version.map b/libdwarf/Version.map index 6e6548bd9732..669f70e44dac 100644 --- a/libdwarf/Version.map +++ b/libdwarf/Version.map @@ -1,4 +1,4 @@ -/* $Id: Version.map 2576 2012-09-13 09:16:11Z jkoshy $ */ +/* $Id: Version.map 3085 2014-09-02 22:08:23Z kaiwang27 $ */ R1.0 { global: @@ -39,6 +39,7 @@ global: dwarf_arrayorder; dwarf_attr; dwarf_attrlist; + dwarf_attroffset; dwarf_attrval_flag; dwarf_attrval_signed; dwarf_attrval_string; @@ -116,6 +117,8 @@ global: dwarf_get_cie_of_fde; dwarf_get_cu_die_offset; dwarf_get_cu_die_offset_given_cu_header_offset; + dwarf_get_cu_die_offset_given_cu_header_offset_b; + dwarf_get_die_infotypes_flag; dwarf_get_elf; dwarf_get_fde_at_pc; dwarf_get_fde_info_for_all_regs3; @@ -139,6 +142,8 @@ global: dwarf_get_relocation_info; dwarf_get_relocation_info_count; dwarf_get_section_bytes; + dwarf_get_section_max_offsets; + dwarf_get_section_max_offsets_b; dwarf_get_str; dwarf_get_types; dwarf_get_vars; @@ -152,6 +157,7 @@ global: dwarf_hasattr; dwarf_hasform; dwarf_highpc; + dwarf_highpc_b; dwarf_init; dwarf_line_srcfileno; dwarf_lineaddr; @@ -166,6 +172,7 @@ global: dwarf_loclist; dwarf_loclist_from_expr; dwarf_loclist_from_expr_a; + dwarf_loclist_from_expr_b; dwarf_loclist_n; dwarf_lowpc; dwarf_new_die; @@ -173,9 +180,12 @@ global: dwarf_new_fde; dwarf_next_cu_header; dwarf_next_cu_header_b; + dwarf_next_cu_header_c; + dwarf_next_types_section; dwarf_object_finish; dwarf_object_init; dwarf_offdie; + dwarf_offdie_b; dwarf_producer_finish; dwarf_producer_init; dwarf_producer_init_b; @@ -196,6 +206,7 @@ global: dwarf_seterrarg; dwarf_seterrhand; dwarf_siblingof; + dwarf_siblingof_b; dwarf_srcfiles; dwarf_srclang; dwarf_srclines; diff --git a/libdwarf/_libdwarf.h b/libdwarf/_libdwarf.h index 23f60e8ee267..d2e74c15687a 100644 --- a/libdwarf/_libdwarf.h +++ b/libdwarf/_libdwarf.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ * 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 $ + * $Id: _libdwarf.h 3106 2014-12-19 16:00:58Z kaiwang27 $ */ #ifndef __LIBDWARF_H_ @@ -89,6 +89,7 @@ extern struct _libdwarf_globals _libdwarf; goto gen_fail; \ } while(0) +typedef struct _Dwarf_CU *Dwarf_CU; struct _Dwarf_AttrDef { uint64_t ad_attrib; /* DW_AT_XXX */ @@ -147,14 +148,6 @@ struct _Dwarf_Die { 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. */ @@ -265,6 +258,8 @@ struct _Dwarf_Cie { Dwarf_Half cie_version; /* CIE version. */ uint8_t *cie_augment; /* CIE augmentation (UTF-8). */ Dwarf_Unsigned cie_ehdata; /* Optional EH Data. */ + uint8_t cie_addrsize; /* Address size. (DWARF4) */ + uint8_t cie_segmentsize; /* Segment size. (DWARF4) */ Dwarf_Unsigned cie_caf; /* Code alignment factor. */ Dwarf_Signed cie_daf; /* Data alignment factor. */ Dwarf_Unsigned cie_ra; /* Return address register. */ @@ -333,11 +328,14 @@ struct _Dwarf_CU { 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_Sig8 cu_type_sig; /* Type unit's signature. */ + uint64_t cu_type_offset; /* Type unit's type offset. */ 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. */ + Dwarf_Bool cu_is_info; /* Compilation/type unit flag. */ STAILQ_ENTRY(_Dwarf_CU) cu_next; /* Next compilation unit. */ }; @@ -399,17 +397,21 @@ struct _Dwarf_Debug { 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_Section *dbg_types_sec; /* Pointer to type section. */ + Dwarf_Off dbg_types_off; /* Current types 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. */ + int dbg_types_loaded; /* Flag indicating all TU 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. */ + STAILQ_HEAD(, _Dwarf_CU) dbg_tu;/* List of type units. */ Dwarf_CU dbg_cu_current; /* Ptr to the current CU. */ - TAILQ_HEAD(, _Dwarf_Loclist) dbg_loclist; /* List of location list. */ + Dwarf_CU dbg_tu_current; /* Ptr to the current TU. */ 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. */ @@ -532,13 +534,15 @@ 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_next_types_section(Dwarf_Debug, Dwarf_Section *); 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_fop(Dwarf_Debug, uint8_t, 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 *); @@ -553,9 +557,12 @@ 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_first_tu(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_load(Dwarf_Debug, Dwarf_Bool, Dwarf_Bool, + Dwarf_Error *); int _dwarf_info_next_cu(Dwarf_Debug, Dwarf_Error *); +int _dwarf_info_next_tu(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 *); @@ -563,20 +570,19 @@ 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_locdesc(Dwarf_Debug, Dwarf_Locdesc *, + uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t, + Dwarf_Error *); int _dwarf_loc_fill_locexpr(Dwarf_Debug, Dwarf_Locdesc **, - uint8_t *, uint64_t, uint8_t, Dwarf_Error *); + uint8_t *, uint64_t, uint8_t, uint8_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 *); + Dwarf_Locdesc ***, Dwarf_Signed *, Dwarf_Unsigned *, + 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 *); @@ -633,6 +639,7 @@ 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_type_unit_cleanup(Dwarf_Debug); 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 *); diff --git a/libdwarf/dwarf.3 b/libdwarf/dwarf.3 index b32299cd1a11..5363034c45ae 100644 --- a/libdwarf/dwarf.3 +++ b/libdwarf/dwarf.3 @@ -21,9 +21,9 @@ .\" 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 $ +.\" $Id: dwarf.3 3130 2014-12-21 20:06:29Z jkoshy $ .\" -.Dd September 17, 2011 +.Dd December 21, 2014 .Os .Dt DWARF 3 .Sh NAME @@ -217,6 +217,8 @@ attribute. Retrieve an attribute descriptor. .It Fn dwarf_attrlist Retrieve attribute descriptors for a debugging information entry. +.It Fn dwarf_attroffset +Retrieve the section-relative offset of an attribute descriptor. .It Fn dwarf_attrval_flag Retrieve a .Dv DW_AT_FORM_flag @@ -309,10 +311,17 @@ 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 +.It Xo +.Fn dwarf_get_cu_die_offset_given_cu_header_offset , +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +.Xc Retrieve the offset of the debugging information entry for a -compilation unit. -.It Fn dwarf_next_cu_header , Fn dwarf_next_cu_header_b +compilation or type unit. +.It Xo +.Fn dwarf_next_cu_header , +.Fn dwarf_next_cu_header_b , +.Fn dwarf_next_cu_header_c +.Xc Step through compilation units in a debug context. .El .It Debugging Information Entries @@ -329,13 +338,15 @@ Returns the attribute for a debugging information entry. .It Fn dwarf_dieoffset Retrieves the offset for a debugging information entry. -.It Fn dwarf_highpc +.It Fn dwarf_get_die_infotypes_flag +Indicate the originating section for a debugging information entry. +.It Fn dwarf_highpc , Fn dwarf_highpc_b 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 +.It Fn dwarf_offdie , Fn dwarf_offdie_b Retrieve a debugging information entry given an offset. -.It Fn dwarf_siblingof +.It Fn dwarf_siblingof , Fn dwarf_siblingof_b Retrieve the sibling descriptor for a debugging information entry. .It Fn dwarf_srclang Retrive the source language attribute for a debugging information @@ -416,7 +427,11 @@ Return line number information for a compilation unit. 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 +.It Xo +.Fn dwarf_loclist_from_expr , +.Fn dwarf_loclist_from_expr_a , +.Fn dwarf_loclist_from_expr_b +.Xc Translate a location expression into a location descriptor. .El .It Error Handling @@ -513,6 +528,10 @@ and .Bl -tag -compact .It Fn dwarf_get_pubtypes , Fn dwarf_get_types Retrieve descriptors for user-defined types. +.It Fn dwarf_next_types_section +Step through +.Dq \&.debug_types +sections in a debug context. .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 @@ -699,9 +718,16 @@ addition to the per-debug context handlers supported by the SGI/GNU API, see the subsection .Sx Error Handling above. +.El +.Ss Extensions +The following APIs are extensions specific to this implementation: +.Bl -bullet -compact +.It +.Fn dwarf_attroffset .It -The following API is an extension: -.Fn dwarf_producer_set_isa . +.Fn dwarf_next_types_section +.It +.Fn dwarf_producer_set_isa .El .Sh SEE ALSO .Xr elf 3 diff --git a/libdwarf/dwarf.h b/libdwarf/dwarf.h index b1a3e4ec9670..c79da96dbb47 100644 --- a/libdwarf/dwarf.h +++ b/libdwarf/dwarf.h @@ -23,7 +23,7 @@ * 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 $ + * $Id: dwarf.h 3052 2014-05-26 20:36:24Z kaiwang27 $ */ #ifndef _DWARF_H_ @@ -93,6 +93,19 @@ #define DW_TAG_lo_user 0x4080 #define DW_TAG_hi_user 0xffff +/* GNU extensions. */ +#define DW_TAG_format_label 0x4101 +#define DW_TAG_function_template 0x4102 +#define DW_TAG_class_template 0x4103 +#define DW_TAG_GNU_BINCL 0x4104 +#define DW_TAG_GNU_EINCL 0x4105 +#define DW_TAG_GNU_template_template_parameter 0x4106 +#define DW_TAG_GNU_template_template_param 0x4106 +#define DW_TAG_GNU_template_parameter_pack 0x4107 +#define DW_TAG_GNU_formal_parameter_pack 0x4108 +#define DW_TAG_GNU_call_site 0x4109 +#define DW_TAG_GNU_call_site_parameter 0x410a + #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 @@ -195,6 +208,32 @@ #define DW_AT_lo_user 0x2000 #define DW_AT_hi_user 0x3fff +/* GNU extensions. */ +#define DW_AT_sf_names 0x2101 +#define DW_AT_src_info 0x2102 +#define DW_AT_mac_info 0x2103 +#define DW_AT_src_coords 0x2104 +#define DW_AT_body_begin 0x2105 +#define DW_AT_body_end 0x2106 +#define DW_AT_GNU_vector 0x2107 +#define DW_AT_GNU_guarded_by 0x2108 +#define DW_AT_GNU_pt_guarded_by 0x2109 +#define DW_AT_GNU_guarded 0x210a +#define DW_AT_GNU_pt_guarded 0x210b +#define DW_AT_GNU_locks_excluded 0x210c +#define DW_AT_GNU_exclusive_locks_required 0x210d +#define DW_AT_GNU_shared_locks_required 0x210e +#define DW_AT_GNU_odr_signature 0x210f +#define DW_AT_GNU_template_name 0x2110 +#define DW_AT_GNU_call_site_value 0x2111 +#define DW_AT_GNU_call_site_data_value 0x2112 +#define DW_AT_GNU_call_site_target 0x2113 +#define DW_AT_GNU_call_site_target_clobbered 0x2114 +#define DW_AT_GNU_tail_call 0x2115 +#define DW_AT_GNU_all_tail_call_sites 0x2116 +#define DW_AT_GNU_all_call_sites 0x2117 +#define DW_AT_GNU_all_source_call_sites 0x2118 + #define DW_FORM_addr 0x01 #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 @@ -220,6 +259,8 @@ #define DW_FORM_exprloc 0x18 #define DW_FORM_flag_present 0x19 #define DW_FORM_ref_sig8 0x20 +#define DW_FORM_GNU_ref_alt 0x1f20 +#define DW_FORM_GNU_strp_alt 0x1f21 #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 @@ -376,9 +417,23 @@ #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 +/* GNU extensions. */ +#define DW_OP_GNU_push_tls_address 0xe0 +#define DW_OP_GNU_uninit 0xf0 +#define DW_OP_GNU_encoded_addr 0xf1 +#define DW_OP_GNU_implicit_pointer 0xf2 +#define DW_OP_GNU_entry_value 0xf3 +#define DW_OP_GNU_const_type 0xf4 +#define DW_OP_GNU_regval_type 0xf5 +#define DW_OP_GNU_deref_type 0xf6 +#define DW_OP_GNU_convert 0xf7 +#define DW_OP_GNU_reinterpret 0xf9 +#define DW_OP_GNU_parameter_ref 0xfa +#define DW_OP_GNU_addr_index 0xfb +#define DW_OP_GNU_const_index 0xfc + #define DW_ATE_address 0x1 #define DW_ATE_boolean 0x2 #define DW_ATE_complex_float 0x3 diff --git a/libdwarf/dwarf_attr.3 b/libdwarf/dwarf_attr.3 index b1e30017a89a..9ba367be5f69 100644 --- a/libdwarf/dwarf_attr.3 +++ b/libdwarf/dwarf_attr.3 @@ -22,7 +22,7 @@ .\" 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 $ +.\" $Id: dwarf_attr.3 3093 2014-09-02 22:09:40Z kaiwang27 $ .\" .Dd April 8, 2010 .Os @@ -113,6 +113,7 @@ in argument .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attrlist 3 , +.Xr dwarf_attroffset 3 , .Xr dwarf_hasattr 3 , .Xr dwarf_hasform 3 , .Xr dwarf_whatattr 3 , diff --git a/libdwarf/dwarf_attr.c b/libdwarf/dwarf_attr.c index ce40294c6b12..a081d7b93a8f 100644 --- a/libdwarf/dwarf_attr.c +++ b/libdwarf/dwarf_attr.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_attr.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); int dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, @@ -114,6 +114,23 @@ dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, } int +dwarf_attroffset(Dwarf_Attribute at, Dwarf_Off *ret_off, Dwarf_Error *error) +{ + Dwarf_Debug dbg; + + dbg = at != NULL ? at->at_die->die_dbg : NULL; + + if (at == NULL || ret_off == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } + + *ret_off = at->at_offset; + + return (DW_DLV_OK); +} + +int dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) { Dwarf_Attribute at; @@ -139,8 +156,17 @@ dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) int dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) { + + return (dwarf_highpc_b(die, ret_highpc, NULL, NULL, error)); +} + +int +dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form, + enum Dwarf_Form_Class *ret_class, Dwarf_Error *error) +{ Dwarf_Attribute at; Dwarf_Debug dbg; + Dwarf_CU cu; dbg = die != NULL ? die->die_dbg : NULL; @@ -156,6 +182,17 @@ dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) *ret_highpc = at->u[0].u64; + if (ret_form != NULL) { + *ret_form = at->at_form; + } + + if (ret_class != NULL) { + cu = die->die_cu; + *ret_class = dwarf_get_form_class(cu->cu_version, + DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8, + at->at_form); + } + return (DW_DLV_OK); } diff --git a/libdwarf/dwarf_attroffset.3 b/libdwarf/dwarf_attroffset.3 new file mode 100644 index 000000000000..af24cebab8e9 --- /dev/null +++ b/libdwarf/dwarf_attroffset.3 @@ -0,0 +1,86 @@ +.\" Copyright (c) 2014 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_attroffset.3 3115 2014-12-20 18:26:46Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_ATTROFFSET 3 +.Sh NAME +.Nm dwarf_attroffset +.Nd retrieve the section-relative offset of an attribute descriptor +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_attroffset +.Fa "Dwarf_Attribute at" +.Fa "Dwarf_Off *ret_off" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_attroffset +retrieves the section-relative offset of the attribute descriptor +referenced by argument +.Ar at . +.Pp +Argument +.Ar ret_off +should point to a location that is to hold the returned +section-relative offset. +If argument +.Ar err +is non-NULL, it is used to return an error descriptor in case of an +error. +.Sh RETURN VALUES +On success, function +.Fn dwarf_attroffset +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_attroffset +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Either of the arguments +.Ar at +or +.Ar ret_off +was NULL. +.El +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_attr 3 diff --git a/libdwarf/dwarf_attrval.c b/libdwarf/dwarf_attrval.c index 0f17016ad810..3bddae9eceff 100644 --- a/libdwarf/dwarf_attrval.c +++ b/libdwarf/dwarf_attrval.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_attrval.c 2977 2014-01-21 20:13:31Z kaiwang27 $"); int dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) @@ -50,6 +50,7 @@ dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error switch (at->at_form) { case DW_FORM_flag: + case DW_FORM_flag_present: *valp = (Dwarf_Bool) (!!at->u[0].u64); break; default: diff --git a/libdwarf/dwarf_attrval_signed.3 b/libdwarf/dwarf_attrval_signed.3 index 9646990fc2de..93d4ae0596ed 100644 --- a/libdwarf/dwarf_attrval_signed.3 +++ b/libdwarf/dwarf_attrval_signed.3 @@ -22,9 +22,9 @@ .\" 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 $ +.\" $Id: dwarf_attrval_signed.3 2980 2014-01-21 20:15:54Z kaiwang27 $ .\" -.Dd January 29, 2011 +.Dd January 18, 2014 .Os .Dt DWARF_ATTRVAL_SIGNED 3 .Sh NAME @@ -84,13 +84,28 @@ Function .Fn dwarf_attrval_flag sets the location pointed to by argument .Ar ret -to 1 if the attribute named by argument +to either 0 or 1. If the form of the attribute named by argument .Ar attr -has a non-zero value, or to 0 otherwise. -The form of the attribute named by argument +is +.Dv DW_FORM_flag , +function +.Fn dwarf_attrval_flag +sets the location pointed to by argument +.Ar ret +to 1 if the attribute has a non-zero value, or to 0 otherwise. +If the form of the attribute named by argument .Ar attr -must be -.Dv DW_FORM_flag . +is +.Dv DW_FORM_flag_present , +function +.Fn dwarf_attrval_flag +unconditionally sets the location pointed to by argument +.Ar ret +to 1. +The form of the attribute must be one of +.Dv DW_FORM_flag +or +.Dv DW_FORM_flag_present . .Pp Function .Fn dwarf_attrval_signed @@ -122,7 +137,7 @@ attribute named by argument The form of the attribute must be one of .Dv DW_FORM_string or -.Dv DW_FORM_strp . +.Dv DW_FORM_strp . .Pp Function .Fn dwarf_attrval_unsigned diff --git a/libdwarf/dwarf_child.3 b/libdwarf/dwarf_child.3 index 57549c01c66e..1e32e58d4451 100644 --- a/libdwarf/dwarf_child.3 +++ b/libdwarf/dwarf_child.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,15 +22,17 @@ .\" 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 $ +.\" $Id: dwarf_child.3 3127 2014-12-21 19:09:19Z jkoshy $ .\" -.Dd November 9, 2011 +.Dd December 21, 2014 .Os .Dt DWARF_CHILD 3 .Sh NAME .Nm dwarf_child , +.Nm dwarf_offdie , +.Nm dwarf_offdie_b , .Nm dwarf_siblingof , -.Nm dwarf_offdie +.Nm dwarf_siblingof_b .Nd retrieve DWARF Debugging Information Entry descriptors .Sh LIBRARY .Lb libdwarf @@ -39,6 +41,21 @@ .Ft int .Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err" .Ft int +.Fo dwarf_offdie +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int +.Fo dwarf_offdie_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off offset" +.Fa "Dwarf_Bool is_info" +.Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Error *err" +.Fc +.Ft int .Fo dwarf_siblingof .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Die die" @@ -46,10 +63,11 @@ .Fa "Dwarf_Error *err" .Fc .Ft int -.Fo dwarf_offdie +.Fo dwarf_siblingof_b .Fa "Dwarf_Debug dbg" -.Fa "Dwarf_Off offset" +.Fa "Dwarf_Die die" .Fa "Dwarf_Die *ret_die" +.Fa "Dwarf_Bool is_info" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION @@ -92,6 +110,34 @@ may be used together to traverse the tree of debugging information entry descriptors for a compilation unit. .Pp Function +.Fn dwarf_siblingof_b +is identical to the function +.Fn dwarf_siblingof +except that it can retrieve the sibling descriptor from either the +current compilation unit or type unit. +If argument +.Ar is_info +is non-zero, the function behaves identically to function +.Fn dwarf_siblingof . +If argument +.Ar is_info +is zero, the descriptor referred by argument +.Ar die +should be associated with a debugging information entry in the +type unit. +The function will store the sibling of the descriptor in the location +pointed to by argument +.Ar ret_die . +If argument +.Ar is_info +is zero and argument +.Ar die +is +.Dv NULL , +the first debugging information entry descriptor for the +current type unit will be returned. +.Pp +Function .Fn dwarf_offdie retrieves the debugging information entry descriptor at global offset .Ar offset @@ -101,6 +147,31 @@ section of the object associated with argument .Ar dbg . The returned descriptor is written to the location pointed to by argument .Ar ret_die . +.Pp +Function +.Fn dwarf_offdie_b +is identical to the function +.Fn dwarf_offdie +except that it can retrieve the debugging information entry descriptor at +global offset +.Ar offset +from either of the +.Dq .debug_info +and +.Dq .debug_types +sections of the object associated with argument +.Ar dbg . +If argument +.Ar is_info +is non-zero, the function will retrieve the debugging information +entry from the +.Dq .debug_info +section, otherwise the function will retrieve the debugging +information entry from the +.Dq .debug_types +section. +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 @@ -128,14 +199,18 @@ argument if it is not NULL. .It Bq Er DW_DLV_NO_ENTRY For functions -.Fn dwarf_child +.Fn dwarf_child , +.Fn dwarf_siblingof and -.Fn dwarf_siblingof , +.Fn dwarf_siblingof_b , the descriptor denoted by argument .Ar die did not have a child or sibling. -For function -.Fn dwarf_offdie , +.Pp +For functions +.Fn dwarf_offdie +and +.Fn dwarf_offdie_b , there was no debugging information entry at the offset specified by argument .Ar offset . @@ -199,4 +274,5 @@ do { .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , +.Xr dwarf_get_die_infotypes_flag.3 , .Xr dwarf_next_cu_header 3 diff --git a/libdwarf/dwarf_cu.c b/libdwarf/dwarf_cu.c index c203dc2f1fc7..d103488d1098 100644 --- a/libdwarf/dwarf_cu.c +++ b/libdwarf/dwarf_cu.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,14 +27,15 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_cu.c 2072 2011-10-27 03:26:49Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_cu.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); 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_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info, + 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_Sig8 *type_signature, Dwarf_Unsigned *type_offset, + Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error) { Dwarf_CU cu; int ret; @@ -43,10 +45,17 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, 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 (is_info) { + if (dbg->dbg_cu_current == NULL) + ret = _dwarf_info_first_cu(dbg, error); + else + ret = _dwarf_info_next_cu(dbg, error); + } else { + if (dbg->dbg_tu_current == NULL) + ret = _dwarf_info_first_tu(dbg, error); + else + ret = _dwarf_info_next_tu(dbg, error); + } if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -54,11 +63,19 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, } 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); + if (is_info) { + 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; + } else { + if (dbg->dbg_tu_current == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + cu = dbg->dbg_tu_current; } - cu = dbg->dbg_cu_current; if (cu_length) *cu_length = cu->cu_length; @@ -81,11 +98,32 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, *cu_extension_size = 4; } if (cu_next_offset) - *cu_next_offset = dbg->dbg_cu_current->cu_next_offset; + *cu_next_offset = cu->cu_next_offset; + + if (!is_info) { + if (type_signature) + *type_signature = cu->cu_type_sig; + if (type_offset) + *type_offset = cu->cu_type_offset; + } return (DW_DLV_OK); } + +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) +{ + + return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version, + cu_abbrev_offset, cu_pointer_size, cu_offset_size, + cu_extension_size, NULL, NULL, cu_next_offset, error)); +} + int dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset, @@ -97,3 +135,27 @@ dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length, cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset, error)); } + +int +dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error) +{ + + /* Free resource allocated for current .debug_types section. */ + _dwarf_type_unit_cleanup(dbg); + dbg->dbg_types_loaded = 0; + dbg->dbg_types_off = 0; + + /* Reset type unit pointer. */ + dbg->dbg_tu_current = NULL; + + /* Search for the next .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, + dbg->dbg_types_sec); + + if (dbg->dbg_types_sec == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + + return (DW_DLV_OK); +} diff --git a/libdwarf/dwarf_die.c b/libdwarf/dwarf_die.c index b2b38403005f..de6351ac608f 100644 --- a/libdwarf/dwarf_die.c +++ b/libdwarf/dwarf_die.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009,2011 Kai Wang + * Copyright (c) 2009,2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,12 +27,13 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_die.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); int dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) { Dwarf_Debug dbg; + Dwarf_Section *ds; Dwarf_CU cu; int ret; @@ -44,13 +45,13 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) } if (die->die_ab->ab_children == DW_CHILDREN_no) - return (DW_DLE_NO_ENTRY); + return (DW_DLV_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); + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + ret = _dwarf_die_parse(die->die_dbg, ds, 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); @@ -62,11 +63,12 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error) } int -dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, - Dwarf_Error *error) +dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Bool is_info, Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Attribute at; + Dwarf_Section *ds; uint64_t offset; int ret, search_sibling; @@ -75,15 +77,27 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, return (DW_DLV_ERROR); } - if ((cu = dbg->dbg_cu_current) == NULL) { + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + + if (cu == 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)); + return (dwarf_offdie_b(dbg, cu->cu_1st_offset, is_info, + ret_die, error)); + + /* + * Check if the `is_info' flag matches the debug section the + * DIE belongs to. + */ + if (is_info != die->die_cu->cu_is_info) { + DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); + return (DW_DLV_ERROR); + } /* * If the DIE doesn't have any children, its sibling sits next @@ -108,9 +122,8 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, } } - 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); + ret = _dwarf_die_parse(die->die_dbg, ds, 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); @@ -121,21 +134,31 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, return (DW_DLV_OK); } + +int +dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_siblingof_b(dbg, die, ret_die, 1, error)); +} + static int -_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off offset, - Dwarf_Die *ret_die, Dwarf_Error *error) +_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_Section *s, 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, + return (_dwarf_die_parse(dbg, s, 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_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info, + Dwarf_Die *ret_die, Dwarf_Error *error) { + Dwarf_Section *ds; Dwarf_CU cu; int ret; @@ -144,11 +167,13 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, return (DW_DLV_ERROR); } + ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; + cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current; + /* First search the current CU. */ - if (dbg->dbg_cu_current != NULL) { - cu = dbg->dbg_cu_current; + if (cu != NULL) { if (offset > cu->cu_offset && offset < cu->cu_next_offset) { - ret = _dwarf_search_die_within_cu(dbg, cu, offset, + ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset, ret_die, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); @@ -160,21 +185,38 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, } /* Search other CUs. */ - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, is_info, 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); + if (is_info) { + 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, ds, 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); + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (offset < cu->cu_offset || + offset > cu->cu_next_offset) + continue; + ret = _dwarf_search_die_within_cu(dbg, ds, 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); @@ -182,6 +224,14 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, } int +dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die, + Dwarf_Error *error) +{ + + return (dwarf_offdie_b(dbg, offset, 1, ret_die, error)); +} + +int dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *error) { Dwarf_Debug dbg; @@ -293,9 +343,9 @@ dwarf_die_abbrev_code(Dwarf_Die die) } 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_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, + Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info, + Dwarf_Off *out_cu_die_offset, Dwarf_Error *error) { Dwarf_CU cu; @@ -304,10 +354,19 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, 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 (is_info) { + 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; + } + } + } else { + STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) { + if (cu->cu_offset == in_cu_header_offset) { + *out_cu_die_offset = cu->cu_1st_offset; + break; + } } } @@ -320,6 +379,16 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, } 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) +{ + + return (dwarf_get_cu_die_offset_given_cu_header_offset_b(dbg, + in_cu_header_offset, 1, out_cu_die_offset, error)); +} + +int dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, Dwarf_Error *error) { @@ -333,3 +402,12 @@ dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size, return (DW_DLV_OK); } + +Dwarf_Bool +dwarf_get_die_infotypes_flag(Dwarf_Die die) +{ + + assert(die != NULL); + + return (die->die_cu->cu_is_info); +} diff --git a/libdwarf/dwarf_dieoffset.3 b/libdwarf/dwarf_dieoffset.3 index 545bf2699c4d..00b0e71b8389 100644 --- a/libdwarf/dwarf_dieoffset.3 +++ b/libdwarf/dwarf_dieoffset.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,16 +22,17 @@ .\" 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 $ +.\" $Id: dwarf_dieoffset.3 3129 2014-12-21 20:06:26Z jkoshy $ .\" -.Dd April 17, 2010 +.Dd December 21, 2014 .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 +.Nm dwarf_get_cu_die_offset_given_cu_header_offset , +.Nm dwarf_get_cu_die_offset_given_cu_header_offset_b .Nd return offsets of DWARF debugging information entries .Sh LIBRARY .Lb libdwarf @@ -63,6 +64,14 @@ .Fa "Dwarf_Off *out_cu_die_offset" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_get_cu_die_offset_given_cu_header_offset_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Off in_cu_header_offset" +.Fa "Dwarf_Bool is_info" +.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. @@ -114,7 +123,7 @@ an error. .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset -returns the offset for the debugging information entry for a +returns the offset for the first debugging information entry for a compilation unit, given an offset to the header of the compilation unit. Argument @@ -131,8 +140,30 @@ 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_b +behaves identically to the function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset +when the argument +.Ar is_info +is non-zero. +When the argument +.Ar is_info +is zero, function +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b +returns the offset for the first debugging information entry for a +type unit, given an offset to the header of the type unit in argument +.Ar in_cu_header_offset . +Argument +.Ar out_cu_die_offset +points to a location that will hold the returned offset. +If the 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 +On success, these functions return .Dv DW_DLV_OK . In case of an error, these functions return .Dv DW_DLV_ERROR @@ -141,11 +172,13 @@ and set argument .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset +and +.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err -if there is no compilation unit located at the +if there is no compilation or type unit located at the offset specified in argument .Ar in_cu_header_offset . .Sh ERRORS @@ -169,4 +202,5 @@ specified an unknown offset. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_next_cu_header 3 , -.Xr dwarf_offdie 3 +.Xr dwarf_offdie 3 , +.Xr dwarf_offdie_b 3 diff --git a/libdwarf/dwarf_dump.c b/libdwarf/dwarf_dump.c index 9b5d1f767e1a..3219fa4c0c6c 100644 --- a/libdwarf/dwarf_dump.c +++ b/libdwarf/dwarf_dump.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_dump.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_dump.c 3052 2014-05-26 20:36:24Z kaiwang27 $"); int dwarf_get_ACCESS_name(unsigned access, const char **s) @@ -250,6 +250,54 @@ dwarf_get_AT_name(unsigned attr, const char **s) *s = "DW_AT_visibility"; break; case DW_AT_vtable_elem_location: *s = "DW_AT_vtable_elem_location"; break; + case DW_AT_sf_names: + *s = "DW_AT_sf_names"; break; + case DW_AT_src_info: + *s = "DW_AT_src_info"; break; + case DW_AT_mac_info: + *s = "DW_AT_mac_info"; break; + case DW_AT_src_coords: + *s = "DW_AT_src_coords"; break; + case DW_AT_body_begin: + *s = "DW_AT_body_begin"; break; + case DW_AT_body_end: + *s = "DW_AT_body_end"; break; + case DW_AT_GNU_vector: + *s = "DW_AT_GNU_vector"; break; + case DW_AT_GNU_guarded_by: + *s = "DW_AT_GNU_guarded_by"; break; + case DW_AT_GNU_pt_guarded_by: + *s = "DW_AT_GNU_pt_guarded_by"; break; + case DW_AT_GNU_guarded: + *s = "DW_AT_GNU_guarded"; break; + case DW_AT_GNU_pt_guarded: + *s = "DW_AT_GNU_pt_guarded"; break; + case DW_AT_GNU_locks_excluded: + *s = "DW_AT_GNU_locks_excluded"; break; + case DW_AT_GNU_exclusive_locks_required: + *s = "DW_AT_GNU_exclusive_locks_required"; break; + case DW_AT_GNU_shared_locks_required: + *s = "DW_AT_GNU_shared_locks_required"; break; + case DW_AT_GNU_odr_signature: + *s = "DW_AT_GNU_odr_signature"; break; + case DW_AT_GNU_template_name: + *s = "DW_AT_GNU_template_name"; break; + case DW_AT_GNU_call_site_value: + *s = "DW_AT_GNU_call_site_value"; break; + case DW_AT_GNU_call_site_data_value: + *s = "DW_AT_GNU_call_site_data_value"; break; + case DW_AT_GNU_call_site_target: + *s = "DW_AT_GNU_call_site_target"; break; + case DW_AT_GNU_call_site_target_clobbered: + *s = "DW_AT_GNU_call_site_target_clobbered"; break; + case DW_AT_GNU_tail_call: + *s = "DW_AT_GNU_tail_call"; break; + case DW_AT_GNU_all_tail_call_sites: + *s = "DW_AT_GNU_all_tail_call_sites"; break; + case DW_AT_GNU_all_call_sites: + *s = "DW_AT_GNU_all_call_sites"; break; + case DW_AT_GNU_all_source_call_sites: + *s = "DW_AT_GNU_all_source_call_sites"; break; default: return (DW_DLV_NO_ENTRY); } @@ -1094,6 +1142,30 @@ dwarf_get_OP_name(unsigned op, const char **s) *s = "DW_OP_stack_value"; break; case DW_OP_GNU_push_tls_address: *s = "DW_OP_GNU_push_tls_address"; break; + case DW_OP_GNU_uninit: + *s = "DW_OP_GNU_uninit"; break; + case DW_OP_GNU_encoded_addr: + *s = "DW_OP_GNU_encoded_addr"; break; + case DW_OP_GNU_implicit_pointer: + *s = "DW_OP_GNU_implicit_pointer"; break; + case DW_OP_GNU_entry_value: + *s = "DW_OP_GNU_entry_value"; break; + case DW_OP_GNU_const_type: + *s = "DW_OP_GNU_const_type"; break; + case DW_OP_GNU_regval_type: + *s = "DW_OP_GNU_regval_type"; break; + case DW_OP_GNU_deref_type: + *s = "DW_OP_GNU_deref_type"; break; + case DW_OP_GNU_convert: + *s = "DW_OP_GNU_convert"; break; + case DW_OP_GNU_reinterpret: + *s = "DW_OP_GNU_reinterpret"; break; + case DW_OP_GNU_parameter_ref: + *s = "DW_OP_GNU_parameter_ref"; break; + case DW_OP_GNU_addr_index: + *s = "DW_OP_GNU_addr_index"; break; + case DW_OP_GNU_const_index: + *s = "DW_OP_GNU_const_index"; break; default: return (DW_DLV_NO_ENTRY); } @@ -1244,6 +1316,26 @@ dwarf_get_TAG_name(unsigned tag, const char **s) *s = "DW_TAG_volatile_type"; break; case DW_TAG_with_stmt: *s = "DW_TAG_with_stmt"; break; + case DW_TAG_format_label: + *s = "DW_TAG_format_label"; break; + case DW_TAG_function_template: + *s = "DW_TAG_function_template"; break; + case DW_TAG_class_template: + *s = "DW_TAG_class_template"; break; + case DW_TAG_GNU_BINCL: + *s = "DW_TAG_GNU_BINCL"; break; + case DW_TAG_GNU_EINCL: + *s = "DW_TAG_GNU_EINCL"; break; + case DW_TAG_GNU_template_template_param: + *s = "DW_TAG_GNU_template_template_param"; break; + case DW_TAG_GNU_template_parameter_pack: + *s = "DW_TAG_GNU_template_parameter_pack"; break; + case DW_TAG_GNU_formal_parameter_pack: + *s = "DW_TAG_GNU_formal_parameter_pack"; break; + case DW_TAG_GNU_call_site: + *s = "DW_TAG_GNU_call_site"; break; + case DW_TAG_GNU_call_site_parameter: + *s = "DW_TAG_GNU_call_site_parameter"; break; default: return (DW_DLV_NO_ENTRY); } diff --git a/libdwarf/dwarf_errmsg.c b/libdwarf/dwarf_errmsg.c index 86afa28457bd..e300893a61c1 100644 --- a/libdwarf/dwarf_errmsg.c +++ b/libdwarf/dwarf_errmsg.c @@ -26,9 +26,9 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_errmsg.c 2576 2012-09-13 09:16:11Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_errmsg.c 2975 2014-01-21 20:08:04Z kaiwang27 $"); -const char *_libdwarf_errors[] = { +static const char *_libdwarf_errors[] = { #define DEFINE_ERROR(N,S) [DW_DLE_##N] = S DEFINE_ERROR(NONE, "No Error"), DEFINE_ERROR(ERROR, "An error"), diff --git a/libdwarf/dwarf_frame.c b/libdwarf/dwarf_frame.c index 5ccbbc4aead7..442f232cf092 100644 --- a/libdwarf/dwarf_frame.c +++ b/libdwarf/dwarf_frame.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); int dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list, @@ -539,8 +539,8 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, return (DW_DLV_ERROR); } - ret = _dwarf_frame_get_fop(dbg, instruction, len, ret_oplist, ret_opcnt, - error); + ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len, + ret_oplist, ret_opcnt, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); diff --git a/libdwarf/dwarf_get_die_infotypes_flag.3 b/libdwarf/dwarf_get_die_infotypes_flag.3 new file mode 100644 index 000000000000..4f5a19ace367 --- /dev/null +++ b/libdwarf/dwarf_get_die_infotypes_flag.3 @@ -0,0 +1,73 @@ +.\" Copyright (c) 2014 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_die_infotypes_flag.3 3118 2014-12-20 20:30:06Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_GET_DIE_INFOTYPES_FLAG 3 +.Sh NAME +.Nm dwarf_get_die_infotypes_flag +.Nd indicate the originating DWARF section for a DIE +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft Dwarf_Bool +.Fo dwarf_get_die_infotypes_flag +.Fa "Dwarf_Die die" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_die_infotypes_flag +returns a flag indicating the originating DWARF section for the +debugging information entry referenced by argument +.Ar die . +.Pp +Argument +.Ar die +should reference a valid debugging information entry descriptor. +.Sh RETURN VALUES +Function +.Fn dwarf_get_die_infotypes_flag +returns a non-zero value if argument +.Ar die +originates in the +.Dq .debug_info +section. +.Pp +It returns zero if argument +.Ar die +originates in the +.Dq .debug_types +section. +.Sh ERRORS +Function +.Fn dwarf_get_die_infotypes_flag +always succeeds. +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_next_cu_header_c 3 , +.Xr dwarf_offdie_b 3 , +.Xr dwarf_siblingof_b 3 diff --git a/libdwarf/dwarf_get_section_max_offsets.3 b/libdwarf/dwarf_get_section_max_offsets.3 new file mode 100644 index 000000000000..6f79341cd367 --- /dev/null +++ b/libdwarf/dwarf_get_section_max_offsets.3 @@ -0,0 +1,116 @@ +.\" Copyright (c) 2014 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_max_offsets.3 3098 2014-09-02 22:18:29Z kaiwang27 $ +.\" +.Dd July 27, 2014 +.Os +.Dt DWARF_GET_SECTION_MAX_OFFSETS +.Sh NAME +.Nm dwarf_get_section_max_offsets , +.Nm dwarf_get_section_max_offsets_b +.Nd return the size of DWARF sections +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_get_section_max_offsets +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fc +.Ft int +.Fo dwarf_get_section_max_offsets_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Unsigned *debug_info" +.Fa "Dwarf_Unsigned *debug_abbrev" +.Fa "Dwarf_Unsigned *debug_line" +.Fa "Dwarf_Unsigned *debug_loc" +.Fa "Dwarf_Unsigned *debug_aranges" +.Fa "Dwarf_Unsigned *debug_macinfo" +.Fa "Dwarf_Unsigned *debug_pubnames" +.Fa "Dwarf_Unsigned *debug_str" +.Fa "Dwarf_Unsigned *debug_frame" +.Fa "Dwarf_Unsigned *debug_ranges" +.Fa "Dwarf_Unsigned *debug_pubtypes" +.Fa "Dwarf_Unsigned *debug_types" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_get_section_max_offsets_b +retrieves the sizes of the DWARF sections in a DWARF debug context. +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +The function stores the size of each DWARF section to the location +pointed to by the argument corresponding to the section name. +If a DWARF section does not exist, the location pointed to by the +argument corresponding to that section will be set to zero. +.Pp +A value of NULL may be used for any of the arguments +.Ar debug_info , +.Ar debug_abbrev , +.Ar debug_line , +.Ar debug_loc , +.Ar debug_aranges , +.Ar debug_macinfo , +.Ar debug_pubnames , +.Ar debug_str , +.Ar debug_frame , +.Ar debug_ranges , +.Ar debug_pubtypes +and +.Ar debug_types +if the caller is not interested in the respective section size. +.Pp +Function +.Fn dwarf_get_section_max_offsets +is identical to function +.Fn dwarf_get_section_max_offsets_b +except that it does not provide argument +.Ar debug_types , +thus it can not retrieve the size of the +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, these functions return +.Dv DW_DLV_OK . +If argument +.Ar dbg +is NULL, they return +.Dv DW_DLV_ERROR . +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 diff --git a/libdwarf/dwarf_highpc.3 b/libdwarf/dwarf_highpc.3 index 998a3b6ad650..4d31f5c8d1a2 100644 --- a/libdwarf/dwarf_highpc.3 +++ b/libdwarf/dwarf_highpc.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,9 +22,9 @@ .\" 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 $ +.\" $Id: dwarf_highpc.3 3092 2014-09-02 22:09:30Z kaiwang27 $ .\" -.Dd April 7, 2010 +.Dd July 22, 2014 .Os .Dt DWARF_HIGHPC 3 .Sh NAME @@ -33,6 +33,7 @@ .Nm dwarf_bitsize , .Nm dwarf_bytesize , .Nm dwarf_highpc , +.Nm dwarf_highpc_b , .Nm dwarf_lowpc , .Nm dwarf_srclang .Nd retrieve the value of a DWARF attribute @@ -71,6 +72,14 @@ .Fa "Dwarf_Error *err" .Fc .Ft int +.Fo dwarf_highpc_b +.Fa "Dwarf_Die die" +.Fa "Dwarf_Addr *ret_highpc" +.Fa "Dwarf_Half *ret_form" +.Fa "enum Dwarf_Form_Class *ret_class" +.Fa "Dwarf_Error *err" +.Fc +.Ft int .Fo dwarf_lowpc .Fa "Dwarf_Die die" .Fa "Dwarf_Addr *ret_lowpc" @@ -114,6 +123,10 @@ attribute value. Retrieve the .Dv DW_AT_high_pc attribute value. +.It Fn dwarf_highpc_b +Retrieve the +.Dv DW_AT_high_pc +attribute value. .It Fn dwarf_lowpc Retrieve the .Dv DW_AT_low_pc @@ -123,6 +136,23 @@ Retrieve the .Dv DW_AT_language attribute value. .El +.Pp +Function +.Fn dwarf_highpc_b +is an enhanced version of function +.Fn dwarf_highpc . +It sets the location specified by argument +.Ar ret_form +to the form code of the attribute +.Dv DW_AT_high_pc , +and sets the location specified by argument +.Ar ret_class +to the class of that form. +A value of NULL may be used for either of the arguments +.Ar ret_form +or +.Ar ret_class +if the caller is not interested in the respective value. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. @@ -159,4 +189,5 @@ had no requested attribute. .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_attrlist 3 , -.Xr dwarf_hasattr 3 +.Xr dwarf_hasattr 3 , +.Xr dwarf_get_form_class 3 diff --git a/libdwarf/dwarf_lineno.c b/libdwarf/dwarf_lineno.c index d0c24b176b71..cbcc9aeaa69d 100644 --- a/libdwarf/dwarf_lineno.c +++ b/libdwarf/dwarf_lineno.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 $"); int dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, @@ -75,8 +75,8 @@ dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, return (DW_DLV_OK); } - if ((li->li_lnarray = malloc(*linecount * - sizeof(struct _Dwarf_Line))) == NULL) { + if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) == + NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_ERROR); } diff --git a/libdwarf/dwarf_loclist.c b/libdwarf/dwarf_loclist.c index cf6fa9dc9f8e..e780a87128e5 100644 --- a/libdwarf/dwarf_loclist.c +++ b/libdwarf/dwarf_loclist.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009 Kai Wang + * Copyright (c) 2009,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,13 +26,37 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_loclist.c 2074 2011-10-27 03:34:33Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_loclist.c 3066 2014-06-06 19:36:06Z kaiwang27 $"); + +static int +copy_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *dst, Dwarf_Locdesc *src, + Dwarf_Error *error) +{ + + assert(src != NULL && dst != NULL); + + dst->ld_lopc = src->ld_lopc; + dst->ld_hipc = src->ld_hipc; + dst->ld_cents = src->ld_cents; + + if (dst->ld_cents > 0) { + dst->ld_s = calloc(dst->ld_cents, sizeof(Dwarf_Loc)); + if (dst->ld_s == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + memcpy(dst->ld_s, src->ld_s, src->ld_cents * + sizeof(Dwarf_Loc)); + } else + dst->ld_s = NULL; + + return (DW_DLE_NONE); +} int dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { - Dwarf_Loclist ll; Dwarf_Debug dbg; int ret; @@ -56,27 +80,54 @@ dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf, 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); + /* + * DW_FORM_data[48] can not be used as section offset + * since DWARF4. For DWARF[23], the application needs + * to determine if DW_FORM_data[48] is representing + * a constant or a section offset. + */ + if (at->at_die->die_cu->cu_version >= 4) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLV_NO_ENTRY); + } + /* FALLTHROUGH */ + case DW_FORM_sec_offset: + ret = _dwarf_loclist_find(dbg, at->at_die->die_cu, + at->u[0].u64, llbuf, listlen, NULL, 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: + case DW_FORM_exprloc: 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; + *llbuf = calloc(1, sizeof(Dwarf_Locdesc *)); + if (*llbuf == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + (*llbuf)[0] = calloc(1, sizeof(Dwarf_Locdesc)); + if ((*llbuf)[0] == NULL) { + free(*llbuf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLV_ERROR); + } + if (copy_locdesc(dbg, (*llbuf)[0], at->at_ld, error) != + DW_DLE_NONE) { + free((*llbuf)[0]); + free(*llbuf); + return (DW_DLV_ERROR); + } *listlen = 1; return (DW_DLV_OK); default: @@ -95,62 +146,27 @@ int dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, Dwarf_Error *error) { - Dwarf_Loclist ll; - Dwarf_Debug dbg; - int ret; + Dwarf_Locdesc **_llbuf; + int i, ret; - dbg = at != NULL ? at->at_die->die_dbg : NULL; + ret = dwarf_loclist_n(at, &_llbuf, listlen, error); + if (ret != DW_DLV_OK) + return (ret); - if (at == NULL || llbuf == NULL || listlen == NULL) { - DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); - return (DW_DLV_ERROR); - } + /* Only return the first location description of the list. */ + *llbuf = _llbuf[0]; - 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); + /* Free the rest of the list. */ + for (i = 1; i < *listlen; i++) { + if (_llbuf[i]->ld_s) + free(_llbuf[i]->ld_s); + free(_llbuf[i]); } + free(_llbuf); + + *listlen = 1; + + return (DW_DLV_OK); } int @@ -159,19 +175,25 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry, Dwarf_Error *error) { - Dwarf_Loclist ll, next_ll; - Dwarf_Locdesc *ld; + Dwarf_Locdesc *ld, **llbuf; Dwarf_Section *ds; + Dwarf_Signed listlen; int i, ret; + /* + * Note that this API sometimes will not work correctly because + * it assumes that all units have the same pointer size and offset + * size. + */ + 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); + ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, + &llbuf, &listlen, entry_len, error); if (ret == DW_DLE_NO_ENTRY) { DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY); return (DW_DLV_NO_ENTRY); @@ -179,8 +201,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, return (DW_DLV_ERROR); *hipc = *lopc = 0; - for (i = 0; i < ll->ll_ldlen; i++) { - ld = ll->ll_ldlist[i]; + for (i = 0; i < listlen; i++) { + ld = llbuf[i]; if (i == 0) { *hipc = ld->ld_hipc; *lopc = ld->ld_lopc; @@ -194,14 +216,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset, 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; + *data = (uint8_t *) ds->ds_data + offset; + *next_entry = offset + *entry_len; return (DW_DLV_OK); } @@ -211,24 +227,9 @@ 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); + return (dwarf_loclist_from_expr_a(dbg, bytes_in, bytes_len, + dbg->dbg_pointer_size, llbuf, listlen, error)); } int @@ -236,6 +237,40 @@ 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_Half offset_size; + Dwarf_Small version; + + /* + * Obtain offset size and DWARF version from the current + * Compilation Unit or Type Unit. These values are needed + * for correctly parsing DW_OP_GNU_implicit_pointer operator. + * + * Note that dwarf_loclist_from_expr_b() should be used instead + * if the application knows correct values for offset size + * and DWARF version. + */ + if (dbg->dbg_cu_current) { + offset_size = dbg->dbg_cu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_cu_current->cu_version; + } else if (dbg->dbg_tu_current) { + offset_size = dbg->dbg_tu_current->cu_length_size == 4 ? 4 : 8; + version = dbg->dbg_tu_current->cu_version; + } else { + /* Default values if no CU/TU context. */ + offset_size = 4; + version = 2; /* DWARF2 */ + } + + return (dwarf_loclist_from_expr_b(dbg, bytes_in, bytes_len, addr_size, + offset_size, version, llbuf, listlen, error)); +} + +int +dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, + Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size, + Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen, + Dwarf_Error *error) +{ Dwarf_Locdesc *ld; int ret; @@ -250,8 +285,13 @@ dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in, return (DW_DLV_ERROR); } + if (offset_size != 4 && offset_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); + offset_size, version, error); if (ret != DW_DLE_NONE) return (DW_DLV_ERROR); diff --git a/libdwarf/dwarf_loclist_from_expr.3 b/libdwarf/dwarf_loclist_from_expr.3 index d317f7e28004..d0eb88c464d2 100644 --- a/libdwarf/dwarf_loclist_from_expr.3 +++ b/libdwarf/dwarf_loclist_from_expr.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2011 Kai Wang +.\" Copyright (c) 2011,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,14 +22,15 @@ .\" 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 $ +.\" $Id: dwarf_loclist_from_expr.3 3129 2014-12-21 20:06:26Z jkoshy $ .\" -.Dd July 6, 2011 +.Dd December 21, 2014 .Os .Dt DWARF_LOCLIST_FROM_EXPR 3 .Sh NAME .Nm dwarf_loclist_from_expr , -.Nm dwarf_loclist_from_expr_a +.Nm dwarf_loclist_from_expr_a , +.Nm dwarf_loclist_from_expr_b .Nd translate DWARF location expression bytes .Sh LIBRARY .Lb libdwarf @@ -54,6 +55,18 @@ .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_loclist_from_expr_b +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Ptr bytes_in" +.Fa "Dwarf_Unsigned bytes_len" +.Fa "Dwarf_Half addr_size" +.Fa "Dwarf_Half offset_size" +.Fa "Dwarf_Small version" +.Fa "Dwarf_Locdesc **llbuf" +.Fa "Dwarf_Signed *listlen" +.Fa "Dwarf_Error *error" +.Fc .Sh DESCRIPTION Function .Fn dwarf_loclist_from_expr @@ -104,6 +117,21 @@ except that it requires one additional argument .Ar addr_size , which specifies the address size to use when translating the location expression bytes. +.Pp +Function +.Fn dwarf_loclist_from_expr_b +is identical to function +.Fn dwarf_loclist_from_expr_a +except that it requires two additional arguments for translating the +location expression bytes. +Argument +.Ar offset_size +specifies the offset size, and argument +.Ar version +specifies the DWARF version. +These values are required to correctly translate the +.Dv DW_OP_GNU_implicit_pointer +opcode. .Ss Memory Management The memory area used for the descriptor returned in argument .Ar llbuf diff --git a/libdwarf/dwarf_next_cu_header.3 b/libdwarf/dwarf_next_cu_header.3 index 5be00b8ec4ee..f172322daa48 100644 --- a/libdwarf/dwarf_next_cu_header.3 +++ b/libdwarf/dwarf_next_cu_header.3 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2010 Kai Wang +.\" Copyright (c) 2010,2014 Kai Wang .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -22,14 +22,15 @@ .\" 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 $ +.\" $Id: dwarf_next_cu_header.3 3128 2014-12-21 20:06:22Z jkoshy $ .\" -.Dd July 24, 2010 +.Dd December 21, 2014 .Os .Dt DWARF_NEXT_CU_HEADER 3 .Sh NAME .Nm dwarf_next_cu_header , -.Nm dwarf_next_cu_header_b +.Nm dwarf_next_cu_header_b , +.Nm dwarf_next_cu_header_c .Nd step through compilation units in a DWARF debug context .Sh LIBRARY .Lb libdwarf @@ -57,33 +58,71 @@ .Fa "Dwarf_Unsigned *cu_next_offset" .Fa "Dwarf_Error *err" .Fc +.Ft int +.Fo dwarf_next_cu_header_c +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Bool is_info" +.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_Sig8 *type_signature" +.Fa "Dwarf_Unsigned *type_offset" +.Fa "Dwarf_Unsigned *cu_next_offset" +.Fa "Dwarf_Error *err" +.Fc .Sh DESCRIPTION -These functions are used to step through compilation unit contexts +These functions are used to step through compilation or type units associated with a DWARF debug context, optionally returning information about the unit. .Pp Function -.Fn dwarf_next_cu_header_b +.Fn dwarf_next_cu_header_c is the API recommended for new application code. +Function +.Fn dwarf_next_cu_header +and +.Fn dwarf_next_cu_header_b +can only operate on compilation units associated with the +.Dq \&.debug_info +section. +They are less general than function +.Fn dwarf_next_cu_header_c , +and are deprecated for use by new application code. +.Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . +If argument +.Ar is_info +is set to 1, +the function returns information for compilation units found in the +.Dq \&.debug_info +section. +If argument +.Ar is_info +is set to 0, +the function returns information for type units found in the +.Dq \&.debug_types +sections. Argument .Ar cu_length should point to a location that will be set to the -length of the compilation unit. +length of the compilation or type unit. Argument .Ar cu_version should point to a location that will be set to the -version number for the compilation unit. +version number for the compilation or type 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. +associated with this compilation or type unit. Argument .Ar cu_pointer_size should point to a location that will be set to the @@ -92,7 +131,7 @@ 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. +size in bytes for a DWARF offset in the compilation or type unit. Argument .Ar cu_extension_size is only needed for processing MIPS/IRIX objects that use @@ -100,10 +139,26 @@ 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 type_signature +and +.Ar type_offset +is only needed for processing type units. +Argument +.Ar type_signature +should point to a location that will be set to the 64-bit unique signature +of the type described in the type unit. +Argument +.Ar type_offset +should point to a location that will be set to the offset of the debugging +information entry that describes the type. +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, +or the offset of the next type unit header in the +.Dq \&.debug_types section. Argument .Ar err @@ -111,42 +166,23 @@ should point to a location that will hold an error descriptor in case of an error. .Pp Function +.Fn dwarf_next_cu_header_b +is identical to function +.Fn dwarf_next_cu_header_c +except that it does not provide arguments +.Ar is_info , +.Ar type_signature +and +.Ar type_offset . +.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. +is identical to function +.Fn dwarf_next_cu_header_b +except that it does not provide arguments +.Ar cu_offset_size +and +.Ar cu_extension_size . .Pp A value of NULL may be used for any of the arguments .Ar cu_length , @@ -155,30 +191,79 @@ A value of NULL may be used for any of the arguments .Ar cu_pointer_size , .Ar cu_offset_size , .Ar cu_extension_size , +.Ar type_signature , +.Ar type_offset , .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 +The first call to function +.Fn dwarf_next_cu_header_c +for a given debug context with argument +.Ar is_info +set to 1 will return information about the first +compilation unit in the +.Dq \&.debug_info +section. +Subsequent calls to the function will iterate through the remaining +compilation units in the section. +On stepping past the last compilation unit in the section, +function +.Fn dwarf_next_cu_header_c +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first compilation +unit in the section. +.Ss Iterating Through Type Units in a Debug Context +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer assoicated with the context will point to the +fisrt +.Dq \&.debug_types +section found in the debug object. +The first call to function +.Fn dwarf_next_cu_header_c +for the debug context with argument +.Ar is_info +set to 0 will return information about the first +type unit in that +.Dq \&.debug_types +section. +Subsequent calls to the function will iterate through the remaining +type units in the section. +On stepping past the last type unit in the debug context, +function +.Fn dwarf_next_cu_header_c +returns +.Dv DW_DLV_NO_ENTRY +and resets its internal state. +The next call to the function will restart from the first type +unit in the +.Dq \&.debug_types +section. +.Pp +If the debug object contains multiple +.Dq \&.debug_types +sections, the function +.Fn dwarf_next_types_section +can be called to move the internal pointer to the next +.Dq \&.debug_types +section. +As a result, subsequent calls of the function +.Fn dwarf_next_cu_header_c +will operate on the new +.Dq \&.debug_types +section. +Function +.Fn dwarf_next_types_section +returns .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. +when there are no more +.Dq \&.debug_types +sections left in the debug object. .Sh RETURN VALUES On success, these functions return .Dv DW_DLV_OK . @@ -200,4 +285,5 @@ was NULL. .Xr dwarf 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_init 3 , +.Xr dwarf_next_types_section 3 , .Xr dwarf_siblingof 3 diff --git a/libdwarf/dwarf_next_types_section.3 b/libdwarf/dwarf_next_types_section.3 new file mode 100644 index 000000000000..98ff70d82668 --- /dev/null +++ b/libdwarf/dwarf_next_types_section.3 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2014 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_types_section.3 3116 2014-12-20 18:26:55Z jkoshy $ +.\" +.Dd December 20, 2014 +.Os +.Dt DWARF_NEXT_TYPES_SECTION 3 +.Sh NAME +.Nm dwarf_next_types_section +.Nd step through .debug_types sections in a debug context +.Sh LIBRARY +.Lb libdwarf +.Sh SYNOPSIS +.In libdwarf.h +.Ft int +.Fo dwarf_next_types_section +.Fa "Dwarf_Debug dbg" +.Fa "Dwarf_Error *err" +.Fc +.Sh DESCRIPTION +Function +.Fn dwarf_next_types_section +steps through the +.Dq \&.debug_types +sections found in a debug context. +.Pp +Argument +.Ar dbg +should reference a DWARF debug context allocated using +.Xr dwarf_init 3 . +Argument +.Ar err +should point to a location that will hold an error descriptor in case +of an error. +.Pp +When a DWARF debug context is allocated using +.Xr dwarf_init 3 , +an internal pointer associated with the context will point to the +first +.Dq \&.debug_types +section present in the debug object. +When the application calls function +.Fn dwarf_next_types_section , +this internal pointer will move to the next +.Dq \&.debug_types +section present. +On stepping past the last +.Dq \&.debug_types +section left in the debug context, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_NO_ENTRY . +The next call to the function will restart from the first +.Dq \&.debug_types +section in the debug context. +.Pp +Application code should call function +.Xr dwarf_next_cu_header_c 3 +to iterate though the type units associated with the current +.Dq \&.debug_types +section. +.Sh RETURN VALUES +On success, function +.Fn dwarf_next_types_section +returns +.Dv DW_DLV_OK . +.Pp +In case of an error, it returns +.Dv DW_DLV_ERROR +and sets argument +.Ar err . +When there are no more +.Dq \&.debug_types +sections left to traverse, it returns +.Dv DW_DLV_NO_ENTRY . +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_next_types_section +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was NULL. +.El +.Sh EXAMPLES +To iterate though every type unit in all the +.Dq \&.debug_types +sections found in a debug context: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Sig8 sig8; +Dwarf_Unsigned typeoff; +Dwarf_Error de; + +\&... allocate dbg using dwarf_init() etc ... + +do { + while ((ret = dwarf_next_cu_header_c(dbg, 0, NULL, NULL, NULL, + NULL, NULL, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) { + /* Access DIEs etc ... */ + } +} while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); +.Ed +.Sh SEE ALSO +.Xr dwarf 3 , +.Xr dwarf_init 3 , +.Xr dwarf_next_cu_header_c 3 diff --git a/libdwarf/dwarf_ranges.c b/libdwarf/dwarf_ranges.c index 9ad60832350d..2e01da553f7e 100644 --- a/libdwarf/dwarf_ranges.c +++ b/libdwarf/dwarf_ranges.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_ranges.c 2075 2011-10-27 03:47:28Z jkoshy $"); +ELFTC_VCSID("$Id: dwarf_ranges.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); static int _dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off off, @@ -63,7 +63,7 @@ dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Ranges **ranges, } if (!dbg->dbg_info_loaded) { - if (_dwarf_info_load(dbg, 1, error) != DW_DLE_NONE) + if (_dwarf_info_load(dbg, 1, 1, error) != DW_DLE_NONE) return (DW_DLV_ERROR); } diff --git a/libdwarf/dwarf_sections.c b/libdwarf/dwarf_sections.c new file mode 100644 index 000000000000..d3c1379378fe --- /dev/null +++ b/libdwarf/dwarf_sections.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2014 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_sections.c 3036 2014-05-05 19:19:31Z kaiwang27 $"); + +#define SET(N, V) \ + do { \ + if ((N) != NULL) \ + *(N) = (V); \ + } while (0) + +int +dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes, + Dwarf_Unsigned *debug_types) +{ + const char *n; + Dwarf_Unsigned sz; + int i; + + if (dbg == NULL) + return (DW_DLV_ERROR); + + SET(debug_info, 0); + SET(debug_abbrev, 0); + SET(debug_line, 0); + SET(debug_loc, 0); + SET(debug_aranges, 0); + SET(debug_macinfo, 0); + SET(debug_pubnames, 0); + SET(debug_str, 0); + SET(debug_frame, 0); + SET(debug_ranges, 0); + SET(debug_pubtypes, 0); + SET(debug_types, 0); + + for (i = 0; (Dwarf_Unsigned) i < dbg->dbg_seccnt; i++) { + n = dbg->dbg_section[i].ds_name; + sz = dbg->dbg_section[i].ds_size; + if (!strcmp(n, ".debug_info")) + SET(debug_info, sz); + else if (!strcmp(n, ".debug_abbrev")) + SET(debug_abbrev, sz); + else if (!strcmp(n, ".debug_line")) + SET(debug_line, sz); + else if (!strcmp(n, ".debug_loc")) + SET(debug_loc, sz); + else if (!strcmp(n, ".debug_aranges")) + SET(debug_aranges, sz); + else if (!strcmp(n, ".debug_macinfo")) + SET(debug_macinfo, sz); + else if (!strcmp(n, ".debug_pubnames")) + SET(debug_pubnames, sz); + else if (!strcmp(n, ".debug_str")) + SET(debug_str, sz); + else if (!strcmp(n, ".debug_frame")) + SET(debug_frame, sz); + else if (!strcmp(n, ".debug_ranges")) + SET(debug_ranges, sz); + else if (!strcmp(n, ".debug_pubtypes")) + SET(debug_pubtypes, sz); + else if (!strcmp(n, ".debug_types")) + SET(debug_types, sz); + } + + return (DW_DLV_OK); +} + +int +dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info, + Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line, + Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges, + Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames, + Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame, + Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes) +{ + + return (dwarf_get_section_max_offsets(dbg, debug_info, debug_abbrev, + debug_line, debug_loc, debug_aranges, debug_macinfo, + debug_pubnames, debug_str, debug_frame, debug_ranges, + debug_pubtypes)); +} diff --git a/libdwarf/libdwarf.h b/libdwarf/libdwarf.h index 105a0e7d96d2..9a4a89984769 100644 --- a/libdwarf/libdwarf.h +++ b/libdwarf/libdwarf.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +24,7 @@ * 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 $ + * $Id: libdwarf.h 3064 2014-06-06 19:35:55Z kaiwang27 $ */ #ifndef _LIBDWARF_H_ @@ -47,7 +47,6 @@ 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; @@ -60,7 +59,6 @@ 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; @@ -519,6 +517,7 @@ int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *, Dwarf_Error *); int dwarf_attrlist(Dwarf_Die, Dwarf_Attribute **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_attroffset(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *); int dwarf_attrval_flag(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, Dwarf_Error *); int dwarf_attrval_signed(Dwarf_Die, Dwarf_Half, Dwarf_Signed *, @@ -626,6 +625,9 @@ 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_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug, + Dwarf_Off, Dwarf_Bool, Dwarf_Off *, Dwarf_Error *); +Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die); 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 *); @@ -678,6 +680,16 @@ 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_section_max_offsets(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *); +int dwarf_get_section_max_offsets_b(Dwarf_Debug, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Unsigned *); int dwarf_get_str(Dwarf_Debug, Dwarf_Off, char **, Dwarf_Signed *, Dwarf_Error *); int dwarf_get_types(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *, @@ -700,6 +712,8 @@ int dwarf_hasattr(Dwarf_Die, Dwarf_Half, Dwarf_Bool *, int dwarf_hasform(Dwarf_Attribute, Dwarf_Half, Dwarf_Bool *, Dwarf_Error *); int dwarf_highpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *); +int dwarf_highpc_b(Dwarf_Die, Dwarf_Addr *, Dwarf_Half *, + enum Dwarf_Form_Class *, Dwarf_Error *); int dwarf_init(int, int, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *); int dwarf_line_srcfileno(Dwarf_Line, Dwarf_Unsigned *, @@ -722,6 +736,10 @@ int dwarf_loclist_from_expr(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, int dwarf_loclist_from_expr_a(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned, Dwarf_Half, Dwarf_Locdesc **, Dwarf_Signed *, Dwarf_Error *); +int dwarf_loclist_from_expr_b(Dwarf_Debug, Dwarf_Ptr, + Dwarf_Unsigned, Dwarf_Half, Dwarf_Half, + Dwarf_Small, 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 *); @@ -735,11 +753,18 @@ int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *, 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_next_cu_header_c(Dwarf_Debug, Dwarf_Bool, + Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, + Dwarf_Half *, Dwarf_Half *, Dwarf_Sig8 *, Dwarf_Unsigned *, + Dwarf_Unsigned *, Dwarf_Error *); +int dwarf_next_types_section(Dwarf_Debug, 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 *); +int dwarf_offdie_b(Dwarf_Debug, Dwarf_Off, Dwarf_Bool, 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 *); @@ -765,6 +790,8 @@ 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_siblingof_b(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Bool, + 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 *, diff --git a/libdwarf/libdwarf_arange.c b/libdwarf/libdwarf_arange.c index 75434f6ae20b..eefb63ba6b10 100644 --- a/libdwarf/libdwarf_arange.c +++ b/libdwarf/libdwarf_arange.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_arange.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_arange.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); void _dwarf_arange_cleanup(Dwarf_Debug dbg) @@ -67,7 +67,7 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NONE); if (!dbg->dbg_info_loaded) { - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, 1, error); if (ret != DW_DLE_NONE) return (ret); } @@ -137,8 +137,8 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error) /* Build arange array. */ if (dbg->dbg_arange_cnt > 0) { - if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * - sizeof(struct _Dwarf_Arange))) == NULL) { + if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt * + sizeof(Dwarf_Arange))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); ret = DW_DLE_MEMORY; goto fail_cleanup; diff --git a/libdwarf/libdwarf_attr.c b/libdwarf/libdwarf_attr.c index a7fb71cd1f24..dfbbc484c352 100644 --- a/libdwarf/libdwarf_attr.c +++ b/libdwarf/libdwarf_attr.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_attr.c 2966 2013-09-21 14:40:14Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); int _dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) @@ -106,6 +106,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, ret = DW_DLE_NONE; memset(&atref, 0, sizeof(atref)); atref.at_die = die; + atref.at_offset = *offsetp; atref.at_attrib = ad->ad_attrib; atref.at_form = indirect ? form : ad->ad_form; atref.at_indirect = indirect; @@ -162,7 +163,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, 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) + else atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); break; diff --git a/libdwarf/libdwarf_die.c b/libdwarf/libdwarf_die.c index 4572875ed0d7..b7796d3cb6b0 100644 --- a/libdwarf/libdwarf_die.c +++ b/libdwarf/libdwarf_die.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_die.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); int _dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) @@ -81,6 +81,7 @@ Dwarf_Die _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) { Dwarf_Debug dbg; + Dwarf_Section *ds; Dwarf_CU cu; Dwarf_Die die1; Dwarf_Error de; @@ -88,9 +89,10 @@ _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) cu = die->die_cu; dbg = die->die_dbg; + ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; - ret = _dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, - off, cu->cu_next_offset, &die1, 0, &de); + ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off, + cu->cu_next_offset, &die1, 0, &de); if (ret == DW_DLE_NONE) return (die1); diff --git a/libdwarf/libdwarf_frame.c b/libdwarf/libdwarf_frame.c index 375d64f5f66f..dd331379a4fd 100644 --- a/libdwarf/libdwarf_frame.c +++ b/libdwarf/libdwarf_frame.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2011 Kai Wang + * Copyright (c) 2009-2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_frame.c 2529 2012-07-29 23:31:12Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $"); static int _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, @@ -49,8 +49,9 @@ _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, } 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) +_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val, + uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, + Dwarf_Error *error) { uint8_t application; @@ -62,7 +63,7 @@ _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data, switch (encode) { case DW_EH_PE_absptr: - *val = dbg->read(data, offsetp, dbg->dbg_pointer_size); + *val = dbg->read(data, offsetp, cie->cie_addrsize); break; case DW_EH_PE_uleb128: *val = _dwarf_read_uleb128(data, offsetp); @@ -149,7 +150,7 @@ _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie, /* Skip two augments in augment data. */ encode = *augdata_p++; offset = 0; - ret = _dwarf_frame_read_lsb_encoded(dbg, &val, + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, augdata_p, &offset, encode, 0, error); if (ret != DW_DLE_NONE) return (ret); @@ -233,6 +234,18 @@ _dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, cie->cie_ehdata = dbg->read(ds->ds_data, off, dbg->dbg_pointer_size); + /* DWARF4 added "address_size" and "segment_size". */ + if (cie->cie_version == 4) { + cie->cie_addrsize = dbg->read(ds->ds_data, off, 1); + cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1); + } else { + /* + * Otherwise (DWARF[23]) we just set CIE addrsize to the + * debug context pointer size. + */ + cie->cie_addrsize = dbg->dbg_pointer_size; + } + cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off); cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off); @@ -345,8 +358,9 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, * 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); + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &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; @@ -354,16 +368,16 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, * 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); + ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &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); + cie->cie_addrsize); fde->fde_adrange = dbg->read(ds->ds_data, off, - dbg->dbg_pointer_size); + cie->cie_addrsize); } /* Optional FDE augmentation data for .eh_frame section. (ignored) */ @@ -530,9 +544,9 @@ fail_cleanup: } 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_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size, + 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; @@ -632,7 +646,7 @@ _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts, switch (low6) { case DW_CFA_set_loc: - pc = dbg->decode(&p, dbg->dbg_pointer_size); + pc = dbg->decode(&p, addr_size); #ifdef FRAME_DEBUG printf("DW_CFA_set_loc(pc=%#jx)\n", pc); #endif @@ -898,14 +912,13 @@ program_done: } 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) +_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, 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 { \ @@ -970,7 +983,6 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, } \ } while(0) - ret = DW_DLE_NONE; *count = 0; p = insts; @@ -1020,7 +1032,7 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, switch (low6) { case DW_CFA_set_loc: - uoff = dbg->decode(&p, dbg->dbg_pointer_size); + uoff = dbg->decode(&p, addr_size); SET_OFFSET(uoff); break; case DW_CFA_advance_loc1: @@ -1103,15 +1115,16 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, } 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_get_fop(Dwarf_Debug dbg, uint8_t addr_size, 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); + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + NULL, NULL, error); if (ret != DW_DLE_NONE) return (ret); @@ -1120,8 +1133,8 @@ _dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len, return (DW_DLE_MEMORY); } - ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, oplist, NULL, - error); + ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, + oplist, NULL, error); if (ret != DW_DLE_NONE) { free(oplist); return (ret); @@ -1201,17 +1214,17 @@ _dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req, /* 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); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + 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); + ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, + 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); } diff --git a/libdwarf/libdwarf_info.c b/libdwarf/libdwarf_info.c index dc82b7ddfde8..261bee6d933e 100644 --- a/libdwarf/libdwarf_info.c +++ b/libdwarf/libdwarf_info.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * Copyright (c) 2010,2011 Kai Wang + * Copyright (c) 2010,2011,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_info.c 2942 2013-05-04 23:03:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_info.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); int _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) @@ -46,7 +46,7 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NO_ENTRY); dbg->dbg_info_off = 0; - ret = _dwarf_info_load(dbg, 0, error); + ret = _dwarf_info_load(dbg, 0, 1, error); if (ret != DW_DLE_NONE) return (ret); @@ -56,6 +56,32 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) } int +_dwarf_info_first_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU tu; + int ret; + + assert(dbg->dbg_tu_current == NULL); + tu = STAILQ_FIRST(&dbg->dbg_tu); + if (tu != NULL) { + dbg->dbg_tu_current = tu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) + return (DW_DLE_NO_ENTRY); + + dbg->dbg_types_off = 0; + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_FIRST(&dbg->dbg_tu); + + return (DW_DLE_NONE); +} + +int _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_CU cu; @@ -73,7 +99,7 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_NO_ENTRY); } - ret = _dwarf_info_load(dbg, 0, error); + ret = _dwarf_info_load(dbg, 0, 1, error); if (ret != DW_DLE_NONE) return (ret); @@ -83,7 +109,35 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) } int -_dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) +_dwarf_info_next_tu(Dwarf_Debug dbg, Dwarf_Error *error) +{ + Dwarf_CU cu; + int ret; + + assert(dbg->dbg_tu_current != NULL); + cu = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + if (cu != NULL) { + dbg->dbg_tu_current = cu; + return (DW_DLE_NONE); + } + + if (dbg->dbg_types_loaded) { + dbg->dbg_tu_current = NULL; + return (DW_DLE_NO_ENTRY); + } + + ret = _dwarf_info_load(dbg, 0, 0, error); + if (ret != DW_DLE_NONE) + return (ret); + + dbg->dbg_tu_current = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); + + return (DW_DLE_NONE); +} + +int +_dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, + Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Section *ds; @@ -93,12 +147,22 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) 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); + if (is_info) { + if (dbg->dbg_info_loaded) + return (ret); + offset = dbg->dbg_info_off; + ds = dbg->dbg_info_sec; + assert(ds != NULL); + } else { + if (dbg->dbg_types_loaded) + return (ret); + offset = dbg->dbg_types_off; + ds = dbg->dbg_types_sec; + if (ds == NULL) + return (DW_DLE_NO_ENTRY); + } + while (offset < ds->ds_size) { if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); @@ -106,6 +170,7 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) } cu->cu_dbg = dbg; + cu->cu_is_info = is_info; cu->cu_offset = offset; length = dbg->read(ds->ds_data, &offset, 4); @@ -129,7 +194,10 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) /* Compute the offset to the next compilation unit: */ next_offset = offset + length; - dbg->dbg_info_off = next_offset; + if (is_info) + dbg->dbg_info_off = next_offset; + else + dbg->dbg_types_off = next_offset; /* Initialise the compilation unit. */ cu->cu_length = length; @@ -141,8 +209,20 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1); cu->cu_next_offset = next_offset; + /* .debug_types extra fields. */ + if (!is_info) { + memcpy(cu->cu_type_sig.signature, + (char *) ds->ds_data + offset, 8); + offset += 8; + cu->cu_type_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + } + /* Add the compilation unit to the list. */ - STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + if (is_info) + STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); + else + STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next); if (cu->cu_version < 2 || cu->cu_version > 4) { DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); @@ -158,8 +238,13 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error) break; } - if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) - dbg->dbg_info_loaded = 1; + if (is_info) { + if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) + dbg->dbg_info_loaded = 1; + } else { + if ((Dwarf_Unsigned) dbg->dbg_types_off >= ds->ds_size) + dbg->dbg_types_loaded = 1; + } return (ret); } @@ -180,6 +265,22 @@ _dwarf_info_cleanup(Dwarf_Debug dbg) } free(cu); } + + _dwarf_type_unit_cleanup(dbg); +} + +void +_dwarf_type_unit_cleanup(Dwarf_Debug dbg) +{ + Dwarf_CU cu, tcu; + + assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); + + STAILQ_FOREACH_SAFE(cu, &dbg->dbg_tu, cu_next, tcu) { + STAILQ_REMOVE(&dbg->dbg_tu, cu, _Dwarf_CU, cu_next); + _dwarf_abbrev_cleanup(cu); + free(cu); + } } int diff --git a/libdwarf/libdwarf_init.c b/libdwarf/libdwarf_init.c index 71d596699d58..8e3fbbe5db36 100644 --- a/libdwarf/libdwarf_init.c +++ b/libdwarf/libdwarf_init.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_init.c 3061 2014-06-02 00:42:41Z kaiwang27 $"); static int _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) @@ -69,7 +69,8 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) dbg->dbg_seccnt = cnt; - if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) { + if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == + NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } @@ -90,6 +91,7 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) return (ret); } } + dbg->dbg_section[cnt].ds_name = NULL; if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == @@ -98,6 +100,9 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) return (DW_DLE_DEBUG_INFO_NULL); } + /* Try to find the optional DWARF4 .debug_types section. */ + dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); + /* Initialise call frame API related parameters. */ _dwarf_frame_params_init(dbg); @@ -210,10 +215,10 @@ _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, dbg->dbg_errarg = errarg; STAILQ_INIT(&dbg->dbg_cu); + STAILQ_INIT(&dbg->dbg_tu); 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); @@ -270,7 +275,6 @@ _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); diff --git a/libdwarf/libdwarf_lineno.c b/libdwarf/libdwarf_lineno.c index 8bb3c85f3dee..63627f736f7f 100644 --- a/libdwarf/libdwarf_lineno.c +++ b/libdwarf/libdwarf_lineno.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_lineno.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_lineno.c 3100 2014-10-25 20:34:29Z jkoshy $"); static int _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, @@ -87,9 +87,8 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, { Dwarf_Debug dbg; Dwarf_Line ln, tln; - uint64_t address, file, line, column, isa, opsize; + uint64_t address, file, line, column, opsize; int is_stmt, basic_block, end_sequence; - int prologue_end, epilogue_begin; int ret; #define RESET_REGISTERS \ @@ -101,8 +100,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, is_stmt = li->li_defstmt; \ basic_block = 0; \ end_sequence = 0; \ - prologue_end = 0; \ - epilogue_begin = 0; \ } while(0) #define APPEND_ROW \ @@ -181,8 +178,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *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) * @@ -210,13 +205,11 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, 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); + (void) _dwarf_decode_uleb128(&p); break; default: /* Unrecognized extened opcodes. What to do? */ @@ -233,8 +226,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, address += ADDRESS(*p); APPEND_ROW; basic_block = 0; - prologue_end = 0; - epilogue_begin = 0; p++; } } @@ -482,7 +473,7 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Unsigned address, file, line, spc; Dwarf_Unsigned addr0, maddr; Dwarf_Signed line0, column; - int is_stmt, basic_block, end_sequence; + int is_stmt, basic_block; int need_copy; int ret; @@ -494,7 +485,6 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, column = 0; \ is_stmt = li->li_defstmt; \ basic_block = 0; \ - end_sequence = 0; \ } while(0) li = dbg->dbgp_lineinfo; diff --git a/libdwarf/libdwarf_loc.c b/libdwarf/libdwarf_loc.c index ea366fb0768e..c2d3f5cc6662 100644 --- a/libdwarf/libdwarf_loc.c +++ b/libdwarf/libdwarf_loc.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) + * Copyright (c) 2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $"); /* * Given an array of bytes of length 'len' representing a @@ -38,12 +39,12 @@ ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $"); */ static int _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, - uint8_t *p, int len) + uint8_t offset_size, uint8_t version, uint8_t *p, int len) { int count; uint64_t operand1; uint64_t operand2; - uint8_t *ps, *pe; + uint8_t *ps, *pe, s; count = 0; ps = p; @@ -165,37 +166,49 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, case DW_OP_ne: case DW_OP_nop: + case DW_OP_push_object_address: case DW_OP_form_tls_address: case DW_OP_call_frame_cfa: case DW_OP_stack_value: case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: 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; + case DW_OP_const1s: + operand1 = (int8_t) *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; + case DW_OP_const2s: + operand1 = (int16_t) dbg->decode(&p, 2); + break; + /* Operations with 4-byte operands. */ case DW_OP_call4: case DW_OP_const4u: - case DW_OP_const4s: + case DW_OP_GNU_parameter_ref: operand1 = dbg->decode(&p, 4); break; + case DW_OP_const4s: + operand1 = (int32_t) dbg->decode(&p, 4); + break; + /* Operations with 8-byte operands. */ case DW_OP_const8u: case DW_OP_const8s: @@ -207,6 +220,9 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: + case DW_OP_GNU_deref_type: + case DW_OP_GNU_convert: + case DW_OP_GNU_reinterpret: operand1 = _dwarf_decode_uleb128(&p); break; @@ -252,6 +268,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, * Oeration with two unsigned LEB128 operands. */ case DW_OP_bit_piece: + case DW_OP_GNU_regval_type: operand1 = _dwarf_decode_uleb128(&p); operand2 = _dwarf_decode_uleb128(&p); break; @@ -267,10 +284,14 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, /* * Operation with an unsigned LEB128 operand - * followed by a block. Store a pointer to the - * block in the operand2. + * representing the size of a block, followed + * by the block content. + * + * Store the size of the block in the operand1 + * and a pointer to the block in the operand2. */ case DW_OP_implicit_value: + case DW_OP_GNU_entry_value: operand1 = _dwarf_decode_uleb128(&p); operand2 = (Dwarf_Unsigned) (uintptr_t) p; p += operand1; @@ -278,25 +299,59 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, /* Target address size operand. */ case DW_OP_addr: + case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: operand1 = dbg->decode(&p, pointer_size); break; + /* Offset size operand. */ + case DW_OP_call_ref: + operand1 = dbg->decode(&p, offset_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 + * The first byte is address byte length, followed by + * the address value. If the length is 0, the address + * size is the same as target pointer size. */ - case DW_OP_call_ref: - operand1 = dbg->decode(&p, dbg->dbg_offset_size); + case DW_OP_GNU_encoded_addr: + s = *p++; + if (s == 0) + s = pointer_size; + operand1 = dbg->decode(&p, s); + break; + + /* + * Operand1: DIE offset (size depending on DWARF version) + * DWARF2: pointer size + * DWARF{3,4}: offset size + * + * Operand2: SLEB128 + */ + case DW_OP_GNU_implicit_pointer: + if (version == 2) + operand1 = dbg->decode(&p, pointer_size); + else + operand1 = dbg->decode(&p, offset_size); + operand2 = _dwarf_decode_sleb128(&p); + break; + + /* + * Operand1: DIE offset (ULEB128) + * Operand2: pointer to a block. The block's first byte + * is its size. + */ + case DW_OP_GNU_const_type: + operand1 = _dwarf_decode_uleb128(&p); + operand2 = (Dwarf_Unsigned) (uintptr_t) p; + s = *p++; + p += s; break; /* All other operations cause an error. */ default: count = -1; - break; + goto done; } if (lbuf != NULL) { @@ -307,6 +362,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size, count++; } +done: return (count); } @@ -561,7 +617,8 @@ _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end, 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) + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) { int num; @@ -570,8 +627,8 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, assert(in_len > 0); /* Compute the number of locations. */ - if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) < - 0) { + if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size, + version, in, in_len)) < 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD); return (DW_DLE_LOC_EXPR_BAD); } @@ -585,14 +642,16 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in, return (DW_DLE_MEMORY); } - (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len); + (void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size, + version, 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) + uint64_t in_len, uint8_t pointer_size, uint8_t offset_size, + uint8_t version, Dwarf_Error *error) { Dwarf_Locdesc *llbuf; int ret; @@ -606,7 +665,7 @@ _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in, llbuf->ld_s = NULL; ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size, - error); + offset_size, version, error); if (ret != DW_DLE_NONE) { free(llbuf); return (ret); @@ -635,7 +694,8 @@ _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error) 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); + at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8, + cu->cu_version, error); return (ret); } diff --git a/libdwarf/libdwarf_loclist.c b/libdwarf/libdwarf_loclist.c index 8b599868d00d..bb3e39f6c899 100644 --- a/libdwarf/libdwarf_loclist.c +++ b/libdwarf/libdwarf_loclist.c @@ -26,11 +26,11 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_loclist.c 2972 2013-12-23 06:46:04Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_loclist.c 3061 2014-06-02 00:42:41Z 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 *off, Dwarf_Locdesc **ld, Dwarf_Signed *ldlen, Dwarf_Unsigned *total_len, Dwarf_Error *error) { uint64_t start, end; @@ -75,6 +75,7 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, if (ld != NULL) { ret = _dwarf_loc_fill_locdesc(dbg, ld[i], ds->ds_data + *off, len, cu->cu_pointer_size, + cu->cu_length_size == 4 ? 4 : 8, cu->cu_version, error); if (ret != DW_DLE_NONE) return (ret); @@ -91,134 +92,74 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds, 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_Locdesc ***ret_llbuf, Dwarf_Signed *listlen, + Dwarf_Unsigned *entry_len, Dwarf_Error *error) { + Dwarf_Locdesc **llbuf; Dwarf_Section *ds; - Dwarf_Loclist ll, tll; - uint64_t ldlen; + Dwarf_Signed ldlen; + Dwarf_Unsigned off; 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); + if (lloff >= ds->ds_size) { + DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); + return (DW_DLE_NO_ENTRY); } - ll->ll_offset = lloff; - /* Get the number of locdesc the first round. */ - ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, NULL, &ldlen, + off = lloff; + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, NULL, &ldlen, NULL, error); if (ret != DW_DLE_NONE) - goto fail_cleanup; + return (ret); + + if (ldlen == 0) + return (DW_DLE_NO_ENTRY); /* * 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) { + if ((llbuf = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == NULL) { + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + for (i = 0; i < ldlen; i++) { + if ((llbuf[i] = calloc(1, 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; + off = lloff; /* Fill in locdesc. */ - ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, ll->ll_ldlist, - NULL, &ll->ll_length, error); + ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, llbuf, NULL, + entry_len, 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_llbuf = llbuf; + *listlen = ldlen; - *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]); + if (llbuf != NULL) { + for (i = 0; i < ldlen; i++) { + if (llbuf[i]->ld_s) + free(llbuf[i]->ld_s); + free(llbuf[i]); } - free(ll->ll_ldlist); + free(llbuf); } - 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); - } + return (ret); } diff --git a/libdwarf/libdwarf_nametbl.c b/libdwarf/libdwarf_nametbl.c index 158aca34ad43..661b56f1c9c8 100644 --- a/libdwarf/libdwarf_nametbl.c +++ b/libdwarf/libdwarf_nametbl.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_nametbl.c 2070 2011-10-27 03:05:32Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_nametbl.c 3029 2014-04-21 23:26:02Z kaiwang27 $"); void _dwarf_nametbl_cleanup(Dwarf_NameSec *nsp) @@ -103,7 +103,7 @@ _dwarf_nametbl_init(Dwarf_Debug dbg, Dwarf_NameSec *namesec, Dwarf_Section *ds, nt->nt_cu_length = dbg->read(ds->ds_data, &offset, dwarf_size); if (!dbg->dbg_info_loaded) { - ret = _dwarf_info_load(dbg, 1, error); + ret = _dwarf_info_load(dbg, 1, 1, error); if (ret != DW_DLE_NONE) goto fail_cleanup; } diff --git a/libdwarf/libdwarf_sections.c b/libdwarf/libdwarf_sections.c index 3ac30b251e02..24d5db839e49 100644 --- a/libdwarf/libdwarf_sections.c +++ b/libdwarf/libdwarf_sections.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_sections.c 2379 2012-01-05 02:08:20Z jkoshy $"); +ELFTC_VCSID("$Id: libdwarf_sections.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); #define _SECTION_INIT_SIZE 128 @@ -212,7 +212,7 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name) Dwarf_Section *ds; Dwarf_Half i; - assert(name != NULL); + assert(dbg != NULL && name != NULL); for (i = 0; i < dbg->dbg_seccnt; i++) { ds = &dbg->dbg_section[i]; @@ -223,6 +223,27 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name) return (NULL); } +Dwarf_Section * +_dwarf_find_next_types_section(Dwarf_Debug dbg, Dwarf_Section *ds) +{ + + assert(dbg != NULL); + + if (ds == NULL) + return (_dwarf_find_section(dbg, ".debug_types")); + + assert(ds->ds_name != NULL); + + do { + ds++; + if (ds->ds_name != NULL && + !strcmp(ds->ds_name, ".debug_types")) + return (ds); + } while (ds->ds_name != NULL); + + return (NULL); +} + Dwarf_P_Section _dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name) { diff --git a/libelf/_libelf.h b/libelf/_libelf.h index fba2f97fd670..d5803a4e44ff 100644 --- a/libelf/_libelf.h +++ b/libelf/_libelf.h @@ -23,7 +23,7 @@ * 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 $ + * $Id: _libelf.h 3011 2014-03-23 03:32:42Z jkoshy $ */ #ifndef __LIBELF_H_ @@ -48,7 +48,7 @@ struct _libelf_globals { int libelf_error; int libelf_fillchar; unsigned int libelf_version; - char libelf_msg[LIBELF_MSG_SIZE]; + unsigned char libelf_msg[LIBELF_MSG_SIZE]; }; extern struct _libelf_globals _libelf; @@ -71,14 +71,14 @@ extern struct _libelf_globals _libelf; * 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 */ +#define LIBELF_F_API_MASK 0x00FFFFU /* Flags defined by the API. */ +#define LIBELF_F_AR_HEADER 0x010000U /* translated header available */ +#define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */ +#define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ +#define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ +#define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ +#define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ +#define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ struct _Elf { int e_activations; /* activation count */ @@ -89,7 +89,7 @@ struct _Elf { 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 */ + unsigned char *e_rawfile; /* uninterpreted bytes */ size_t e_rawsize; /* size of uninterpreted bytes */ unsigned int e_version; /* file version */ @@ -99,16 +99,16 @@ struct _Elf { */ union { Elf_Arhdr *e_arhdr; /* translated header */ - char *e_rawhdr; /* untranslated header */ + unsigned 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 */ + unsigned char *e_rawstrtab; /* file name strings */ size_t e_rawstrtabsz; - char *e_rawsymtab; /* symbol table */ + unsigned char *e_rawsymtab; /* symbol table */ size_t e_rawsymtabsz; Elf_Arsym *e_symtab; size_t e_symtabsz; @@ -162,21 +162,31 @@ enum { 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; \ + +/* + * The LIBELF_COPY macros are used to copy fields from a GElf_* + * structure to their 32-bit counterparts, while checking for out of + * range values. + * + * - LIBELF_COPY_U32 :: copy an unsigned 32 bit field. + * - LIBELF_COPY_S32 :: copy a signed 32 bit field. + */ + +#define LIBELF_COPY_U32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > UINT32_MAX) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \ } 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; \ +#define LIBELF_COPY_S32(DST, SRC, NAME) do { \ + if ((SRC)->NAME > INT32_MAX || \ + (SRC)->NAME < INT32_MIN) { \ + LIBELF_SET_ERROR(RANGE, 0); \ + return (0); \ + } \ + (DST)->NAME = (int32_t) (SRC)->NAME; \ } while (0) @@ -191,22 +201,22 @@ 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); +long _libelf_checksum(Elf *_e, int _elfclass); void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); -int _libelf_falign(Elf_Type _t, int _elfclass); +unsigned 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); + (unsigned char *_dst, size_t dsz, unsigned 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); +unsigned int _libelf_malign(Elf_Type _t, int _elfclass); +Elf *_libelf_memory(unsigned 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); diff --git a/libelf/_libelf_ar.h b/libelf/_libelf_ar.h index d6b15a7501ef..45a7e16be863 100644 --- a/libelf/_libelf_ar.h +++ b/libelf/_libelf_ar.h @@ -23,7 +23,7 @@ * 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 $ + * $Id: _libelf_ar.h 3013 2014-03-23 06:16:59Z jkoshy $ */ #ifndef __LIBELF_AR_H_ @@ -42,15 +42,16 @@ (sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1) #define IS_EXTENDED_BSD_NAME(NAME) \ - (strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \ + (strncmp((const char *) (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); +unsigned char *_libelf_ar_get_string(const char *_buf, size_t _sz, + unsigned 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); +int _libelf_ar_get_number(const char *_buf, size_t _sz, + unsigned int _base, size_t *_ret); #endif /* __LIBELF_AR_H_ */ diff --git a/libelf/elf.3 b/libelf/elf.3 index 462e72854177..97677eb205d6 100644 --- a/libelf/elf.3 +++ b/libelf/elf.3 @@ -21,9 +21,9 @@ .\" 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 $ +.\" $Id: elf.3 3082 2014-07-28 09:13:33Z jkoshy $ .\" -.Dd August 14, 2011 +.Dd July 28, 2014 .Os .Dt ELF 3 .Sh NAME @@ -367,6 +367,11 @@ 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_GNU_HASH Ta Dv ELF_T_GNUHASH Ta GNU hash sections. +.It Dv SHT_GNU_LIBLIST Ta Dv ELF_T_WORD Ta List of libraries to be pre-linked. +.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_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. @@ -383,12 +388,31 @@ See .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_dof Ta Dv ELF_T_BYTE Ta Xo +Used by +.Xr dtrace 1 . +.Xc .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. +.It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo +Same as +.Dv SHT_GNU_verdef . +.Xc +.It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo +Same as +.Dv SHT_GNU_verneed . +.Xc +.It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo +Same as +.Dv SHT_GNU_versym . +.Xc .El +.Pp +Section types in the range +.Ns [ Dv SHT_LOOS , +.Dv SHT_HIUSER ] +are otherwise considered to be of type +.Dv ELF_T_BYTE . .TE .Ss Functional Grouping This section contains a brief overview of the available functionality diff --git a/libelf/elf_data.c b/libelf/elf_data.c index 06a3577dc5dd..9960b77bea27 100644 --- a/libelf/elf_data.c +++ b/libelf/elf_data.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_data.c 2921 2013-03-04 16:19:22Z jkoshy $"); +ELFTC_VCSID("$Id: elf_data.c 3009 2014-03-23 01:49:59Z jkoshy $"); Elf_Data * elf_getdata(Elf_Scn *s, Elf_Data *ed) @@ -39,10 +39,11 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) Elf *e; unsigned int sh_type; int elfclass, elftype; - size_t fsz, msz, count; + size_t count, fsz, msz; 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); + int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); d = (struct _Libelf_Data *) ed; @@ -108,11 +109,23 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) return (NULL); } - count = sh_size / fsz; + if (sh_size / fsz > SIZE_MAX) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + + count = (size_t) (sh_size / fsz); msz = _libelf_msize(elftype, elfclass, e->e_version); + if (count > 0 && msz > SIZE_MAX / count) { + LIBELF_SET_ERROR(RANGE, 0); + return (NULL); + } + assert(msz > 0); + assert(count <= SIZE_MAX); + assert(msz * count <= SIZE_MAX); if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); @@ -129,7 +142,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) return (&d->d_data); } - if ((d->d_data.d_buf = malloc(msz*count)) == NULL) { + if ((d->d_data.d_buf = malloc(msz * count)) == NULL) { (void) _libelf_release_data(d); LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); @@ -138,7 +151,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed) 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, + if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size, e->e_rawfile + sh_offset, count, e->e_byteorder != LIBELF_PRIVATE(byteorder))) { _libelf_release_data(d); diff --git a/libelf/elf_errmsg.c b/libelf/elf_errmsg.c index adcaa74b29ba..409862cc1557 100644 --- a/libelf/elf_errmsg.c +++ b/libelf/elf_errmsg.c @@ -32,13 +32,13 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_errmsg.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_errmsg.c 3012 2014-03-23 03:41:38Z jkoshy $"); /* * Retrieve a human readable translation for an error message. */ -const char *_libelf_errors[] = { +static 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"), @@ -76,7 +76,7 @@ elf_errmsg(int error) if (error < ELF_E_NONE || error >= ELF_E_NUM) return _libelf_errors[ELF_E_NUM]; if (oserr) { - (void) snprintf(LIBELF_PRIVATE(msg), + (void) snprintf((char *) LIBELF_PRIVATE(msg), sizeof(LIBELF_PRIVATE(msg)), "%s: %s", _libelf_errors[error], strerror(oserr)); return (const char *)&LIBELF_PRIVATE(msg); diff --git a/libelf/elf_flag.c b/libelf/elf_flag.c index ab9d24a0ecea..89af3160da6a 100644 --- a/libelf/elf_flag.c +++ b/libelf/elf_flag.c @@ -30,7 +30,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: elf_flag.c 2988 2014-03-17 08:51:49Z jkoshy $"); unsigned int elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) @@ -111,7 +111,7 @@ elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) unsigned int elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) { - int r; + unsigned int r; if (e == NULL) return (0); @@ -173,7 +173,7 @@ elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) unsigned int elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) { - int r; + unsigned int r; if (s == NULL) return (0); diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c index 9c4755d0f59b..d70f6e094912 100644 --- a/libelf/elf_memory.c +++ b/libelf/elf_memory.c @@ -28,7 +28,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); +ELFTC_VCSID("$Id: elf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $"); Elf * elf_memory(char *image, size_t sz) @@ -43,5 +43,5 @@ elf_memory(char *image, size_t sz) return (NULL); } - return (_libelf_memory(image, sz, 1)); + return (_libelf_memory((unsigned char *) image, sz, 1)); } diff --git a/libelf/elf_next.c b/libelf/elf_next.c index 605a593dd9e3..7da8ba6fe857 100644 --- a/libelf/elf_next.c +++ b/libelf/elf_next.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_next.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_next.c 2989 2014-03-17 09:56:46Z jkoshy $"); Elf_Cmd elf_next(Elf *e) @@ -48,13 +48,17 @@ elf_next(Elf *e) return (ELF_C_NULL); } - assert (parent->e_kind == ELF_K_AR); - assert (parent->e_cmd == ELF_C_READ); + 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 = e->e_rawfile - parent->e_rawfile + (off_t) e->e_rawsize; next = (next + 1) & ~1; /* round up to an even boundary */ + /* + * Setup the 'e_next' field of the archive descriptor for the + * next call to 'elf_begin()'. + */ parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? (off_t) 0 : next; diff --git a/libelf/elf_open.c b/libelf/elf_open.c index b039431571fb..5aad459f4002 100644 --- a/libelf/elf_open.c +++ b/libelf/elf_open.c @@ -63,5 +63,5 @@ elf_openmemory(char *image, size_t sz) return (NULL); } - return (_libelf_memory(image, sz, 0)); + return (_libelf_memory((unsigned char *) image, sz, 0)); } diff --git a/libelf/elf_rand.c b/libelf/elf_rand.c index f48f01745802..8c36ff809702 100644 --- a/libelf/elf_rand.c +++ b/libelf/elf_rand.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_rand.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_rand.c 2991 2014-03-17 09:57:04Z jkoshy $"); off_t elf_rand(Elf *ar, off_t offset) @@ -40,7 +40,7 @@ elf_rand(Elf *ar, off_t offset) if (ar == NULL || ar->e_kind != ELF_K_AR || (offset & 1) || offset < SARMAG || - offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { + (size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { LIBELF_SET_ERROR(ARGUMENT, 0); return 0; } diff --git a/libelf/elf_rawfile.c b/libelf/elf_rawfile.c index 76cfd7fa3435..a5b5b3ed5f7f 100644 --- a/libelf/elf_rawfile.c +++ b/libelf/elf_rawfile.c @@ -30,13 +30,13 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_rawfile.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_rawfile.c 3013 2014-03-23 06:16:59Z jkoshy $"); char * elf_rawfile(Elf *e, size_t *sz) { - char *ptr; size_t size; + unsigned char *ptr; size = e ? e->e_rawsize : 0; ptr = NULL; @@ -49,5 +49,5 @@ elf_rawfile(Elf *e, size_t *sz) if (sz) *sz = size; - return (ptr); + return ((char *) ptr); } diff --git a/libelf/elf_scn.c b/libelf/elf_scn.c index 357fbb33d847..f80711579d59 100644 --- a/libelf/elf_scn.c +++ b/libelf/elf_scn.c @@ -36,7 +36,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: elf_scn.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Load an ELF section table and create a list of Elf_Scn structures. @@ -44,14 +44,15 @@ ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $"); int _libelf_load_section_headers(Elf *e, void *ehdr) { - int ec, swapbytes; - size_t fsz, i, shnum; + Elf_Scn *scn; 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); + int ec, swapbytes; + unsigned char *src; + size_t fsz, i, shnum; + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(e != NULL); assert(ehdr != NULL); @@ -104,8 +105,8 @@ _libelf_load_section_headers(Elf *e, void *ehdr) if ((scn = _libelf_allocate_scn(e, i)) == NULL) return (0); - (*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src, - (size_t) 1, swapbytes); + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + src, (size_t) 1, swapbytes); if (ec == ELFCLASS32) { scn->s_offset = scn->s_rawoff = diff --git a/libelf/elf_strptr.c b/libelf/elf_strptr.c index c79970dc8907..e2a6b2899f58 100644 --- a/libelf/elf_strptr.c +++ b/libelf/elf_strptr.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: elf_strptr.c 2271 2011-12-03 17:06:35Z jkoshy $"); +ELFTC_VCSID("$Id: elf_strptr.c 2990 2014-03-17 09:56:58Z jkoshy $"); /* * Convert an ELF section#,offset pair to a string pointer. @@ -42,8 +42,8 @@ elf_strptr(Elf *e, size_t scndx, size_t offset) { Elf_Scn *s; Elf_Data *d; - size_t alignment, count; GElf_Shdr shdr; + uint64_t alignment, count; if (e == NULL || e->e_kind != ELF_K_ELF) { LIBELF_SET_ERROR(ARGUMENT, 0); @@ -90,7 +90,7 @@ elf_strptr(Elf *e, size_t scndx, size_t offset) * account 'holes' in coverage of the section introduced * by alignment requirements. */ - count = (size_t) 0; /* cumulative count of bytes seen */ + count = (uint64_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) diff --git a/libelf/elf_update.c b/libelf/elf_update.c index b589233c8e4a..70a7c2e21e25 100644 --- a/libelf/elf_update.c +++ b/libelf/elf_update.c @@ -41,7 +41,7 @@ #include <sys/mman.h> #endif -ELFTC_VCSID("$Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy $"); +ELFTC_VCSID("$Id: elf_update.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Layout strategy: @@ -110,14 +110,13 @@ SLIST_HEAD(_Elf_Extent_List, _Elf_Extent); static int _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) { - int ec; Elf_Data *d; size_t fsz, msz; + int ec, elftype; 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; @@ -253,7 +252,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc) 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); + (size_t) d->d_size / msz); scn_size += fsz; } @@ -307,7 +306,7 @@ computeoffset: * Compute the new offset for the section based on * the section's alignment needs. */ - sh_offset = roundup(rc, sh_align); + sh_offset = roundup((uint64_t) rc, sh_align); /* * Update the section header. @@ -471,7 +470,7 @@ _libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents) return ((off_t) -1); if ((size_t) rc < s->s_offset + s->s_size) - rc = s->s_offset + s->s_size; + rc = (off_t) (s->s_offset + s->s_size); } return (rc); @@ -529,17 +528,22 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) 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; + phoff = (off_t) eh32->e_phoff; + shoff = (off_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; + phoff = (off_t) eh64->e_phoff; + shoff = (off_t) eh64->e_shoff; eh_version = eh64->e_version; } + if (phoff < 0 || shoff < 0) { + LIBELF_SET_ERROR(HEADER, 0); + return ((off_t) -1); + } + if (eh_version == EV_NONE) eh_version = EV_CURRENT; @@ -564,18 +568,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) e->e_byteorder = eh_byteorder; #define INITIALIZE_EHDR(E,EC,V) do { \ + unsigned int _version = (unsigned int) (V); \ (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); \ + (E)->e_ident[EI_CLASS] = (unsigned char) (EC); \ + (E)->e_ident[EI_VERSION] = (_version & 0xFFU); \ + (E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \ + (EC), _version, (size_t) 1); \ + (E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \ + _libelf_fsize(ELF_T_PHDR, (EC), _version, \ + (size_t) 1)); \ + (E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \ + (EC), _version, (size_t) 1); \ } while (0) if (ec == ELFCLASS32) @@ -585,9 +591,10 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) (void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY); - rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); + rc += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); - if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) rc, + ehdr)) return ((off_t) -1); /* @@ -608,20 +615,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) return ((off_t) -1); } - if (phoff % align) { + if (phoff % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else - phoff = roundup(rc, align); + phoff = roundup(rc, (off_t) align); - rc = phoff + fsz; + rc = phoff + (off_t) fsz; phdr = _libelf_getphdr(e, ec); - if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff, - fsz, phdr)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, + (uint64_t) phoff, fsz, phdr)) return ((off_t) -1); } else phoff = 0; @@ -656,18 +663,18 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) align = _libelf_falign(ELF_T_SHDR, ec); if (e->e_flags & ELF_F_LAYOUT) { - if (shoff % align) { + if (shoff % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else - shoff = roundup(rc, align); + shoff = roundup(rc, (off_t) align); - if (shoff + fsz > (size_t) rc) - rc = shoff + fsz; + if (shoff + (off_t) fsz > rc) + rc = shoff + (off_t) fsz; - if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff, - fsz, NULL)) + if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, + (uint64_t) shoff, fsz, NULL)) return ((off_t) -1); } else shoff = 0; @@ -700,22 +707,23 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents) * Write out the contents of an ELF section. */ -static size_t -_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) +static off_t +_libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; + off_t rc; 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; + size_t fsz, msz, nobjects; assert(ex->ex_type == ELF_EXTENT_SECTION); s = ex->ex_desc; - rc = ex->ex_start; + rc = (off_t) ex->ex_start; if ((ec = e->e_class) == ELFCLASS32) { sh_type = s->s_shdr.s_shdr32.sh_type; @@ -756,18 +764,20 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) 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; + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - + (uint64_t) rc)); + rc = (off_t) (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); + e->e_rawfile + s->s_rawoff + d->d_off, + (size_t) d->d_size); - rc += d->d_size; + rc += (off_t) d->d_size; } return (rc); @@ -789,15 +799,16 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, - LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc); + LIBELF_PRIVATE(fillchar), + (size_t) (sh_off + d->d_off - (uint64_t) rc)); - rc = sh_off + d->d_off; + rc = (off_t) (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; + nobjects = (size_t) (d->d_size / msz); fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects); @@ -808,10 +819,10 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) NULL) return ((off_t) -1); - rc += fsz; + rc += (off_t) fsz; } - return ((off_t) rc); + return (rc); } /* @@ -819,7 +830,7 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -860,7 +871,7 @@ _libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -909,7 +920,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) NULL) return ((off_t) -1); - return (phoff + fsz); + return ((off_t) (phoff + fsz)); } /* @@ -917,7 +928,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex) */ static off_t -_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) +_libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { int ec; void *ehdr; @@ -969,7 +980,7 @@ _libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex) return ((off_t) -1); } - return (ex->ex_start + nscn * fsz); + return ((off_t) (ex->ex_start + nscn * fsz)); } /* @@ -993,9 +1004,9 @@ 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; + unsigned char *newfile; assert(e->e_kind == ELF_K_ELF); assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE); @@ -1012,7 +1023,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) /* Fill inter-extent gaps. */ if (ex->ex_start > (size_t) rc) (void) memset(newfile + rc, LIBELF_PRIVATE(fillchar), - ex->ex_start - rc); + (size_t) (ex->ex_start - (uint64_t) rc)); switch (ex->ex_type) { case ELF_EXTENT_EHDR: @@ -1103,7 +1114,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents) #endif /* ELFTC_HAVE_MMAP */ /* Record the new size of the file. */ - e->e_rawsize = newsize; + e->e_rawsize = (size_t) newsize; } else { /* File opened in ELF_C_WRITE mode. */ assert(e->e_rawfile == NULL); diff --git a/libelf/gelf_cap.c b/libelf/gelf_cap.c index a1c1417be1fa..9925d1bd214f 100644 --- a/libelf/gelf_cap.c +++ b/libelf/gelf_cap.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_cap.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_cap.c 2995 2014-03-18 02:16:31Z jkoshy $"); GElf_Cap * gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) @@ -72,7 +72,7 @@ gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) assert(msz > 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,7 +131,7 @@ gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) msz = _libelf_msize(ELF_T_CAP, ec, e->e_version); assert(msz > 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_dyn.c b/libelf/gelf_dyn.c index 263102603397..4e09afd12ce2 100644 --- a/libelf/gelf_dyn.c +++ b/libelf/gelf_dyn.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_dyn.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_dyn.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Dyn * gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) @@ -71,8 +71,9 @@ gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -128,9 +129,11 @@ gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) } msz = _libelf_msize(ELF_T_DYN, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_move.c b/libelf/gelf_move.c index d9e8993deee4..2b734eba53b8 100644 --- a/libelf/gelf_move.c +++ b/libelf/gelf_move.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_move.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_move.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Move * gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) @@ -71,8 +71,9 @@ gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,9 +132,11 @@ gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) } msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_rel.c b/libelf/gelf_rel.c index eb057177d4cc..3b798c042201 100644 --- a/libelf/gelf_rel.c +++ b/libelf/gelf_rel.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_rel.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_rel.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Rel * gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) @@ -71,8 +71,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) msz = _libelf_msize(ELF_T_REL, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -130,9 +131,11 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) } msz = _libelf_msize(ELF_T_REL, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } @@ -147,8 +150,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) 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)); + rel32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); } else { rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; diff --git a/libelf/gelf_rela.c b/libelf/gelf_rela.c index cb61bdc2e2df..ed289a674d1f 100644 --- a/libelf/gelf_rela.c +++ b/libelf/gelf_rela.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_rela.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_rela.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Rela * gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) @@ -71,8 +71,9 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -131,9 +132,11 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) } msz = _libelf_msize(ELF_T_RELA, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } @@ -148,8 +151,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) 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)); + rela32->r_info = ELF32_R_INFO( + (Elf32_Word) ELF64_R_SYM(dr->r_info), + (Elf32_Word) ELF64_R_TYPE(dr->r_info)); LIBELF_COPY_S32(rela32, dr, r_addend); } else { diff --git a/libelf/gelf_sym.c b/libelf/gelf_sym.c index 4a490d9ee079..e32a1869cea7 100644 --- a/libelf/gelf_sym.c +++ b/libelf/gelf_sym.c @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_sym.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_sym.c 2999 2014-03-18 17:19:06Z jkoshy $"); GElf_Sym * gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) @@ -71,25 +71,23 @@ gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) 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_info = 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; @@ -133,9 +131,11 @@ gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) } msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_syminfo.c b/libelf/gelf_syminfo.c index bb2063d9a2d4..e54258292aa1 100644 --- a/libelf/gelf_syminfo.c +++ b/libelf/gelf_syminfo.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_syminfo.c 2272 2011-12-03 17:07:31Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_syminfo.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Syminfo * gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) @@ -70,8 +70,9 @@ gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -128,9 +129,11 @@ gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) } msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= d->d_data.d_size) { + if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/gelf_symshndx.c b/libelf/gelf_symshndx.c index 9cf3b7578183..69fabe55ce03 100644 --- a/libelf/gelf_symshndx.c +++ b/libelf/gelf_symshndx.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: gelf_symshndx.c 2283 2011-12-04 04:07:24Z jkoshy $"); +ELFTC_VCSID("$Id: gelf_symshndx.c 2998 2014-03-18 17:19:00Z jkoshy $"); GElf_Sym * gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, @@ -74,8 +74,9 @@ gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= id->d_size) { + if (msz * (size_t) ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } @@ -123,9 +124,11 @@ gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs, } msz = _libelf_msize(ELF_T_WORD, ec, e->e_version); + assert(msz > 0); + assert(ndx >= 0); - if (msz * ndx >= id->d_size) { + if (msz * (size_t) ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } diff --git a/libelf/libelf.h b/libelf/libelf.h index d3219d7ce251..41e7224956fc 100644 --- a/libelf/libelf.h +++ b/libelf/libelf.h @@ -23,7 +23,7 @@ * 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 $ + * $Id: libelf.h 2988 2014-03-17 08:51:49Z jkoshy $ */ #ifndef _LIBELF_H_ @@ -129,7 +129,7 @@ typedef struct { /* * Members that are not part of the public API. */ - int ar_flags; + unsigned int ar_flags; } Elf_Arhdr; /* diff --git a/libelf/libelf_align.c b/libelf/libelf_align.c index 9550c5bd49ea..817fd1588565 100644 --- a/libelf/libelf_align.c +++ b/libelf/libelf_align.c @@ -32,11 +32,11 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_align.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_align.c 3006 2014-03-22 08:10:07Z jkoshy $"); struct align { - int a32; - int a64; + unsigned int a32; + unsigned int a64; }; #ifdef __GNUC__ @@ -87,7 +87,7 @@ static struct align malign[ELF_T_NUM] = { [ELF_T_GNUHASH] = MALIGN_WORD() }; -int +unsigned int _libelf_malign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) @@ -126,7 +126,7 @@ static struct align falign[ELF_T_NUM] = { [ELF_T_GNUHASH] = FALIGN(4,8) }; -int +unsigned int _libelf_falign(Elf_Type t, int elfclass) { if (t >= ELF_T_NUM || (int) t < 0) diff --git a/libelf/libelf_ar.c b/libelf/libelf_ar.c index c990d6dc971a..0830dd6fc069 100644 --- a/libelf/libelf_ar.c +++ b/libelf/libelf_ar.c @@ -35,7 +35,7 @@ #include "_libelf.h" #include "_libelf_ar.h" -ELFTC_VCSID("$Id: libelf_ar.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ar.c 3013 2014-03-23 06:16:59Z jkoshy $"); #define LIBELF_NALLOC_SIZE 16 @@ -110,8 +110,8 @@ Elf_Arhdr * _libelf_ar_gethdr(Elf *e) { Elf *parent; - char *namelen; Elf_Arhdr *eh; + char *namelen; size_t n, nlen; struct ar_hdr *arh; @@ -192,7 +192,7 @@ _libelf_ar_gethdr(Elf *e) } e->e_flags &= ~LIBELF_F_AR_HEADER; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; return (NULL); } @@ -201,10 +201,10 @@ Elf * _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) { Elf *e; - char *member, *namelen; - size_t nsz, sz; off_t next; + size_t nsz, sz; struct ar_hdr *arh; + char *member, *namelen; assert(elf->e_kind == ELF_K_AR); @@ -249,12 +249,12 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) member = (char *) (arh + 1); - if ((e = elf_memory((char *) member, sz)) == NULL) + if ((e = elf_memory(member, sz)) == NULL) return (NULL); e->e_fd = fd; e->e_cmd = c; - e->e_hdr.e_rawhdr = (char *) arh; + e->e_hdr.e_rawhdr = (unsigned char *) arh; elf->e_u.e_ar.e_nchildren++; e->e_parent = elf; @@ -274,9 +274,10 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) */ /* - * 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'. + * 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)); \ @@ -287,9 +288,10 @@ Elf_Arsym * _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) { Elf_Arsym *symtab, *sym; + unsigned int n, nentries; unsigned char *end, *p, *p0, *s, *s0; - const unsigned int entrysize = 2 * sizeof(long); - long arraysize, fileoffset, n, nentries, stroffset, strtabsize; + const size_t entrysize = 2 * sizeof(long); + long arraysize, fileoffset, stroffset, strtabsize; assert(e != NULL); assert(count != NULL); @@ -313,7 +315,8 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) */ GET_LONG(p, arraysize); - if (p0 + arraysize >= end || (arraysize % entrysize != 0)) + if (arraysize < 0 || p0 + arraysize >= end || + ((size_t) arraysize % entrysize != 0)) goto symtaberror; /* @@ -323,10 +326,10 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(s, strtabsize); s0 = s; /* Start of string table. */ - if (s0 + strtabsize > end) + if (strtabsize < 0 || s0 + strtabsize > end) goto symtaberror; - nentries = arraysize / entrysize; + nentries = (size_t) arraysize / entrysize; /* * Allocate space for the returned Elf_Arsym array. @@ -341,12 +344,16 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count) GET_LONG(p, stroffset); GET_LONG(p, fileoffset); + if (stroffset < 0 || fileoffset < 0 || + (size_t) fileoffset >= e->e_rawsize) + goto symtaberror; + s = s0 + stroffset; if (s >= end) goto symtaberror; - sym->as_off = fileoffset; + sym->as_off = (off_t) fileoffset; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; } @@ -393,7 +400,8 @@ symtaberror: Elf_Arsym * _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) { - size_t n, nentries, off; + uint32_t off; + size_t n, nentries; Elf_Arsym *symtab, *sym; unsigned char *p, *s, *end; @@ -424,15 +432,14 @@ _libelf_ar_process_svr4_symtab(Elf *e, size_t *count) 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); + if (off >= e->e_rawsize) + goto symtaberror; - sym->as_off = off; + sym->as_off = (off_t) off; sym->as_hash = elf_hash((char *) s); sym->as_name = (char *) s; diff --git a/libelf/libelf_ar_util.c b/libelf/libelf_ar_util.c index 958fbbf49022..7e6ec4068f69 100644 --- a/libelf/libelf_ar_util.c +++ b/libelf/libelf_ar_util.c @@ -34,21 +34,23 @@ #include "_libelf.h" #include "_libelf_ar.h" -ELFTC_VCSID("$Id: libelf_ar_util.c 2365 2011-12-29 04:36:44Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ar_util.c 3013 2014-03-23 06:16:59Z 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) +_libelf_ar_get_number(const char *src, size_t sz, unsigned int base, + size_t *ret) { - int c, v; size_t r; - const char *e; + unsigned int c, v; + const unsigned char *e, *s; assert(base <= 10); + s = (const unsigned char *) src; e = s + sz; /* skip leading blanks */ @@ -79,17 +81,18 @@ _libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret) char * _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) { - char c, *s; + char *s; + unsigned char c; size_t len, offset; - const char *buf, *p, *q, *r; + const unsigned 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); + assert((const unsigned char *) arh >= ar->e_rawfile && + (const unsigned char *) arh < ar->e_rawfile + ar->e_rawsize); - buf = arh->ar_name; + buf = (const unsigned char *) arh->ar_name; /* * Check for extended naming. @@ -104,8 +107,8 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) * the archive string table where the actual name * resides. */ - if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10, - &offset) == 0) { + if (_libelf_ar_get_number((const char *) (buf + 1), + bufsize - 1, 10, &offset) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); return (NULL); } @@ -120,21 +123,21 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) for (; p < r && *p != '/'; p++) ; - len = p - q + 1; /* space for the trailing NUL */ + len = (size_t) (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); + (void) strncpy(s, (const char *) 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 - + if (_libelf_ar_get_number((const char *) r, bufsize - LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10, &len) == 0) { LIBELF_SET_ERROR(ARCHIVE, 0); @@ -153,9 +156,9 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) /* * The file name follows the archive header. */ - q = (const char *) (arh + 1); + q = (const unsigned char *) (arh + 1); - (void) strncpy(s, q, len); + (void) strncpy(s, (const char *) q, len); s[len] = '\0'; return (s); @@ -183,10 +186,10 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) q--; } - len = q - buf + 2; /* Add space for a trailing NUL. */ + len = (size_t) (q - buf + 2); /* Space for a trailing NUL. */ } else { /* The buffer only had blanks. */ - buf = ""; + buf = (const unsigned char *) ""; len = 1; } @@ -195,7 +198,7 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar) return (NULL); } - (void) strncpy(s, buf, len - 1); + (void) strncpy(s, (const char *) buf, len - 1); s[len - 1] = '\0'; return (s); @@ -229,8 +232,8 @@ _libelf_ar_open(Elf *e, int reporterror) { size_t sz; int scanahead; - char *s, *end; struct ar_hdr arh; + unsigned char *s, *end; _libelf_init_elf(e, ELF_K_AR); @@ -264,7 +267,7 @@ _libelf_ar_open(Elf *e, int reporterror) (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, \ + if (_libelf_ar_get_number((char *) (ARH).ar_size, \ sizeof((ARH).ar_size), 10, &(SZ)) == 0) \ goto error; \ } while (0) diff --git a/libelf/libelf_checksum.c b/libelf/libelf_checksum.c index 8f84aa4d0f05..f05f9a936404 100644 --- a/libelf/libelf_checksum.c +++ b/libelf/libelf_checksum.c @@ -30,7 +30,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_checksum.c 3003 2014-03-22 07:43:10Z jkoshy $"); static unsigned long _libelf_sum(unsigned long c, const unsigned char *s, size_t size) @@ -44,7 +44,7 @@ _libelf_sum(unsigned long c, const unsigned char *s, size_t size) return (c); } -unsigned long +long _libelf_checksum(Elf *e, int elfclass) { size_t shn; @@ -90,11 +90,11 @@ _libelf_checksum(Elf *e, int elfclass) d = NULL; while ((d = elf_rawdata(scn, d)) != NULL) checksum = _libelf_sum(checksum, - (unsigned char *) d->d_buf, d->d_size); + (unsigned char *) d->d_buf, (size_t) d->d_size); } /* * Return a 16-bit checksum compatible with Solaris. */ - return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); + return (long) (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL)); } diff --git a/libelf/libelf_convert.m4 b/libelf/libelf_convert.m4 index 0e0e4fd8ff35..fc9cf394a24d 100644 --- a/libelf/libelf_convert.m4 +++ b/libelf/libelf_convert.m4 @@ -32,7 +32,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_convert.m4 3009 2014-03-23 01:49:59Z jkoshy $"); /* WARNING: GENERATED FROM __file__. */ @@ -143,8 +143,8 @@ define(`SIZEDEP_OFF', 1) # 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) +_libelf_cvt_$1$4_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src; size_t c; @@ -166,8 +166,8 @@ _libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$4_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst; size_t c; @@ -267,8 +267,8 @@ define(`READ_STRUCT', # `$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) +_libelf_cvt_$1$3_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$3_$2 t, *s; size_t c; @@ -288,16 +288,16 @@ _libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$3_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { - Elf$3_$2 t, *d; - char *s,*s0; + Elf$3_$2 t, *d; + unsigned 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; + s0 = src + (count - 1) * fsz; if (dsz < count * sizeof(Elf$3_$2)) return (0); @@ -398,8 +398,8 @@ define(`MAKE_VERSION_CONVERTERS', # 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) +_libelf_cvt_$1$5_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$5_$2 t; Elf$5_$3 a; @@ -407,12 +407,12 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, 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; + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dtmp, *dstaux, *srcaux; Elf$5_Word aux, anext, cnt, vnext; - for (dtmp = dst, vnext = ~0; + for (dtmp = dst, vnext = ~0U; vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend; dtmp += vnext, src += vnext) { @@ -434,7 +434,7 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, return (0); /* Process AUX entries. */ - for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux; + for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux; cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend && srcaux + auxmsz <= srcend; dstaux += anext, srcaux += anext, cnt--) { @@ -462,8 +462,8 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_$1$5_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { Elf$5_$2 t, *dp; Elf$5_$3 a, *ap; @@ -471,12 +471,12 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, 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; + unsigned char * const dstend = dst + dsz; + unsigned char * const srcend = src + count; + unsigned char *dstaux, *s, *srcaux, *stmp; Elf$5_Word aux, anext, cnt, vnext; - for (stmp = src, vnext = ~0; + for (stmp = src, vnext = ~0U; vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; stmp += vnext, dst += vnext) { @@ -498,7 +498,7 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count, return (0); /* Process AUX entries. */ - for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux; + for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && srcaux + auxfsz <= srcend; dstaux += anext, srcaux += anext, cnt--) { @@ -536,22 +536,23 @@ divert(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; \ + uint32_t _t = _x & 0xFFU; \ + _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ + (X) = (uint16_t) _t; \ } while (0) -#define SWAP_WORD(X) do { \ +#define _SWAP_WORD(X, T) 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; \ + (X) = (T) _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 { \ +#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) +#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) +#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) +#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) +#define _SWAP_WORD64(X, T) do { \ uint64_t _x = (uint64_t) (X); \ uint64_t _t = _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ @@ -561,13 +562,13 @@ divert(0) _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ - (X) = _t; \ + (X) = (T) _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) +#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) +#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) +#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) +#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) +#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) /* * C macros to write out various integral values. @@ -578,22 +579,22 @@ divert(0) * - The destination pointer is incremented after the write. */ #define WRITE_BYTE(P,X) do { \ - char *const _p = (char *) (P); \ - _p[0] = (char) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + _p[0] = (unsigned 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; \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned 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; \ +#define WRITE_WORD(P,X) do { \ + uint32_t _t = (uint32_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ @@ -604,9 +605,9 @@ divert(0) #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; \ + uint64_t _t = (uint64_t) (X); \ + unsigned char *const _p = (unsigned char *) (P); \ + const unsigned char *const _q = (unsigned char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ _p[2] = _q[2]; \ @@ -637,41 +638,42 @@ divert(0) */ #define READ_BYTE(P,X) do { \ - const char *const _p = \ - (const char *) (P); \ + const unsigned char *const _p = \ + (const unsigned 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); \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ (P) = (P) + 2; \ (X) = _t; \ } while (0) -#define READ_WORD(P,X) do { \ +#define _READ_WORD(P,X,T) do { \ uint32_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ _q[2] = _p[2]; \ _q[3] = _p[3]; \ (P) = (P) + 4; \ - (X) = _t; \ + (X) = (T) _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 { \ +#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) +#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) +#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) +#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) +#define _READ_WORD64(P,X,T) do { \ uint64_t _t; \ - char *const _q = (char *) &_t; \ - const char *const _p = \ - (const char *) (P); \ + unsigned char *const _q = (unsigned char *) &_t; \ + const unsigned char *const _p = \ + (const unsigned char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ _q[2] = _p[2]; \ @@ -681,13 +683,13 @@ divert(0) _q[6] = _p[6]; \ _q[7] = _p[7]; \ (P) = (P) + 8; \ - (X) = _t; \ + (X) = (T) _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_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) +#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) +#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) +#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) +#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) #define READ_IDENT(P,X) do { \ (void) memcpy((X), (P), sizeof((X))); \ (P) = (P) + EI_NIDENT; \ @@ -707,8 +709,8 @@ MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn) */ static int -_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { (void) byteswap; if (dsz < count) @@ -732,24 +734,24 @@ _libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count, */ static int -_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) +_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned 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) +_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned 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) +_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) { size_t sz; uint64_t t64, *bloom64; @@ -834,8 +836,8 @@ _libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz, } static int -_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, - int byteswap) +_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t srcsz, int byteswap) { uint32_t *s32; size_t sz, hdrsz; @@ -921,8 +923,8 @@ _libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz, * 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) +_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; @@ -962,8 +964,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, dst += sizeof(Elf_Note); count -= hdrsz; - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); sz = namesz + descsz; @@ -983,8 +985,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count, } static int -_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, - int byteswap) +_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src, + size_t count, int byteswap) { uint32_t namesz, descsz, type; Elf_Note *en; @@ -1015,8 +1017,8 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, src += sizeof(Elf_Note); - ROUNDUP2(namesz, 4); - ROUNDUP2(descsz, 4); + ROUNDUP2(namesz, 4U); + ROUNDUP2(descsz, 4U); sz = namesz + descsz; @@ -1034,14 +1036,14 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count, } 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); + int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); + int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, + size_t cnt, int byteswap); }; @@ -1070,7 +1072,8 @@ CONVERTER_NAMES(ELF_TYPE_LIST) }; int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) - (char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap) + (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt, + int _byteswap) { assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); diff --git a/libelf/libelf_data.c b/libelf/libelf_data.c index 809002f71e78..f078c36ab755 100644 --- a/libelf/libelf_data.c +++ b/libelf/libelf_data.c @@ -30,11 +30,14 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_data.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_data.c 3080 2014-07-28 08:46:17Z jkoshy $"); int _libelf_xlate_shtype(uint32_t sht) { + /* + * Look for known section types. + */ switch (sht) { case SHT_DYNAMIC: return (ELF_T_DYN); @@ -83,6 +86,18 @@ _libelf_xlate_shtype(uint32_t sht) case SHT_SUNW_versym: /* == SHT_GNU_versym */ return (ELF_T_HALF); default: + /* + * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e., + * OS, processor and user-defined section types) are + * legal, but since we do not know anything more about + * their semantics, we return a type of ELF_T_BYTE. + */ + if (sht >= SHT_LOOS && sht <= SHT_HIUSER) + return (ELF_T_BYTE); + + /* + * Other values are unsupported. + */ return (-1); } } diff --git a/libelf/libelf_ehdr.c b/libelf/libelf_ehdr.c index 363a0a834b9f..d59f61f2ba1e 100644 --- a/libelf/libelf_ehdr.c +++ b/libelf/libelf_ehdr.c @@ -33,7 +33,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_ehdr.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_ehdr.c 3009 2014-03-23 01:49:59Z jkoshy $"); /* * Retrieve counts for sections, phdrs and the section string table index @@ -45,7 +45,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, { Elf_Scn *scn; size_t fsz; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); uint32_t shtype; assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); @@ -62,8 +63,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, 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, + (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), + (unsigned char *) 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 : \ @@ -74,7 +75,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, return (0); } - e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size); + e->e_u.e_elf.e_nscn = (size_t) 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 : @@ -92,7 +93,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, 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_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \ eh->e_machine = EM_NONE; \ eh->e_type = ELF_K_NONE; \ eh->e_version = LIBELF_PRIVATE(version); \ @@ -105,7 +106,8 @@ _libelf_ehdr(Elf *e, int ec, int allocate) 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); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); @@ -167,7 +169,7 @@ _libelf_ehdr(Elf *e, int ec, int allocate) return (ehdr); xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); - (*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1, + (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); /* diff --git a/libelf/libelf_extended.c b/libelf/libelf_extended.c index 5343696548d4..f1a77d17efba 100644 --- a/libelf/libelf_extended.c +++ b/libelf/libelf_extended.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_extended.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_extended.c 3005 2014-03-22 07:43:25Z jkoshy $"); /* * Retrieve section #0, allocating a new section if needed. @@ -69,9 +69,9 @@ _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shnum = shnum; + ((Elf32_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_shnum = shnum; + ((Elf64_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; return (1); @@ -99,9 +99,9 @@ _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx; + ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx; + ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; return (1); } @@ -128,9 +128,9 @@ _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum) } if (ec == ELFCLASS32) - ((Elf32_Ehdr *) eh)->e_phnum = phnum; + ((Elf32_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; else - ((Elf64_Ehdr *) eh)->e_phnum = phnum; + ((Elf64_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; return (1); } diff --git a/libelf/libelf_memory.c b/libelf/libelf_memory.c index 892e909b079c..cb8e8f20438a 100644 --- a/libelf/libelf_memory.c +++ b/libelf/libelf_memory.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $"); /* * Create an ELF descriptor for a memory image, optionally reporting @@ -39,7 +39,7 @@ ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $"); */ Elf * -_libelf_memory(char *image, size_t sz, int reporterror) +_libelf_memory(unsigned char *image, size_t sz, int reporterror) { Elf *e; int e_class; @@ -89,7 +89,7 @@ _libelf_memory(char *image, size_t sz, int reporterror) e->e_version = e_version; } } else if (sz >= SARMAG && - strncmp(image, ARMAG, (size_t) SARMAG) == 0) + strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0) return (_libelf_ar_open(e, reporterror)); return (e); diff --git a/libelf/libelf_open.c b/libelf/libelf_open.c index 6d93c73a0312..7ec33952dfe1 100644 --- a/libelf/libelf_open.c +++ b/libelf/libelf_open.c @@ -39,7 +39,7 @@ #include <sys/mman.h> #endif -ELFTC_VCSID("$Id: libelf_open.c 2932 2013-03-30 01:26:04Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_open.c 3007 2014-03-22 08:10:14Z jkoshy $"); #define _LIBELF_INITSIZE (64*1024) @@ -73,11 +73,11 @@ _libelf_read_special_file(int fd, size_t *fsz) } do { - readsz = bufsz - datasz; + assert(bufsz - datasz > 0); t = buf + datasz; - if ((readsz = read(fd, t, readsz)) <= 0) + if ((readsz = read(fd, t, bufsz - datasz)) <= 0) break; - datasz += readsz; + datasz += (size_t) readsz; } while (datasz < bufsz); } while (readsz > 0); diff --git a/libelf/libelf_phdr.c b/libelf/libelf_phdr.c index f2eb697fbc04..f44c3cd7e44e 100644 --- a/libelf/libelf_phdr.c +++ b/libelf/libelf_phdr.c @@ -33,7 +33,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_phdr.c 2931 2013-03-23 11:41:07Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_phdr.c 3009 2014-03-23 01:49:59Z jkoshy $"); void * _libelf_getphdr(Elf *e, int ec) @@ -44,7 +44,8 @@ _libelf_getphdr(Elf *e, int ec) Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; void *ehdr, *phdr; - int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap); + int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, + size_t _c, int _swap); assert(ec == ELFCLASS32 || ec == ELFCLASS64); diff --git a/libelf/libelf_xlate.c b/libelf/libelf_xlate.c index eda6df8c2260..4cc6a452e4dd 100644 --- a/libelf/libelf_xlate.c +++ b/libelf/libelf_xlate.c @@ -31,7 +31,7 @@ #include "_libelf.h" -ELFTC_VCSID("$Id: libelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_xlate.c 3007 2014-03-22 08:10:14Z jkoshy $"); /* * Translate to/from the file representation of ELF objects. @@ -99,10 +99,10 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, * buffer. */ if (direction == ELF_TOMEMORY) { - cnt = src->d_size / fsz; + cnt = (size_t) src->d_size / fsz; dsz = cnt * msz; } else { - cnt = src->d_size / msz; + cnt = (size_t) src->d_size / msz; dsz = cnt * fsz; } @@ -112,9 +112,9 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding, } sb = (uintptr_t) src->d_buf; - se = sb + src->d_size; + se = sb + (size_t) src->d_size; db = (uintptr_t) dst->d_buf; - de = db + dst->d_size; + de = db + (size_t) dst->d_size; /* * Check for overlapping buffers. Note that db == sb is diff --git a/libelftc/elftc_copyfile.c b/libelftc/elftc_copyfile.c index 0bacaf45e769..7df1678e702d 100644 --- a/libelftc/elftc_copyfile.c +++ b/libelftc/elftc_copyfile.c @@ -37,7 +37,7 @@ #include <sys/mman.h> #endif -ELFTC_VCSID("$Id: elftc_copyfile.c 2318 2011-12-11 10:54:27Z jkoshy $"); +ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $"); /* * Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on @@ -79,11 +79,13 @@ elftc_copyfile(int ifd, int ofd) * If mmap() is not available, or if the mmap() operation * failed, allocate a buffer, and read in input data. */ - if (buf == NULL) { + if (buf_mmapped == false) { if ((buf = malloc(sb.st_size)) == NULL) return (-1); - if (read(ifd, buf, sb.st_size) != sb.st_size) + if (read(ifd, buf, sb.st_size) != sb.st_size) { + free(buf); return (-1); + } } /* diff --git a/libelftc/elftc_demangle.c b/libelftc/elftc_demangle.c index c55564e3df63..9639d630c6e8 100644 --- a/libelftc/elftc_demangle.c +++ b/libelftc/elftc_demangle.c @@ -29,14 +29,13 @@ #include <sys/param.h> #include <assert.h> #include <errno.h> -#include <libelf.h> #include <libelftc.h> #include <stdlib.h> #include <string.h> #include "_libelftc.h" -ELFTC_VCSID("$Id: elftc_demangle.c 2065 2011-10-26 15:24:47Z jkoshy $"); +ELFTC_VCSID("$Id: elftc_demangle.c 3030 2014-05-01 06:30:48Z kaiwang27 $"); static int is_mangled(const char *s, int style) diff --git a/libelftc/libelftc.h b/libelftc/libelftc.h index aa6b0b6ffe1e..85e4feb3a710 100644 --- a/libelftc/libelftc.h +++ b/libelftc/libelftc.h @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $ - * $Id: libelftc.h 2863 2013-01-06 03:18:32Z jkoshy $ + * $Id: libelftc.h 3031 2014-05-01 17:45:41Z jkoshy $ */ #ifndef _LIBELFTC_H_ @@ -34,6 +34,9 @@ #include <libelf.h> +/* + * Types meant to be opaque to the consumers of these APIs. + */ typedef struct _Elftc_Bfd_Target Elftc_Bfd_Target; typedef struct _Elftc_String_Table Elftc_String_Table; diff --git a/libelftc/libelftc_dem_gnu3.c b/libelftc/libelftc_dem_gnu3.c index bd54f549ddb8..05a6302816c9 100644 --- a/libelftc/libelftc_dem_gnu3.c +++ b/libelftc/libelftc_dem_gnu3.c @@ -36,7 +36,7 @@ #include "_libelftc.h" -ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 2179 2011-11-18 03:05:47Z jkoshy $"); +ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3123 2014-12-21 05:46:19Z kaiwang27 $"); /** * @file cpp_demangle.c @@ -156,7 +156,7 @@ static int vector_type_qualifier_init(struct vector_type_qualifier *); static int vector_type_qualifier_push(struct vector_type_qualifier *, enum type_qualifier); -int cpp_demangle_gnu3_push_head; +static int cpp_demangle_gnu3_push_head; /** * @brief Decode the input string by IA-64 C++ ABI style. diff --git a/mk/elftoolchain.lib.mk b/mk/elftoolchain.lib.mk index fab71507cb2c..f62dfc0ffdcc 100644 --- a/mk/elftoolchain.lib.mk +++ b/mk/elftoolchain.lib.mk @@ -1,5 +1,5 @@ # -# $Id: elftoolchain.lib.mk 2796 2012-12-19 12:44:09Z jkoshy $ +# $Id: elftoolchain.lib.mk 3026 2014-04-18 16:20:30Z jkoshy $ # .if !defined(TOP) @@ -11,7 +11,10 @@ .include <bsd.lib.mk> # Support a 'clobber' target. -clobber: clean .PHONY +clobber: clean os-specific-clobber .PHONY + +# Remove '.depend' files on a "make clean". +CLEANFILES+= .depend # Adjust CFLAGS CFLAGS+= -I. # OBJDIR diff --git a/mk/elftoolchain.os.mk b/mk/elftoolchain.os.mk index 31d37959f6bb..ab7c227dfeee 100644 --- a/mk/elftoolchain.os.mk +++ b/mk/elftoolchain.os.mk @@ -1,5 +1,5 @@ # -# $Id: elftoolchain.os.mk 2068 2011-10-26 15:49:07Z jkoshy $ +# $Id: elftoolchain.os.mk 2985 2014-03-06 03:24:35Z jkoshy $ # # OS specific build instructions @@ -19,4 +19,8 @@ OS_HOST != uname -s .include "${.CURDIR}/os.${OS_HOST}.mk" .endif +# Supply an OS-specific "clobber" rule, if one was not specified. +.if !target(os-specific-clobber) +os-specific-clobber: .PHONY +.endif .endif diff --git a/mk/elftoolchain.prog.mk b/mk/elftoolchain.prog.mk index 8d822cdf58ea..f19902a9a830 100644 --- a/mk/elftoolchain.prog.mk +++ b/mk/elftoolchain.prog.mk @@ -1,7 +1,7 @@ # # Rules for building programs. # -# $Id: elftoolchain.prog.mk 2796 2012-12-19 12:44:09Z jkoshy $ +# $Id: elftoolchain.prog.mk 2985 2014-03-06 03:24:35Z jkoshy $ .if !defined(TOP) .error Make variable \"TOP\" has not been defined. @@ -76,7 +76,7 @@ ${_L:R}.o: ${_Y:R}.h .include "${TOP}/mk/elftoolchain.m4.mk" # Support a 'clobber' target. -clobber: clean .PHONY +clobber: clean os-specific-clobber .PHONY .if defined(DEBUG) CFLAGS:= ${CFLAGS:N-O*} -g diff --git a/mk/elftoolchain.subdir.mk b/mk/elftoolchain.subdir.mk index c41878d2f5c6..fa3c60e07187 100644 --- a/mk/elftoolchain.subdir.mk +++ b/mk/elftoolchain.subdir.mk @@ -1,6 +1,6 @@ # # Rules for recursing into directories -# $Id: elftoolchain.subdir.mk 2292 2011-12-04 08:09:17Z jkoshy $ +# $Id: elftoolchain.subdir.mk 3023 2014-04-17 18:06:06Z jkoshy $ # Pass down 'test' as a valid target. @@ -12,8 +12,8 @@ clobber test:: _SUBDIR SUBDIR_TARGETS+= clobber test .elif ${OS_HOST} == OpenBSD clobber test:: _SUBDIRUSE -.else # NetBSD -TARGETS+= clobber test +.else # NetBSD, pmake on Linux +TARGETS+= cleandepend clobber test .endif .include <bsd.subdir.mk> diff --git a/mk/elftoolchain.tetbase.mk b/mk/elftoolchain.tetbase.mk new file mode 100644 index 000000000000..6eeebc1da722 --- /dev/null +++ b/mk/elftoolchain.tetbase.mk @@ -0,0 +1,46 @@ +# $Id$ + +# Convenience rules for the top level directory containing a TET-based test +# suite. + +.if !defined(TOP) +.error Make variable \"TOP\" has not been defined. +.endif + +.include "${TOP}/mk/elftoolchain.tetvars.mk" + +.MAIN: all +.PHONY: clobber execute tccbuild tccclean test + + +# Set up the environment for invoking "tcc", based on the target +# specified. + +.if !defined(TET_EXECUTE) +TET_EXECUTE= ${.OBJDIR} +.endif + +.if make(tccbuild) +TET_OPTIONS+= -b +.endif + +.if make(tccclean) +TET_OPTIONS+= -c +.endif + +.if make(execute) || make(test) +TET_OPTIONS+= -e +.endif + +execute tccbuild tccclean test: + TET_ROOT=${TET_ROOT} TET_EXECUTE=${TET_EXECUTE} \ + TET_SUITE_ROOT=${.CURDIR} ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . + +clobber: clean + rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} + +# Ensure that a 'make test' does not recurse further into the test suite's +# directory hierarchy. +.if !make(test) +.include "${TOP}/mk/elftoolchain.subdir.mk" +.endif diff --git a/mk/os.Linux.mk b/mk/os.Linux.mk index 553c3e14bc32..a8208c8a846f 100644 --- a/mk/os.Linux.mk +++ b/mk/os.Linux.mk @@ -1,6 +1,14 @@ -# $Id: os.Linux.mk 2569 2012-09-04 16:34:04Z jkoshy $ +# $Id: os.Linux.mk 3103 2014-11-02 10:07:01Z jkoshy $ # -# Build recipes for Debian GNU/Linux based operating systems. +# Build recipes for GNU/Linux based operating systems. + +OS_DISTRIBUTION != lsb_release -s -i || echo unknown +OS_DISTRIBUTION_VERSION != lsb_release -s -r || echo unknown + +.if ${OS_DISTRIBUTION} == "unknown" || \ + ${OS_DISTRIBUTION_VERSION} == "unknown" +.error ERROR: Unknown host OS distribution. +.endif MKDOC?= yes # Build documentation. MKLINT?= no diff --git a/mk/os.NetBSD.mk b/mk/os.NetBSD.mk index 99d6b9953e72..6ebd1c193e1f 100644 --- a/mk/os.NetBSD.mk +++ b/mk/os.NetBSD.mk @@ -1,4 +1,4 @@ -# $Id: os.NetBSD.mk 2569 2012-09-04 16:34:04Z jkoshy $ +# $Id: os.NetBSD.mk 2986 2014-03-06 03:29:12Z jkoshy $ # # Build recipes for NetBSD. @@ -11,3 +11,11 @@ MKNOWEB?= no # Build literate programs. # Literate programming utility. NOWEB?= /usr/pkgsrc/bin/noweb + +# NetBSD's 'clean' target does not remove 'cat[0-9]' and 'html[0-9]' +# files generate from manual page sources. Augment the 'clobber' +# target to remove these. +os-specific-clobber: .PHONY +.for f in cat html + rm -f ${MANPAGES:@M@${M:R}.$f${M:E}@} +.endfor @@ -48,7 +48,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: nm.c 2484 2012-04-07 15:52:05Z kaiwang27 $"); +ELFTC_VCSID("$Id: nm.c 3124 2014-12-21 05:46:28Z kaiwang27 $"); /* symbol information list */ STAILQ_HEAD(sym_head, sym_entry); @@ -65,7 +65,7 @@ typedef void (*fn_sym_print)(const GElf_Sym *); typedef int (*fn_filter)(char, const GElf_Sym *, const char *); /* output filter list */ -SLIST_HEAD(filter_head, filter_entry) nm_out_filter = +static SLIST_HEAD(filter_head, filter_entry) nm_out_filter = SLIST_HEAD_INITIALIZER(nm_out_filter); struct filter_entry { diff --git a/readelf/readelf.1 b/readelf/readelf.1 index 9a6efe58fab0..8419d95fbce8 100644 --- a/readelf/readelf.1 +++ b/readelf/readelf.1 @@ -22,7 +22,7 @@ .\" (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: readelf.1 2577 2012-09-13 16:07:04Z jkoshy $ +.\" $Id: readelf.1 3059 2014-06-02 00:42:32Z kaiwang27 $ .\" .Dd September 13, 2012 .Os @@ -139,7 +139,7 @@ option names: .It p Ta pubnames Ta Show global names. .It r Ta aranges|ranges Ta Show address range information. .It s Ta str Ta Show the debug string table. -.It F Ta Ta Show frame information, displaying register rules. +.It F Ta frames-interp Ta Show frame information, displaying register rules. .It L Ta decodedline Ta Show line information in decoded form. .It R Ta Ranges Ta Show range lists. .El diff --git a/readelf/readelf.c b/readelf/readelf.c index 779a7ba9e875..16159ad09ea9 100644 --- a/readelf/readelf.c +++ b/readelf/readelf.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009,2010 Kai Wang + * Copyright (c) 2009-2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: readelf.c 2946 2013-05-26 08:00:11Z kaiwang27 $"); +ELFTC_VCSID("$Id: readelf.c 3110 2014-12-20 08:32:46Z kaiwang27 $"); /* * readelf(1) options. @@ -145,6 +145,9 @@ struct readelf { Elf *elf; /* underlying ELF descriptor. */ Elf *ar; /* archive ELF descriptor. */ Dwarf_Debug dbg; /* DWARF handle. */ + Dwarf_Half cu_psize; /* DWARF CU pointer size. */ + Dwarf_Half cu_osize; /* DWARF CU offset size. */ + Dwarf_Half cu_ver; /* DWARF CU version. */ GElf_Ehdr ehdr; /* ELF header. */ int ec; /* ELF class. */ size_t shnum; /* #sections. */ @@ -254,6 +257,30 @@ static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); static void dump_attributes(struct readelf *re); static uint8_t *dump_compatibility_tag(uint8_t *p); static void dump_dwarf(struct readelf *re); +static void dump_dwarf_abbrev(struct readelf *re); +static void dump_dwarf_aranges(struct readelf *re); +static void dump_dwarf_block(struct readelf *re, uint8_t *b, + Dwarf_Unsigned len); +static void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level); +static void dump_dwarf_frame(struct readelf *re, int alt); +static void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, + uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, + Dwarf_Addr pc, Dwarf_Debug dbg); +static int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, + Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra); +static void dump_dwarf_frame_section(struct readelf *re, struct section *s, + int alt); +static void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info); +static void dump_dwarf_macinfo(struct readelf *re); +static void dump_dwarf_line(struct readelf *re); +static void dump_dwarf_line_decoded(struct readelf *re); +static void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr); +static void dump_dwarf_loclist(struct readelf *re); +static void dump_dwarf_pubnames(struct readelf *re); +static void dump_dwarf_ranges(struct readelf *re); +static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, + Dwarf_Addr base); +static void dump_dwarf_str(struct readelf *re); static void dump_eflags(struct readelf *re, uint64_t e_flags); static void dump_elf(struct readelf *re); static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab); @@ -282,8 +309,12 @@ static void dump_ver(struct readelf *re); static void dump_verdef(struct readelf *re, int dump); static void dump_verneed(struct readelf *re, int dump); static void dump_versym(struct readelf *re); -static struct dumpop *find_dumpop(struct readelf *re, size_t si, const char *sn, - int op, int t); +static const char *dwarf_reg(unsigned int mach, unsigned int reg); +static const char *dwarf_regname(struct readelf *re, unsigned int num); +static struct dumpop *find_dumpop(struct readelf *re, size_t si, + const char *sn, int op, int t); +static char *get_regoff_str(struct readelf *re, Dwarf_Half reg, + Dwarf_Addr off); static const char *get_string(struct readelf *re, int strtab, size_t off); static const char *get_symbol_name(struct readelf *re, int symtab, int i); static uint64_t get_symbol_value(struct readelf *re, int symtab, int i); @@ -298,8 +329,12 @@ static const char *ppc_abi_vector(uint64_t vec); static const char *r_type(unsigned int mach, unsigned int type); static void readelf_usage(void); static void readelf_version(void); +static void search_loclist_at(struct readelf *re, Dwarf_Die die, + Dwarf_Unsigned lowpc); static void search_ver(struct readelf *re); static const char *section_type(unsigned int mach, unsigned int stype); +static void set_cu_context(struct readelf *re, Dwarf_Half psize, + Dwarf_Half osize, Dwarf_Half ver); static const char *st_bind(unsigned int sbind); static const char *st_shndx(unsigned int shndx); static const char *st_type(unsigned int stype); @@ -487,6 +522,7 @@ elf_machine(unsigned int mach) case EM_SEP: return "Sharp embedded microprocessor"; case EM_ARCA: return "Arca RISC Microprocessor"; case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd"; + case EM_AARCH64: return "AArch64"; default: snprintf(s_mach, sizeof(s_mach), "<unknown: %#x>", mach); return (s_mach); @@ -1041,6 +1077,67 @@ r_type(unsigned int mach, unsigned int type) case 37: return "R_386_TLS_TPOFF32"; default: return ""; } + case EM_AARCH64: + switch(type) { + case 0: return "R_AARCH64_NONE"; + case 257: return "R_AARCH64_ABS64"; + case 258: return "R_AARCH64_ABS32"; + case 259: return "R_AARCH64_ABS16"; + case 260: return "R_AARCH64_PREL64"; + case 261: return "R_AARCH64_PREL32"; + case 262: return "R_AARCH64_PREL16"; + case 263: return "R_AARCH64_MOVW_UABS_G0"; + case 264: return "R_AARCH64_MOVW_UABS_G0_NC"; + case 265: return "R_AARCH64_MOVW_UABS_G1"; + case 266: return "R_AARCH64_MOVW_UABS_G1_NC"; + case 267: return "R_AARCH64_MOVW_UABS_G2"; + case 268: return "R_AARCH64_MOVW_UABS_G2_NC"; + case 269: return "R_AARCH64_MOVW_UABS_G3"; + case 270: return "R_AARCH64_MOVW_SABS_G0"; + case 271: return "R_AARCH64_MOVW_SABS_G1"; + case 272: return "R_AARCH64_MOVW_SABS_G2"; + case 273: return "R_AARCH64_LD_PREL_LO19"; + case 274: return "R_AARCH64_ADR_PREL_LO21"; + case 275: return "R_AARCH64_ADR_PREL_PG_HI21"; + case 276: return "R_AARCH64_ADR_PREL_PG_HI21_NC"; + case 277: return "R_AARCH64_ADD_ABS_LO12_NC"; + case 278: return "R_AARCH64_LDST8_ABS_LO12_NC"; + case 279: return "R_AARCH64_TSTBR14"; + case 280: return "R_AARCH64_CONDBR19"; + case 282: return "R_AARCH64_JUMP26"; + case 283: return "R_AARCH64_CALL26"; + case 284: return "R_AARCH64_LDST16_ABS_LO12_NC"; + case 285: return "R_AARCH64_LDST32_ABS_LO12_NC"; + case 286: return "R_AARCH64_LDST64_ABS_LO12_NC"; + case 287: return "R_AARCH64_MOVW_PREL_G0"; + case 288: return "R_AARCH64_MOVW_PREL_G0_NC"; + case 289: return "R_AARCH64_MOVW_PREL_G1"; + case 290: return "R_AARCH64_MOVW_PREL_G1_NC"; + case 291: return "R_AARCH64_MOVW_PREL_G2"; + case 292: return "R_AARCH64_MOVW_PREL_G2_NC"; + case 293: return "R_AARCH64_MOVW_PREL_G3"; + case 299: return "R_AARCH64_LDST128_ABS_LO12_NC"; + case 300: return "R_AARCH64_MOVW_GOTOFF_G0"; + case 301: return "R_AARCH64_MOVW_GOTOFF_G0_NC"; + case 302: return "R_AARCH64_MOVW_GOTOFF_G1"; + case 303: return "R_AARCH64_MOVW_GOTOFF_G1_NC"; + case 304: return "R_AARCH64_MOVW_GOTOFF_G2"; + case 305: return "R_AARCH64_MOVW_GOTOFF_G2_NC"; + case 306: return "R_AARCH64_MOVW_GOTOFF_G3"; + case 307: return "R_AARCH64_GOTREL64"; + case 308: return "R_AARCH64_GOTREL32"; + case 309: return "R_AARCH64_GOT_LD_PREL19"; + case 310: return "R_AARCH64_LD64_GOTOFF_LO15"; + case 311: return "R_AARCH64_ADR_GOT_PAGE"; + case 312: return "R_AARCH64_LD64_GOT_LO12_NC"; + case 313: return "R_AARCH64_LD64_GOTPAGE_LO15"; + case 1024: return "R_AARCH64_COPY"; + case 1025: return "R_AARCH64_GLOB_DAT"; + case 1026: return "R_AARCH64_JUMP_SLOT"; + case 1027: return "R_AARCH64_RELATIVE"; + case 1031: return "R_AARCH64_TLSDESC"; + default: return ""; + } case EM_ARM: switch(type) { case 0: return "R_ARM_NONE"; @@ -2185,6 +2282,124 @@ ppc_abi_vector(uint64_t vec) } } +static const char * +dwarf_reg(unsigned int mach, unsigned int reg) +{ + + switch (mach) { + case EM_386: + switch (reg) { + case 0: return "eax"; + case 1: return "ecx"; + case 2: return "edx"; + case 3: return "ebx"; + case 4: return "esp"; + case 5: return "ebp"; + case 6: return "esi"; + case 7: return "edi"; + case 8: return "eip"; + case 9: return "eflags"; + case 11: return "st0"; + case 12: return "st1"; + case 13: return "st2"; + case 14: return "st3"; + case 15: return "st4"; + case 16: return "st5"; + case 17: return "st6"; + case 18: return "st7"; + case 21: return "xmm0"; + case 22: return "xmm1"; + case 23: return "xmm2"; + case 24: return "xmm3"; + case 25: return "xmm4"; + case 26: return "xmm5"; + case 27: return "xmm6"; + case 28: return "xmm7"; + case 29: return "mm0"; + case 30: return "mm1"; + case 31: return "mm2"; + case 32: return "mm3"; + case 33: return "mm4"; + case 34: return "mm5"; + case 35: return "mm6"; + case 36: return "mm7"; + case 37: return "fcw"; + case 38: return "fsw"; + case 39: return "mxcsr"; + case 40: return "es"; + case 41: return "cs"; + case 42: return "ss"; + case 43: return "ds"; + case 44: return "fs"; + case 45: return "gs"; + case 48: return "tr"; + case 49: return "ldtr"; + default: return (NULL); + } + case EM_X86_64: + switch (reg) { + case 0: return "rax"; + case 1: return "rdx"; + case 2: return "rcx"; + case 3: return "rbx"; + case 4: return "rsi"; + case 5: return "rdi"; + case 6: return "rbp"; + case 7: return "rsp"; + case 16: return "rip"; + case 17: return "xmm0"; + case 18: return "xmm1"; + case 19: return "xmm2"; + case 20: return "xmm3"; + case 21: return "xmm4"; + case 22: return "xmm5"; + case 23: return "xmm6"; + case 24: return "xmm7"; + case 25: return "xmm8"; + case 26: return "xmm9"; + case 27: return "xmm10"; + case 28: return "xmm11"; + case 29: return "xmm12"; + case 30: return "xmm13"; + case 31: return "xmm14"; + case 32: return "xmm15"; + case 33: return "st0"; + case 34: return "st1"; + case 35: return "st2"; + case 36: return "st3"; + case 37: return "st4"; + case 38: return "st5"; + case 39: return "st6"; + case 40: return "st7"; + case 41: return "mm0"; + case 42: return "mm1"; + case 43: return "mm2"; + case 44: return "mm3"; + case 45: return "mm4"; + case 46: return "mm5"; + case 47: return "mm6"; + case 48: return "mm7"; + case 49: return "rflags"; + case 50: return "es"; + case 51: return "cs"; + case 52: return "ss"; + case 53: return "ds"; + case 54: return "fs"; + case 55: return "gs"; + case 58: return "fs.base"; + case 59: return "gs.base"; + case 62: return "tr"; + case 63: return "ldtr"; + case 64: return "mxcsr"; + case 65: return "fcw"; + case 66: return "fsw"; + default: return (NULL); + } + default: + return (NULL); + } +} + static void dump_ehdr(struct readelf *re) { @@ -3220,7 +3435,7 @@ dump_gnu_hash(struct readelf *re, struct section *s) Elf_Data *d; uint32_t *buf; uint32_t *bucket, *chain; - uint32_t nbucket, nchain, symndx, maskwords, shift2; + uint32_t nbucket, nchain, symndx, maskwords; uint32_t *bl, *c, maxl, total; int elferr, dynsymcount, i, j; @@ -3240,7 +3455,6 @@ dump_gnu_hash(struct readelf *re, struct section *s) nbucket = buf[0]; symndx = buf[1]; maskwords = buf[2]; - shift2 = buf[3]; buf += 4; ds = &re->sl[s->link]; dynsymcount = ds->sz / ds->entsize; @@ -4165,6 +4379,20 @@ dump_arch_specific_info(struct readelf *re) } } +static const char * +dwarf_regname(struct readelf *re, unsigned int num) +{ + static char rx[32]; + const char *rn; + + if ((rn = dwarf_reg(re->ehdr.e_machine, num)) != NULL) + return (rn); + + snprintf(rx, sizeof(rx), "r%u", num); + + return (rx); +} + static void dump_dwarf_line(struct readelf *re) { @@ -4180,9 +4408,7 @@ dump_dwarf_line(struct readelf *re) int64_t sdelta; uint8_t *p, *pe; int8_t lbase; - int is_stmt, basic_block, end_sequence; - int prologue_end, epilogue_begin; - int i, dwarf_size, elferr, ret; + int i, is_stmt, dwarf_size, elferr, ret; printf("\nDump of debug contents of section .debug_line:\n"); @@ -4298,10 +4524,6 @@ dump_dwarf_line(struct readelf *re) line = 1; \ column = 0; \ is_stmt = defstmt; \ - basic_block = 0; \ - end_sequence = 0; \ - prologue_end = 0; \ - epilogue_begin = 0; \ } while(0) #define LINE(x) (lbase + (((x) - opbase) % lrange)) @@ -4326,7 +4548,6 @@ dump_dwarf_line(struct readelf *re) switch (*p) { case DW_LNE_end_sequence: p++; - end_sequence = 1; RESET_REGISTERS; printf("End of Sequence\n"); break; @@ -4357,9 +4578,6 @@ dump_dwarf_line(struct readelf *re) */ switch(*p++) { case DW_LNS_copy: - basic_block = 0; - prologue_end = 0; - epilogue_begin = 0; printf(" Copy\n"); break; case DW_LNS_advance_pc: @@ -4392,7 +4610,6 @@ dump_dwarf_line(struct readelf *re) printf(" Set is_stmt to %d\n", is_stmt); break; case DW_LNS_set_basic_block: - basic_block = 1; printf(" Set basic block flag\n"); break; case DW_LNS_const_add_pc: @@ -4411,11 +4628,9 @@ dump_dwarf_line(struct readelf *re) (uintmax_t) address); break; case DW_LNS_set_prologue_end: - prologue_end = 1; printf(" Set prologue end flag\n"); break; case DW_LNS_set_epilogue_begin: - epilogue_begin = 1; printf(" Set epilogue begin flag\n"); break; case DW_LNS_set_isa: @@ -4435,9 +4650,6 @@ dump_dwarf_line(struct readelf *re) */ line += LINE(*p); address += ADDRESS(*p); - basic_block = 0; - prologue_end = 0; - epilogue_begin = 0; printf(" Special opcode %u: advance Address " "by %ju to %#jx and Line by %jd to %ju\n", *p - opbase, (uintmax_t) ADDRESS(*p), @@ -4514,18 +4726,21 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) { Dwarf_Attribute *attr_list; Dwarf_Die ret_die; - Dwarf_Off dieoff, cuoff, culen; - Dwarf_Unsigned ate, v_udata; + Dwarf_Off dieoff, cuoff, culen, attroff; + Dwarf_Unsigned ate, lang, v_udata, v_sig; Dwarf_Signed attr_count, v_sdata; Dwarf_Off v_off; Dwarf_Addr v_addr; Dwarf_Half tag, attr, form; Dwarf_Block *v_block; - Dwarf_Bool v_bool; + Dwarf_Bool v_bool, is_info; + Dwarf_Sig8 v_sig8; Dwarf_Error de; - const char *tag_str, *attr_str, *ate_str; + Dwarf_Ptr v_expr; + const char *tag_str, *attr_str, *ate_str, *lang_str; + char unk_tag[32], unk_attr[32]; char *v_str; - uint8_t *b; + uint8_t *b, *p; int i, j, abc, ret; if (dwarf_dieoffset(die, &dieoff, &de) != DW_DLV_OK) { @@ -4533,7 +4748,7 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) goto cont_search; } - printf("<%d><%jx>: ", level, (uintmax_t) dieoff); + printf(" <%d><%jx>: ", level, (uintmax_t) dieoff); if (dwarf_die_CU_offset_range(die, &cuoff, &culen, &de) != DW_DLV_OK) { warnx("dwarf_die_CU_offset_range failed: %s", @@ -4547,8 +4762,8 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) goto cont_search; } if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { - warnx("dwarf_get_TAG_name failed"); - goto cont_search; + snprintf(unk_tag, sizeof(unk_tag), "[Unknown Tag: %#x]", tag); + tag_str = unk_tag; } printf("Abbrev Number: %d (%s)\n", abc, tag_str); @@ -4570,19 +4785,29 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) continue; } if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { - warnx("dwarf_get_AT_name failed"); - continue; + snprintf(unk_attr, sizeof(unk_attr), + "[Unknown AT: %#x]", attr); + attr_str = unk_attr; + } + if (dwarf_attroffset(attr_list[i], &attroff, &de) != + DW_DLV_OK) { + warnx("dwarf_attroffset failed: %s", dwarf_errmsg(de)); + attroff = 0; } - printf(" %-18s: ", attr_str); + printf(" <%jx> %-18s: ", (uintmax_t) attroff, attr_str); switch (form) { case DW_FORM_ref_addr: + case DW_FORM_sec_offset: if (dwarf_global_formref(attr_list[i], &v_off, &de) != DW_DLV_OK) { warnx("dwarf_global_formref failed: %s", dwarf_errmsg(de)); continue; } - printf("<%jx>", (uintmax_t) v_off); + if (form == DW_FORM_ref_addr) + printf("<0x%jx>", (uintmax_t) v_off); + else + printf("0x%jx", (uintmax_t) v_off); break; case DW_FORM_ref1: @@ -4597,7 +4822,7 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) continue; } v_off += cuoff; - printf("<%jx>", (uintmax_t) v_off); + printf("<0x%jx>", (uintmax_t) v_off); break; case DW_FORM_addr: @@ -4621,7 +4846,10 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) dwarf_errmsg(de)); continue; } - printf("%ju", (uintmax_t) v_udata); + if (attr == DW_AT_high_pc) + printf("0x%jx", (uintmax_t) v_udata); + else + printf("%ju", (uintmax_t) v_udata); break; case DW_FORM_sdata: @@ -4644,6 +4872,10 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) printf("%jd", (intmax_t) v_bool); break; + case DW_FORM_flag_present: + putchar('1'); + break; + case DW_FORM_string: case DW_FORM_strp: if (dwarf_formstring(attr_list[i], &v_str, &de) != @@ -4668,11 +4900,41 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) dwarf_errmsg(de)); continue; } - printf("%ju byte block:", v_block->bl_len); + printf("%ju byte block:", (uintmax_t) v_block->bl_len); b = v_block->bl_data; for (j = 0; (Dwarf_Unsigned) j < v_block->bl_len; j++) printf(" %x", b[j]); + printf("\t("); + dump_dwarf_block(re, v_block->bl_data, v_block->bl_len); + putchar(')'); + break; + + case DW_FORM_exprloc: + if (dwarf_formexprloc(attr_list[i], &v_udata, &v_expr, + &de) != DW_DLV_OK) { + warnx("dwarf_formexprloc failed: %s", + dwarf_errmsg(de)); + continue; + } + printf("%ju byte block:", (uintmax_t) v_udata); + b = v_expr; + for (j = 0; (Dwarf_Unsigned) j < v_udata; j++) + printf(" %x", b[j]); + printf("\t("); + dump_dwarf_block(re, v_expr, v_udata); + putchar(')'); break; + + case DW_FORM_ref_sig8: + if (dwarf_formsig8(attr_list[i], &v_sig8, &de) != + DW_DLV_OK) { + warnx("dwarf_formsig8 failed: %s", + dwarf_errmsg(de)); + continue; + } + p = (uint8_t *)(uintptr_t) &v_sig8.signature[0]; + v_sig = re->dw_decode(&p, 8); + printf("signature: 0x%jx", (uintmax_t) v_sig); } switch (attr) { case DW_AT_encoding: @@ -4680,9 +4942,38 @@ dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) DW_DLV_OK) break; if (dwarf_get_ATE_name(ate, &ate_str) != DW_DLV_OK) - break; + ate_str = "DW_ATE_UNKNOWN"; printf("\t(%s)", &ate_str[strlen("DW_ATE_")]); break; + + case DW_AT_language: + if (dwarf_attrval_unsigned(die, attr, &lang, &de) != + DW_DLV_OK) + break; + if (dwarf_get_LANG_name(lang, &lang_str) != DW_DLV_OK) + break; + printf("\t(%s)", &lang_str[strlen("DW_LANG_")]); + break; + + 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 (form) { + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_sec_offset: + printf("\t(location list)"); + break; + default: + break; + } + default: break; } @@ -4699,7 +4990,8 @@ cont_search: dump_dwarf_die(re, ret_die, level + 1); /* Search sibling. */ - ret = dwarf_siblingof(re->dbg, die, &ret_die, &de); + is_info = dwarf_get_die_infotypes_flag(die); + ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) @@ -4709,73 +5001,108 @@ cont_search: } static void -dump_dwarf_info(struct readelf *re) +set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, + Dwarf_Half ver) +{ + + re->cu_psize = psize; + re->cu_osize = osize; + re->cu_ver = ver; +} + +static void +dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info) { struct section *s; Dwarf_Die die; Dwarf_Error de; - Dwarf_Half tag, version, pointer_size; + Dwarf_Half tag, version, pointer_size, off_size; Dwarf_Off cu_offset, cu_length; Dwarf_Off aboff; - Elf_Data *d; - int i, elferr, ret; + Dwarf_Unsigned typeoff; + Dwarf_Sig8 sig8; + Dwarf_Unsigned sig; + uint8_t *p; + const char *sn; + int i, ret; - printf("\nDump of debug contents of section .debug_info:\n"); + sn = is_info ? ".debug_info" : ".debug_types"; s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; - if (s->name != NULL && !strcmp(s->name, ".debug_info")) + if (s->name != NULL && !strcmp(s->name, sn)) break; } if ((size_t) i >= re->shnum) return; - (void) elf_errno(); - if ((d = elf_getdata(s->scn, NULL)) == NULL) { - elferr = elf_errno(); - if (elferr != 0) - warnx("elf_getdata failed: %s", elf_errmsg(-1)); - return; - } - if (d->d_size <= 0) - return; + do { + printf("\nDump of debug contents of section %s:\n", sn); + + while ((ret = dwarf_next_cu_header_c(re->dbg, is_info, NULL, + &version, &aboff, &pointer_size, &off_size, NULL, &sig8, + &typeoff, NULL, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); + die = NULL; + while (dwarf_siblingof_b(re->dbg, die, &die, is_info, + &de) == DW_DLV_OK) { + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + /* XXX: What about DW_TAG_partial_unit? */ + if ((is_info && tag == DW_TAG_compile_unit) || + (!is_info && tag == DW_TAG_type_unit)) + break; + } + if (die == NULL && is_info) { + warnx("could not find DW_TAG_compile_unit " + "die"); + continue; + } else if (die == NULL && !is_info) { + warnx("could not find DW_TAG_type_unit die"); + continue; + } - while ((ret = dwarf_next_cu_header(re->dbg, NULL, &version, &aboff, - &pointer_size, NULL, &de)) == DW_DLV_OK) { - die = NULL; - while (dwarf_siblingof(re->dbg, die, &die, &de) == DW_DLV_OK) { - if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { - warnx("dwarf_tag failed: %s", + if (dwarf_die_CU_offset_range(die, &cu_offset, + &cu_length, &de) != DW_DLV_OK) { + warnx("dwarf_die_CU_offset failed: %s", dwarf_errmsg(de)); - return; + continue; } - /* XXX: What about DW_TAG_partial_unit? */ - if (tag == DW_TAG_compile_unit) - break; - } - if (die == NULL) { - warnx("could not find DW_TAG_compile_unit die"); - return; - } - if (dwarf_die_CU_offset_range(die, &cu_offset, &cu_length, - &de) != DW_DLV_OK) { - warnx("dwarf_die_CU_offset failed: %s", - dwarf_errmsg(de)); - continue; - } + cu_length -= off_size == 4 ? 4 : 12; - printf(" Compilation Unit @ %jd:\n", (intmax_t) cu_offset); - printf(" Length:\t\t%jd\n", (intmax_t) cu_length); - printf(" Version:\t\t%u\n", version); - printf(" Abbrev Offset:\t%ju\n", (uintmax_t) aboff); - printf(" Pointer Size:\t%u\n", pointer_size); + sig = 0; + if (!is_info) { + p = (uint8_t *)(uintptr_t) &sig8.signature[0]; + sig = re->dw_decode(&p, 8); + } - dump_dwarf_die(re, die, 0); - } - if (ret == DW_DLV_ERROR) - warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + printf("\n Type Unit @ offset 0x%jx:\n", + (uintmax_t) cu_offset); + printf(" Length:\t\t%#jx (%d-bit)\n", + (uintmax_t) cu_length, off_size == 4 ? 32 : 64); + printf(" Version:\t\t%u\n", version); + printf(" Abbrev Offset:\t0x%jx\n", + (uintmax_t) aboff); + printf(" Pointer Size:\t%u\n", pointer_size); + if (!is_info) { + printf(" Signature:\t\t0x%016jx\n", + (uintmax_t) sig); + printf(" Type Offset:\t0x%jx\n", + (uintmax_t) typeoff); + } + + dump_dwarf_die(re, die, 0); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + if (is_info) + break; + } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); } static void @@ -4788,6 +5115,7 @@ dump_dwarf_abbrev(struct readelf *re) Dwarf_Half tag, attr; Dwarf_Error de; const char *tag_str, *attr_str, *form_str; + char unk_tag[32], unk_attr[32], unk_form[32]; int i, j, ret; printf("\nContents of section .debug_abbrev:\n\n"); @@ -4810,8 +5138,9 @@ dump_dwarf_abbrev(struct readelf *re) goto next_abbrev; } if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { - warnx("dwarf_get_TAG_name failed"); - goto next_abbrev; + snprintf(unk_tag, sizeof(unk_tag), + "[Unknown Tag: %#x]", tag); + tag_str = unk_tag; } if (dwarf_get_abbrev_children_flag(ab, &flag, &de) != DW_DLV_OK) { @@ -4830,13 +5159,16 @@ dump_dwarf_abbrev(struct readelf *re) } if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { - warnx("dwarf_get_AT_name failed"); - continue; + snprintf(unk_attr, sizeof(unk_attr), + "[Unknown AT: %#x]", attr); + attr_str = unk_attr; } if (dwarf_get_FORM_name(form, &form_str) != DW_DLV_OK) { - warnx("dwarf_get_FORM_name failed"); - continue; + snprintf(unk_form, sizeof(unk_form), + "[Unknown Form: %#x]", + (Dwarf_Half) form); + form_str = unk_form; } printf(" %-18s %s\n", attr_str, form_str); } @@ -5132,6 +5464,7 @@ dump_dwarf_macinfo(struct readelf *re) Dwarf_Macro_Details *md; Dwarf_Error de; const char *mi_str; + char unk_mi[32]; int i; #define _MAX_MACINFO_ENTRY 65535 @@ -5147,9 +5480,9 @@ dump_dwarf_macinfo(struct readelf *re) break; if (dwarf_get_MACINFO_name(md[i].dmd_type, &mi_str) != DW_DLV_OK) { - warnx("dwarf_get_MACINFO_name failed: %s", - dwarf_errmsg(de)); - continue; + snprintf(unk_mi, sizeof(unk_mi), + "[Unknown MACINFO: %#x]", md[i].dmd_type); + mi_str = unk_mi; } printf(" %s", mi_str); switch (md[i].dmd_type) { @@ -5175,14 +5508,16 @@ dump_dwarf_macinfo(struct readelf *re) } static void -dump_dwarf_frame_inst(Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, - Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, Dwarf_Debug dbg) +dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, uint8_t *insts, + Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, + Dwarf_Debug dbg) { Dwarf_Frame_Op *oplist; Dwarf_Signed opcnt, delta; Dwarf_Small op; Dwarf_Error de; const char *op_str; + char unk_op[32]; int i; if (dwarf_expand_frame_instructions(cie, insts, len, &oplist, @@ -5198,9 +5533,9 @@ dump_dwarf_frame_inst(Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, else op = oplist[i].fp_extended_op; if (dwarf_get_CFA_name(op, &op_str) != DW_DLV_OK) { - warnx("dwarf_get_CFA_name failed: %s", - dwarf_errmsg(de)); - continue; + snprintf(unk_op, sizeof(unk_op), "[Unknown CFA: %#x]", + op); + op_str = unk_op; } printf(" %s", op_str); switch (op) { @@ -5214,11 +5549,13 @@ dump_dwarf_frame_inst(Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, case DW_CFA_offset_extended: case DW_CFA_offset_extended_sf: delta = oplist[i].fp_offset * daf; - printf(": r%u at cfa%+jd", oplist[i].fp_register, + printf(": r%u (%s) at cfa%+jd", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), (intmax_t) delta); break; case DW_CFA_restore: - printf(": r%u", oplist[i].fp_register); + printf(": r%u (%s)", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register)); break; case DW_CFA_set_loc: pc = oplist[i].fp_offset; @@ -5232,15 +5569,18 @@ dump_dwarf_frame_inst(Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, (uintmax_t) pc); break; case DW_CFA_def_cfa: - printf(": r%u ofs %ju", oplist[i].fp_register, + printf(": r%u (%s) ofs %ju", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), (uintmax_t) oplist[i].fp_offset); break; case DW_CFA_def_cfa_sf: - printf(": r%u ofs %jd", oplist[i].fp_register, + printf(": r%u (%s) ofs %jd", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register), (intmax_t) (oplist[i].fp_offset * daf)); break; case DW_CFA_def_cfa_register: - printf(": r%u", oplist[i].fp_register); + printf(": r%u (%s)", oplist[i].fp_register, + dwarf_regname(re, oplist[i].fp_register)); break; case DW_CFA_def_cfa_offset: printf(": %ju", (uintmax_t) oplist[i].fp_offset); @@ -5258,7 +5598,7 @@ dump_dwarf_frame_inst(Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, } static char * -get_regoff_str(Dwarf_Half reg, Dwarf_Addr off) +get_regoff_str(struct readelf *re, Dwarf_Half reg, Dwarf_Addr off) { static char rs[16]; @@ -5267,19 +5607,19 @@ get_regoff_str(Dwarf_Half reg, Dwarf_Addr off) else if (reg == DW_FRAME_CFA_COL) snprintf(rs, sizeof(rs), "c%+jd", (intmax_t) off); else - snprintf(rs, sizeof(rs), "r%u%+jd", reg, (intmax_t) off); + snprintf(rs, sizeof(rs), "%s%+jd", dwarf_regname(re, reg), + (intmax_t) off); return (rs); } static int -dump_dwarf_frame_regtable(Dwarf_Fde fde, Dwarf_Addr pc, Dwarf_Unsigned func_len, - Dwarf_Half cie_ra) +dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, Dwarf_Addr pc, + Dwarf_Unsigned func_len, Dwarf_Half cie_ra) { Dwarf_Regtable rt; Dwarf_Addr row_pc, end_pc, pre_pc, cur_pc; Dwarf_Error de; - char rn[16]; char *vec; int i; @@ -5316,10 +5656,9 @@ dump_dwarf_frame_regtable(Dwarf_Fde fde, Dwarf_Addr pc, Dwarf_Unsigned func_len, if (BIT_ISSET(vec, i)) { if ((Dwarf_Half) i == cie_ra) printf("ra "); - else { - snprintf(rn, sizeof(rn), "r%d", i); - printf("%-5s", rn); - } + else + printf("%-5s", + dwarf_regname(re, (unsigned int) i)); } } putchar('\n'); @@ -5338,12 +5677,12 @@ dump_dwarf_frame_regtable(Dwarf_Fde fde, Dwarf_Addr pc, Dwarf_Unsigned func_len, continue; pre_pc = row_pc; printf("%08jx ", (uintmax_t) row_pc); - printf("%-8s ", get_regoff_str(RT(0).dw_regnum, + printf("%-8s ", get_regoff_str(re, RT(0).dw_regnum, RT(0).dw_offset)); for (i = 1; i < DW_REG_TABLE_SIZE; i++) { if (BIT_ISSET(vec, i)) { - printf("%-5s", get_regoff_str(RT(i).dw_regnum, - RT(i).dw_offset)); + printf("%-5s", get_regoff_str(re, + RT(i).dw_regnum, RT(i).dw_offset)); } } putchar('\n'); @@ -5447,7 +5786,7 @@ dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) printf(" Return address column:\t%ju\n", (uintmax_t) cie_ra); putchar('\n'); - dump_dwarf_frame_inst(cie, cie_inst, + dump_dwarf_frame_inst(re, cie, cie_inst, cie_instlen, cie_caf, cie_daf, 0, re->dbg); putchar('\n'); @@ -5460,7 +5799,7 @@ dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) (uintmax_t) cie_caf, (uintmax_t) cie_daf, (uintmax_t) cie_ra); - dump_dwarf_frame_regtable(fde, low_pc, 1, + dump_dwarf_frame_regtable(re, fde, low_pc, 1, cie_ra); putchar('\n'); } @@ -5472,10 +5811,10 @@ dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) cie_offset), (uintmax_t) low_pc, (uintmax_t) (low_pc + func_len)); if (!alt) - dump_dwarf_frame_inst(cie, fde_inst, fde_instlen, + dump_dwarf_frame_inst(re, cie, fde_inst, fde_instlen, cie_caf, cie_daf, low_pc, re->dbg); else - dump_dwarf_frame_regtable(fde, low_pc, func_len, + dump_dwarf_frame_regtable(re, fde, low_pc, func_len, cie_ra); putchar('\n'); } @@ -5558,6 +5897,9 @@ struct loc_at { Dwarf_Attribute la_at; Dwarf_Unsigned la_off; Dwarf_Unsigned la_lowpc; + Dwarf_Half la_cu_psize; + Dwarf_Half la_cu_osize; + Dwarf_Half la_cu_ver; TAILQ_ENTRY(loc_at) la_next; }; @@ -5569,12 +5911,16 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) Dwarf_Attribute *attr_list; Dwarf_Die ret_die; Dwarf_Unsigned off; + Dwarf_Off ref; Dwarf_Signed attr_count; Dwarf_Half attr, form; + Dwarf_Bool is_info; Dwarf_Error de; struct loc_at *la, *nla; int i, ret; + is_info = dwarf_get_die_infotypes_flag(die); + if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != DW_DLV_OK) { if (ret == DW_DLV_ERROR) @@ -5600,12 +5946,24 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); continue; } - if (form != DW_FORM_data4 && form != DW_FORM_data8) - continue; - if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { - warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); + if (form == DW_FORM_data4 || form == DW_FORM_data8) { + if (dwarf_formudata(attr_list[i], &off, &de) != + DW_DLV_OK) { + warnx("dwarf_formudata failed: %s", + dwarf_errmsg(de)); + continue; + } + } else if (form == DW_FORM_sec_offset) { + if (dwarf_global_formref(attr_list[i], &ref, &de) != + DW_DLV_OK) { + warnx("dwarf_global_formref failed: %s", + dwarf_errmsg(de)); + continue; + } + off = ref; + } else continue; - } + TAILQ_FOREACH(la, &lalist, la_next) { if (off == la->la_off) break; @@ -5615,6 +5973,9 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) nla->la_at = attr_list[i]; nla->la_off = off; nla->la_lowpc = lowpc; + nla->la_cu_psize = re->cu_psize; + nla->la_cu_osize = re->cu_osize; + nla->la_cu_ver = re->cu_ver; TAILQ_INSERT_BEFORE(la, nla, la_next); break; } @@ -5625,6 +5986,9 @@ search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) nla->la_at = attr_list[i]; nla->la_off = off; nla->la_lowpc = lowpc; + nla->la_cu_psize = re->cu_psize; + nla->la_cu_osize = re->cu_osize; + nla->la_cu_ver = re->cu_ver; TAILQ_INSERT_TAIL(&lalist, nla, la_next); } } @@ -5638,7 +6002,7 @@ cont_search: search_loclist_at(re, ret_die, lowpc); /* Search sibling. */ - ret = dwarf_siblingof(re->dbg, die, &ret_die, &de); + ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) @@ -5646,23 +6010,294 @@ cont_search: } static void +dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr) +{ + const char *op_str; + char unk_op[32]; + uint8_t *b, n; + int i; + + if (dwarf_get_OP_name(lr->lr_atom, &op_str) != + DW_DLV_OK) { + snprintf(unk_op, sizeof(unk_op), + "[Unknown OP: %#x]", lr->lr_atom); + op_str = unk_op; + } + + printf("%s", op_str); + + switch (lr->lr_atom) { + 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: + printf(" (%s)", dwarf_regname(re, lr->lr_atom - DW_OP_reg0)); + break; + + case DW_OP_deref: + 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_push_object_address: + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + case DW_OP_stack_value: + case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: + break; + + case DW_OP_const1u: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + case DW_OP_const2u: + case DW_OP_bra: + case DW_OP_skip: + case DW_OP_const4u: + case DW_OP_const8u: + case DW_OP_constu: + case DW_OP_plus_uconst: + case DW_OP_regx: + case DW_OP_piece: + printf(": %ju", (uintmax_t) + lr->lr_number); + break; + + case DW_OP_const1s: + case DW_OP_const2s: + case DW_OP_const4s: + case DW_OP_const8s: + case DW_OP_consts: + printf(": %jd", (intmax_t) + lr->lr_number); + break; + + 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: + printf(" (%s): %jd", + dwarf_regname(re, lr->lr_atom - DW_OP_breg0), + (intmax_t) lr->lr_number); + break; + + case DW_OP_fbreg: + printf(": %jd", (intmax_t) + lr->lr_number); + break; + + case DW_OP_bregx: + printf(": %ju (%s) %jd", + (uintmax_t) lr->lr_number, + dwarf_regname(re, (unsigned int) lr->lr_number), + (intmax_t) lr->lr_number2); + break; + + case DW_OP_addr: + case DW_OP_GNU_encoded_addr: + printf(": %#jx", (uintmax_t) + lr->lr_number); + break; + + case DW_OP_GNU_implicit_pointer: + printf(": <0x%jx> %jd", (uintmax_t) lr->lr_number, + (intmax_t) lr->lr_number2); + break; + + case DW_OP_implicit_value: + printf(": %ju byte block:", (uintmax_t) lr->lr_number); + b = (uint8_t *)(uintptr_t) lr->lr_number2; + for (i = 0; (Dwarf_Unsigned) i < lr->lr_number; i++) + printf(" %x", b[i]); + break; + + case DW_OP_GNU_entry_value: + printf(": ("); + dump_dwarf_block(re, (uint8_t *)(uintptr_t) lr->lr_number2, + lr->lr_number); + putchar(')'); + break; + + case DW_OP_GNU_const_type: + printf(": <0x%jx> ", (uintmax_t) lr->lr_number); + b = (uint8_t *)(uintptr_t) lr->lr_number2; + n = *b; + for (i = 1; (uint8_t) i < n; i++) + printf(" %x", b[i]); + break; + + case DW_OP_GNU_regval_type: + printf(": %ju (%s) <0x%jx>", (uintmax_t) lr->lr_number, + dwarf_regname(re, (unsigned int) lr->lr_number), + (uintmax_t) lr->lr_number2); + break; + + case DW_OP_GNU_convert: + case DW_OP_GNU_deref_type: + case DW_OP_GNU_parameter_ref: + case DW_OP_GNU_reinterpret: + printf(": <0x%jx>", (uintmax_t) lr->lr_number); + break; + + default: + break; + } +} + +static void +dump_dwarf_block(struct readelf *re, uint8_t *b, Dwarf_Unsigned len) +{ + Dwarf_Locdesc *llbuf; + Dwarf_Signed lcnt; + Dwarf_Error de; + int i; + + if (dwarf_loclist_from_expr_b(re->dbg, b, len, re->cu_psize, + re->cu_osize, re->cu_ver, &llbuf, &lcnt, &de) != DW_DLV_OK) { + warnx("dwarf_loclist_form_expr_b: %s", dwarf_errmsg(de)); + return; + } + + for (i = 0; (Dwarf_Half) i < llbuf->ld_cents; i++) { + dump_dwarf_loc(re, &llbuf->ld_s[i]); + if (i < llbuf->ld_cents - 1) + printf("; "); + } + + dwarf_dealloc(re->dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); + dwarf_dealloc(re->dbg, llbuf, DW_DLA_LOCDESC); +} + +static void dump_dwarf_loclist(struct readelf *re) { Dwarf_Die die; Dwarf_Locdesc **llbuf; Dwarf_Unsigned lowpc; Dwarf_Signed lcnt; - Dwarf_Half tag; + Dwarf_Half tag, version, pointer_size, off_size; Dwarf_Error de; - Dwarf_Loc *lr; struct loc_at *la; - const char *op_str; int i, j, ret; printf("\nContents of section .debug_loc:\n"); - while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, - NULL, &de)) == DW_DLV_OK) { + /* Search .debug_info section. */ + while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL, + &pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); die = NULL; if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) continue; @@ -5673,8 +6308,8 @@ dump_dwarf_loclist(struct readelf *re) /* XXX: What about DW_TAG_partial_unit? */ lowpc = 0; if (tag == DW_TAG_compile_unit) { - if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, - &de) != DW_DLV_OK) + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, + &lowpc, &de) != DW_DLV_OK) lowpc = 0; } @@ -5684,6 +6319,39 @@ dump_dwarf_loclist(struct readelf *re) if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + /* Search .debug_types section. */ + do { + while ((ret = dwarf_next_cu_header_c(re->dbg, 0, NULL, + &version, NULL, &pointer_size, &off_size, NULL, NULL, + NULL, NULL, &de)) == DW_DLV_OK) { + set_cu_context(re, pointer_size, off_size, version); + die = NULL; + if (dwarf_siblingof(re->dbg, die, &die, &de) != + DW_DLV_OK) + continue; + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + warnx("dwarf_tag failed: %s", + dwarf_errmsg(de)); + continue; + } + + lowpc = 0; + if (tag == DW_TAG_type_unit) { + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, + &lowpc, &de) != DW_DLV_OK) + lowpc = 0; + } + + /* + * Search attributes for reference to .debug_loc + * section. + */ + search_loclist_at(re, die, lowpc); + } + if (ret == DW_DLV_ERROR) + warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); + } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); + if (TAILQ_EMPTY(&lalist)) return; @@ -5695,6 +6363,8 @@ dump_dwarf_loclist(struct readelf *re) warnx("dwarf_loclist_n failed: %s", dwarf_errmsg(de)); continue; } + set_cu_context(re, la->la_cu_psize, la->la_cu_osize, + la->la_cu_ver); for (i = 0; i < lcnt; i++) { printf(" %8.8jx ", la->la_off); if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) { @@ -5710,184 +6380,9 @@ dump_dwarf_loclist(struct readelf *re) putchar('('); for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { - lr = &llbuf[i]->ld_s[j]; - if (dwarf_get_OP_name(lr->lr_atom, &op_str) != - DW_DLV_OK) { - warnx("dwarf_get_OP_name failed: %s", - dwarf_errmsg(de)); - continue; - } - - printf("%s", op_str); - - switch (lr->lr_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: - break; - - case DW_OP_const1u: - case DW_OP_const1s: - case DW_OP_pick: - case DW_OP_deref_size: - case DW_OP_xderef_size: - case DW_OP_const2u: - case DW_OP_const2s: - case DW_OP_bra: - case DW_OP_skip: - case DW_OP_const4u: - case DW_OP_const4s: - case DW_OP_const8u: - case DW_OP_const8s: - case DW_OP_constu: - case DW_OP_plus_uconst: - case DW_OP_regx: - case DW_OP_piece: - printf(": %ju", (uintmax_t) - lr->lr_number); - break; - - 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: - printf(": %jd", (intmax_t) - lr->lr_number); - break; - - case DW_OP_bregx: - printf(": %ju %jd", - (uintmax_t) lr->lr_number, - (intmax_t) lr->lr_number2); - break; - - case DW_OP_addr: - printf(": %#jx", (uintmax_t) - lr->lr_number); - break; - } + dump_dwarf_loc(re, &llbuf[i]->ld_s[j]); if (j < llbuf[i]->ld_cents - 1) - printf(", "); + printf("; "); } putchar(')'); @@ -5895,6 +6390,12 @@ dump_dwarf_loclist(struct readelf *re) printf(" (start == end)"); putchar('\n'); } + for (i = 0; i < lcnt; i++) { + dwarf_dealloc(re->dbg, llbuf[i]->ld_s, + DW_DLA_LOC_BLOCK); + dwarf_dealloc(re->dbg, llbuf[i], DW_DLA_LOCDESC); + } + dwarf_dealloc(re->dbg, llbuf, DW_DLA_LIST); } } @@ -6247,8 +6748,10 @@ dump_dwarf(struct readelf *re) dump_dwarf_line(re); if (re->dop & DW_LL) dump_dwarf_line_decoded(re); - if (re->dop & DW_I) - dump_dwarf_info(re); + if (re->dop & DW_I) { + dump_dwarf_info(re, 0); + dump_dwarf_info(re, 1); + } if (re->dop & DW_P) dump_dwarf_pubnames(re); if (re->dop & DW_R) @@ -6435,7 +6938,7 @@ static struct { {"Ranges", 'R', DW_RR}, {"macro", 'm', DW_M}, {"frames", 'f', DW_F}, - {"", 'F', DW_FF}, + {"frames-interp", 'F', DW_FF}, {"str", 's', DW_S}, {"loc", 'o', DW_O}, {NULL, 0, 0} diff --git a/strings/strings.c b/strings/strings.c index c936d5c5374f..5964f64f19d5 100644 --- a/strings/strings.c +++ b/strings/strings.c @@ -46,7 +46,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: strings.c 2351 2011-12-19 11:20:37Z jkoshy $"); +ELFTC_VCSID("$Id: strings.c 3124 2014-12-21 05:46:28Z kaiwang27 $"); enum return_code { RETURN_OK, @@ -75,9 +75,9 @@ enum encoding_style { (encoding == ENCODING_8BIT && (c) > 127))) -int encoding_size, entire_file, min_len, show_filename, show_loc; -enum encoding_style encoding; -enum radix_style radix; +static int encoding_size, entire_file, min_len, show_filename, show_loc; +static enum encoding_style encoding; +static enum radix_style radix; static struct option strings_longopts[] = { { "all", no_argument, NULL, 'a'}, diff --git a/test/ar/Makefile b/test/ar/Makefile index a62db09d9320..d767a3934430 100644 --- a/test/ar/Makefile +++ b/test/ar/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2141 2011-11-10 15:03:40Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ TOP= ../.. AR= ${TOP}/ar/ar @@ -17,4 +17,4 @@ clobber: clean SUBDIR= plugin -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/ar/plugin/Makefile b/test/ar/plugin/Makefile index 58e00fd1b2de..36e33a35687c 100644 --- a/test/ar/plugin/Makefile +++ b/test/ar/plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2080 2011-10-27 04:23:24Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ PLUGINS= ardiff teraser @@ -9,7 +9,7 @@ ${PLUGINS}: ${MAKE} -f Makefile.${plugin} .endfor -clean depend: +clean cleandepend depend: .for plugin in ${PLUGINS} ${MAKE} -f Makefile.${plugin} ${.TARGET} .endfor diff --git a/test/ar/plugin/Makefile.ardiff b/test/ar/plugin/Makefile.ardiff index 1558cfe6065c..ec702c2ae585 100644 --- a/test/ar/plugin/Makefile.ardiff +++ b/test/ar/plugin/Makefile.ardiff @@ -1,9 +1,7 @@ -# $Id: Makefile.ardiff 2096 2011-11-01 04:42:04Z jkoshy $ +# $Id: Makefile.ardiff 3120 2014-12-21 05:45:51Z kaiwang27 $ TOP= ../../.. -.include "${TOP}/mk/elftoolchain.os.mk" - PROG= ardiff NOMAN= noman diff --git a/test/ar/plugin/ardiff.c b/test/ar/plugin/ardiff.c index e54f6a9f6cdc..907d1ea80da9 100644 --- a/test/ar/plugin/ardiff.c +++ b/test/ar/plugin/ardiff.c @@ -12,7 +12,7 @@ * By default, it compares nothing and consider the test "not ok" * iff it encounters errors while reading archive. * - * $Id: ardiff.c 2142 2011-11-10 15:29:59Z jkoshy $ + * $Id: ardiff.c 3102 2014-10-29 21:09:01Z jkoshy $ */ #include <archive.h> @@ -93,9 +93,8 @@ main(int argc, char **argv) /* Open file 1 */ a1 = archive_read_new(); - archive_read_support_compression_none(a1); archive_read_support_format_ar(a1); - if (archive_read_open_file(a1, argv[0], + if (archive_read_open_filename(a1, argv[0], 1024*10)) { warnx("%s", archive_error_string(a1)); filediff(tc, "archive open failed", NULL); @@ -103,9 +102,8 @@ main(int argc, char **argv) /* Open file 2 */ a2 = archive_read_new(); - archive_read_support_compression_none(a2); archive_read_support_format_ar(a2); - if (archive_read_open_file(a2, argv[1], + if (archive_read_open_filename(a2, argv[1], 1024*10)) { warnx("%s", archive_error_string(a2)); filediff(tc, "archive open failed", NULL); @@ -233,10 +231,11 @@ static void incct(const char *pathname) { FILE *fp; - char buf[10], *_buf; + char buf[10]; if ((fp = fopen(pathname, "r")) != NULL) { - _buf = fgets(buf, 10, fp); + if (fgets(buf, 10, fp) != buf) + perror("fgets"); snprintf(buf, 10, "%d\n", atoi(buf) + 1); fclose(fp); } diff --git a/test/ar/plugin/teraser.c b/test/ar/plugin/teraser.c index 59d587f7f048..d16752e7cefb 100644 --- a/test/ar/plugin/teraser.c +++ b/test/ar/plugin/teraser.c @@ -2,7 +2,7 @@ * make it easy to `diff'. (option -e) * 2. Check the sanity of timestamp. (option -c) * - * $Id: teraser.c 2142 2011-11-10 15:29:59Z jkoshy $ + * $Id: teraser.c 3102 2014-10-29 21:09:01Z jkoshy $ */ #include <errno.h> @@ -28,7 +28,7 @@ main(int argc, char **argv) char opt; char checktime; char erasetime; - char buf[TSLEN + 1], *_buf; + char buf[TSLEN + 1]; char *tc; int fd; int ts; @@ -85,7 +85,8 @@ main(int argc, char **argv) if (ts <= now && ts >= now - TDELAY) { fprintf(stderr, "%s - timestamp ok\n", tc); if ((ps = fopen(PASSED, "r")) != NULL) { - _buf = fgets(buf, TSLEN, ps); + if (fgets(buf, TSLEN, ps) != buf) + perror("fgets"); snprintf(buf, TSLEN, "%d\n", atoi(buf) + 1); fclose(ps); @@ -98,7 +99,8 @@ main(int argc, char **argv) fprintf(stderr, "%s - timestamp not ok\n", tc); } if ((ct = fopen(COUNTER, "r")) != NULL) { - _buf = fgets(buf, TSLEN, ct); + if (fgets(buf, TSLEN, ct) != buf) + perror("fgets"); snprintf(buf, TSLEN, "%d\n", atoi(buf) + 1); fclose(ct); } diff --git a/test/elfcopy/Makefile b/test/elfcopy/Makefile index f1302f133979..5114a68e7b2f 100644 --- a/test/elfcopy/Makefile +++ b/test/elfcopy/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2141 2011-11-10 15:03:40Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ TOP= ../.. @@ -18,4 +18,4 @@ clobber: clean SUBDIR= plugin -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/elfcopy/plugin/Makefile b/test/elfcopy/plugin/Makefile index a72fbfe7d371..36e33a35687c 100644 --- a/test/elfcopy/plugin/Makefile +++ b/test/elfcopy/plugin/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 2082 2011-10-27 04:38:32Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ PLUGINS= ardiff teraser @@ -9,7 +9,7 @@ ${PLUGINS}: ${MAKE} -f Makefile.${plugin} .endfor -clean depend: +clean cleandepend depend: .for plugin in ${PLUGINS} ${MAKE} -f Makefile.${plugin} ${.TARGET} .endfor diff --git a/test/elfcopy/plugin/Makefile.ardiff b/test/elfcopy/plugin/Makefile.ardiff index 7f371a7a975c..a7baa0a0292b 100644 --- a/test/elfcopy/plugin/Makefile.ardiff +++ b/test/elfcopy/plugin/Makefile.ardiff @@ -1,9 +1,7 @@ -# $Id: Makefile.ardiff 2096 2011-11-01 04:42:04Z jkoshy $ +# $Id: Makefile.ardiff 3121 2014-12-21 05:46:01Z kaiwang27 $ TOP= ../../.. -.include "${TOP}/mk/elftoolchain.os.mk" - PROG= ardiff NOMAN= diff --git a/test/elfcopy/plugin/ardiff.c b/test/elfcopy/plugin/ardiff.c index e54f6a9f6cdc..907d1ea80da9 100644 --- a/test/elfcopy/plugin/ardiff.c +++ b/test/elfcopy/plugin/ardiff.c @@ -12,7 +12,7 @@ * By default, it compares nothing and consider the test "not ok" * iff it encounters errors while reading archive. * - * $Id: ardiff.c 2142 2011-11-10 15:29:59Z jkoshy $ + * $Id: ardiff.c 3102 2014-10-29 21:09:01Z jkoshy $ */ #include <archive.h> @@ -93,9 +93,8 @@ main(int argc, char **argv) /* Open file 1 */ a1 = archive_read_new(); - archive_read_support_compression_none(a1); archive_read_support_format_ar(a1); - if (archive_read_open_file(a1, argv[0], + if (archive_read_open_filename(a1, argv[0], 1024*10)) { warnx("%s", archive_error_string(a1)); filediff(tc, "archive open failed", NULL); @@ -103,9 +102,8 @@ main(int argc, char **argv) /* Open file 2 */ a2 = archive_read_new(); - archive_read_support_compression_none(a2); archive_read_support_format_ar(a2); - if (archive_read_open_file(a2, argv[1], + if (archive_read_open_filename(a2, argv[1], 1024*10)) { warnx("%s", archive_error_string(a2)); filediff(tc, "archive open failed", NULL); @@ -233,10 +231,11 @@ static void incct(const char *pathname) { FILE *fp; - char buf[10], *_buf; + char buf[10]; if ((fp = fopen(pathname, "r")) != NULL) { - _buf = fgets(buf, 10, fp); + if (fgets(buf, 10, fp) != buf) + perror("fgets"); snprintf(buf, 10, "%d\n", atoi(buf) + 1); fclose(fp); } diff --git a/test/elfcopy/plugin/teraser.c b/test/elfcopy/plugin/teraser.c index 59d587f7f048..0deb7cc90630 100644 --- a/test/elfcopy/plugin/teraser.c +++ b/test/elfcopy/plugin/teraser.c @@ -2,7 +2,7 @@ * make it easy to `diff'. (option -e) * 2. Check the sanity of timestamp. (option -c) * - * $Id: teraser.c 2142 2011-11-10 15:29:59Z jkoshy $ + * $Id: teraser.c 3102 2014-10-29 21:09:01Z jkoshy $ */ #include <errno.h> @@ -28,7 +28,7 @@ main(int argc, char **argv) char opt; char checktime; char erasetime; - char buf[TSLEN + 1], *_buf; + char buf[TSLEN + 1]; char *tc; int fd; int ts; @@ -85,7 +85,8 @@ main(int argc, char **argv) if (ts <= now && ts >= now - TDELAY) { fprintf(stderr, "%s - timestamp ok\n", tc); if ((ps = fopen(PASSED, "r")) != NULL) { - _buf = fgets(buf, TSLEN, ps); + if (fgets(buf, TSLEN, ps) != buf) + perror("fgets"); snprintf(buf, TSLEN, "%d\n", atoi(buf) + 1); fclose(ps); @@ -98,7 +99,8 @@ main(int argc, char **argv) fprintf(stderr, "%s - timestamp not ok\n", tc); } if ((ct = fopen(COUNTER, "r")) != NULL) { - _buf = fgets(buf, TSLEN, ct); + if (fgets(buf, TSLEN, ct) != NULL) + perror("fgets"); snprintf(buf, TSLEN, "%d\n", atoi(buf) + 1); fclose(ct); } diff --git a/test/elfcopy/tc/strip-empty-1/in/strip-empty-1.in.shar b/test/elfcopy/tc/strip-empty-1/in/strip-empty-1.in.shar new file mode 100644 index 000000000000..6ff3cf214cc2 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/in/strip-empty-1.in.shar @@ -0,0 +1,32 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# empty.o.uu +# +echo x - empty.o.uu +sed 's/^X//' >empty.o.uu << '446fa33c5b702a1d1fbfe3ec7a501a1a' +Xbegin 644 empty.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````'`````` +XM`````````$```````$``!P`$```N<WEM=&%B`"YS=')T86(`+G-H<W1R=&%B +XM`"YT97AT`"YD871A`"YB<W,````````````````````````````````````` +XM```````````````````````````````````````````````````````;```` +XM`0````8```````````````````!````````````````````````````````$ +XM````````````````````(0````$````#````````````````````0``````` +XM````````````````````````!````````````````````"<````(`````P`` +XM`````````````````$````````````````````````````````0````````` +XM```````````1`````P````````````````````````!``````````"P````` +XM```````````````!`````````````````````0````(````````````````` +XM````````,`(```````!@``````````8````$````"``````````8```````` +XM``D````#`````````````````````````)`"`````````0`````````````` +XM``````$````````````````````````````````````````````````````` +XM`````P`!`````````````````````````````P`"```````````````````` +X;`````````P`#```````````````````````` +X` +Xend +446fa33c5b702a1d1fbfe3ec7a501a1a +exit + diff --git a/test/elfcopy/tc/strip-empty-1/out/strip-empty-1.out.shar b/test/elfcopy/tc/strip-empty-1/out/strip-empty-1.out.shar new file mode 100644 index 000000000000..fc7063cd0e26 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/out/strip-empty-1.out.shar @@ -0,0 +1,22 @@ +# This is a shell archive. Save it in a file, remove anything before +# this line, and then unpack it by entering "sh file". Note, it may +# create directories; files and directories will be owned by you and +# have default permissions. +# +# This archive contains: +# +# empty.o.uu +# +echo x - empty.o.uu +sed 's/^X//' >empty.o.uu << '446fa33c5b702a1d1fbfe3ec7a501a1a' +Xbegin 644 empty.o +XM?T5,1@(!`0D```````````$`/@`!`````````````````````````%`````` +XM`````````$```````$```@`!```N<VAS=')T86(````````````````````` +XM```````````````````````````````````````````````````````````` +XM`````````````0````,`````````````````````````0``````````+```` +X<`````````````````0`````````````````````` +X` +Xend +446fa33c5b702a1d1fbfe3ec7a501a1a +exit + diff --git a/test/elfcopy/tc/strip-empty-1/strip-empty-1.err b/test/elfcopy/tc/strip-empty-1/strip-empty-1.err new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/strip-empty-1.err diff --git a/test/elfcopy/tc/strip-empty-1/strip-empty-1.eval b/test/elfcopy/tc/strip-empty-1/strip-empty-1.eval new file mode 100644 index 000000000000..573541ac9702 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/strip-empty-1.eval @@ -0,0 +1 @@ +0 diff --git a/test/elfcopy/tc/strip-empty-1/strip-empty-1.out b/test/elfcopy/tc/strip-empty-1/strip-empty-1.out new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/strip-empty-1.out diff --git a/test/elfcopy/tc/strip-empty-1/strip-empty-1.sh b/test/elfcopy/tc/strip-empty-1/strip-empty-1.sh new file mode 100755 index 000000000000..2ba44f887d97 --- /dev/null +++ b/test/elfcopy/tc/strip-empty-1/strip-empty-1.sh @@ -0,0 +1,6 @@ +# $Id$ +inittest strip-empty-1 tc/strip-empty-1 +extshar ${TESTDIR} +extshar ${RLTDIR} +runcmd "${STRIP} -R .text -R .data -R .bss -R .ARM.attributes -R .reginfo -R .gnu.attributes -R .MIPS.abiflags -R .pdr -R .xtensa.info empty.o" work true +rundiff true diff --git a/test/elfdump/Makefile b/test/elfdump/Makefile index fa9f176bd0f6..ceac4650543c 100644 --- a/test/elfdump/Makefile +++ b/test/elfdump/Makefile @@ -1,21 +1,5 @@ -# $Id: Makefile 2137 2011-11-10 13:09:30Z jkoshy $ +# $Id: Makefile 3028 2014-04-18 16:20:43Z jkoshy $ TOP= ../.. -.include "${TOP}/mk/elftoolchain.tetvars.mk" - -.if !defined(TET_EXECUTE) -TET_EXECUTE= ${.OBJDIR} -.endif - -.PHONY: all clean clobber execute test - -all clean depend: - -execute test: - TET_EXECUTE="${TET_EXECUTE}" TET_ROOT="${TET_ROOT}" \ - TET_SUITE_ROOT="${.CURDIR}" \ - ${TET_ROOT}/bin/tcc -e . - -clobber: clean - rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/test/libdwarf/Makefile b/test/libdwarf/Makefile index ad239300bcf2..fc9f5d1667e6 100644 --- a/test/libdwarf/Makefile +++ b/test/libdwarf/Makefile @@ -1,34 +1,6 @@ -# -# $Id: Makefile 2137 2011-11-10 13:09:30Z jkoshy $ -# - -TOP= ../.. - -.include "${TOP}/mk/elftoolchain.tetvars.mk" - -.if make(tccbuild) -TET_OPTIONS+= -b -.endif - -.if make(tccclean) -TET_OPTIONS+= -c -.endif - -.if make(execute) || make(test) -TET_OPTIONS+= -e -.endif - -.MAIN: all - -.PHONY: clobber execute tccbuild tccclean test - -execute tccbuild tccclean test: - TET_ROOT=${TET_ROOT} TET_SUITE_ROOT=${.CURDIR} \ - ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . - -clobber: clean - rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} +# $Id: Makefile 3028 2014-04-18 16:20:43Z jkoshy $ +TOP= ../.. SUBDIR= ts -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/test/libdwarf/ts/Makefile b/test/libdwarf/ts/Makefile index 84d6e2404b14..05ddf91e16d4 100644 --- a/test/libdwarf/ts/Makefile +++ b/test/libdwarf/ts/Makefile @@ -1,7 +1,9 @@ # -# $Id: Makefile 2084 2011-10-27 04:48:12Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ # +TOP= ../../.. + SUBDIR+= dwarf_init SUBDIR+= dwarf_next_cu_header SUBDIR+= dwarf_get_address_size @@ -22,4 +24,4 @@ SUBDIR+= dwarf_pubnames SUBDIR+= dwarf_macinfo SUBDIR+= dwarf_ranges -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/libdwarf/ts/Makefile.tset b/test/libdwarf/ts/Makefile.tset index af0f82a10dbc..6546de89d2cf 100644 --- a/test/libdwarf/ts/Makefile.tset +++ b/test/libdwarf/ts/Makefile.tset @@ -1,6 +1,4 @@ -# $Id: Makefile.tset 2198 2011-11-23 16:13:45Z jkoshy $ - -.include "${TOP}/mk/elftoolchain.os.mk" +# $Id: Makefile.tset 3122 2014-12-21 05:46:10Z kaiwang27 $ # libdwarf test suite uses libdwarf in /usr/local (i.e. SGI libdwarf), # if TCGEN is defined. @@ -15,6 +13,11 @@ LDADD+= -ldwarf DPADD+= ${LIBELF} LDADD+= -lelf +# Test cases do not have manual pages. +NOMAN= noman + +.include "${TOP}/mk/elftoolchain.os.mk" + # Determine the location of the XML handling library. .if ${OS_HOST} == FreeBSD LDADD+= -lbsdxml @@ -51,6 +54,3 @@ ${f}: ${TS_OBJROOT}/common/object/${f}.gz .if ${OS_HOST} != NetBSD WARNS?= 2 .endif - -# Test cases do not have manual pages. -NOMAN= noman diff --git a/test/libdwarf/ts/README b/test/libdwarf/ts/README index b163c50a7ccd..0a041dcbd604 100644 --- a/test/libdwarf/ts/README +++ b/test/libdwarf/ts/README @@ -1,4 +1,4 @@ -: $Id: README 2084 2011-10-27 04:48:12Z jkoshy $ +: $Id: README 3072 2014-06-23 03:08:44Z kaiwang27 $ Libdwarf test suite use XML files to describe test case, invocable component and test purpose. @@ -32,3 +32,15 @@ When a test case is compiled with 'make TCGEN=yes', it will instead link with SGI libdwarf and genearte XML files during TP execution. These generated XML files can then be used directly to test this libdwarf implementation. + +For example, to generate XML files for test case dwarf_next_cu_header: + +% cd /path/to/elftoolchain/test/libdwarf/ +# unsetenv TET_ROOT +% make clean && make TCGEN=yes +% cd ts/dwarf_next_cu_header +% setenv TET_ROOT /path/to/elftoolchain/test/tet +% env ICLIST=dt32-g1:dt64-g1:ec32-g1:ec64-g1:ld_symver.o-64-g1 ./tc_dwarf_next_cu_header + +(ICLIST defines a list of test objects on which the test case +generates. One gzipped XML file is generated for each test object.) diff --git a/test/libdwarf/ts/common/die_traverse2.c b/test/libdwarf/ts/common/die_traverse2.c new file mode 100644 index 000000000000..059ca13cb1c0 --- /dev/null +++ b/test/libdwarf/ts/common/die_traverse2.c @@ -0,0 +1,120 @@ +/*- + * Copyright (c) 2010,2014 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: die_traverse2.c 3076 2014-06-23 23:54:01Z kaiwang27 $ + */ + +#include <assert.h> +#include <dwarf.h> +#include <libdwarf.h> + +#include "driver.h" + +static int die_cnt; + +/* + * DIE traverse function shared by test cases. (another version with + * .debug_types support) + */ + +static void +_die_traverse_recursive2(Dwarf_Debug dbg, Dwarf_Die die, + Dwarf_Bool is_info, void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die0; + Dwarf_Off offset; + Dwarf_Half tag; + Dwarf_Error de; + const char *tagname; + int r; + + assert(dbg != NULL && die != NULL && die_callback != NULL); + + if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { + tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tagname = NULL; + if (dwarf_get_TAG_name(tag, &tagname) != DW_DLV_OK) { + tet_infoline("dwarf_get_TAG_name failed"); + result = TET_FAIL; + } + offset = 0; + if (dwarf_dieoffset(die, &offset, &de) != DW_DLV_OK) { + tet_printf("dwarf_dieoffset failed: %s\n", dwarf_errmsg(de)); + result = TET_FAIL; + } + tet_printf("DIE #%d (%s) [%#x]\n", die_cnt++, tagname, offset); + + die_callback(die); + + /* Search children. */ + r = dwarf_child(die, &die0, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_child failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive2(dbg, die0, is_info, die_callback); + + /* Search sibling. */ + r = dwarf_siblingof_b(dbg, die, &die0, is_info, &de); + if (r == DW_DLV_ERROR) + tet_printf("%s: dwarf_siblingof failed: %s", __func__, + dwarf_errmsg(de)); + else if (r == DW_DLV_OK) + _die_traverse_recursive2(dbg, die0, is_info, die_callback); +} + +static void +_die_traverse2(Dwarf_Debug dbg, Dwarf_Bool is_info, + void (*die_callback)(Dwarf_Die die)) +{ + Dwarf_Die die; + Dwarf_Error de; + Dwarf_Unsigned cu_next_offset; + + assert(dbg != NULL && die_callback != NULL); + + die_cnt = 0; + + if (is_info) { + TS_DWARF_CU_FOREACH2(dbg, 1, cu_next_offset, de) { + if (dwarf_siblingof_b(dbg, NULL, &die, 1, &de) != + DW_DLV_OK) + break; + _die_traverse_recursive2(dbg, die, 1, die_callback); + } + } else { + do { + TS_DWARF_CU_FOREACH2(dbg, 0, cu_next_offset, de) { + if (dwarf_siblingof_b(dbg, NULL, &die, 0, + &de) != DW_DLV_OK) + break; + _die_traverse_recursive2(dbg, die, 0, + die_callback); + } + } while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); + } +} diff --git a/test/libdwarf/ts/common/driver.h b/test/libdwarf/ts/common/driver.h index 7d84a017e386..580683ffd17e 100644 --- a/test/libdwarf/ts/common/driver.h +++ b/test/libdwarf/ts/common/driver.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: driver.h 2084 2011-10-27 04:48:12Z jkoshy $ + * $Id: driver.h 3074 2014-06-23 03:08:53Z kaiwang27 $ */ #ifndef _DRIVER_H_ @@ -62,9 +62,16 @@ struct dwarf_tp { while (dwarf_next_cu_header((D), NULL, NULL, NULL, NULL, &(N), \ &(DE)) == DW_DLV_OK) -#define TS_DWARF_DIE_TRAVERSE(D, CB) \ +#define TS_DWARF_CU_FOREACH2(D,I,N,DE) \ + while (dwarf_next_cu_header_c((D), (I), NULL, NULL, NULL, NULL, \ + NULL, NULL, NULL, NULL, &(N), &(DE)) == DW_DLV_OK) + +#define TS_DWARF_DIE_TRAVERSE(D,CB) \ _die_traverse((D), (CB)) +#define TS_DWARF_DIE_TRAVERSE2(D,I,CB) \ + _die_traverse2((D), (I), (CB)) + #ifndef TCGEN #define _TS_CHECK_VAR(X,S) do { \ diff --git a/test/libdwarf/ts/common/object/ld_symver.o-64-g1.gz b/test/libdwarf/ts/common/object/ld_symver.o-64-g1.gz Binary files differnew file mode 100644 index 000000000000..5fd90579c811 --- /dev/null +++ b/test/libdwarf/ts/common/object/ld_symver.o-64-g1.gz diff --git a/test/libdwarf/ts/dwarf_attrlist/Makefile b/test/libdwarf/ts/dwarf_attrlist/Makefile index 29cc2480527b..beaf7e4bb415 100644 --- a/test/libdwarf/ts/dwarf_attrlist/Makefile +++ b/test/libdwarf/ts/dwarf_attrlist/Makefile @@ -1,8 +1,8 @@ -# $Id: Makefile 2084 2011-10-27 04:48:12Z jkoshy $ +# $Id: Makefile 3083 2014-09-02 22:08:01Z kaiwang27 $ TOP= ../../../.. TS_SRCS= dwarf_attrlist.c -TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 .include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/test/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz b/test/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz Binary files differindex 9757123b7b2c..78629601d102 100644 --- a/test/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_attrlist/dt32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz b/test/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz Binary files differindex e4cf1c592c6d..8b69a054fa4d 100644 --- a/test/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_attrlist/dt64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c b/test/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c index fa6818ec1dcc..e8f29edc9366 100644 --- a/test/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c +++ b/test/libdwarf/ts/dwarf_attrlist/dwarf_attrlist.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dwarf_attrlist.c 2084 2011-10-27 04:48:12Z jkoshy $ + * $Id: dwarf_attrlist.c 3083 2014-09-02 22:08:01Z kaiwang27 $ */ #include <assert.h> @@ -48,7 +48,7 @@ static struct dwarf_tp dwarf_tp_array[] = { }; static int result = TET_UNRESOLVED; #include "driver.c" -#include "die_traverse.c" +#include "die_traverse2.c" static void _dwarf_attrlist(Dwarf_Die die) @@ -90,7 +90,8 @@ tp_dwarf_attrlist(void) TS_DWARF_INIT(dbg, fd, de); - TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_attrlist); + TS_DWARF_DIE_TRAVERSE2(dbg, 1, _dwarf_attrlist); + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_attrlist); if (result == TET_UNRESOLVED) result = TET_PASS; diff --git a/test/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz b/test/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz Binary files differindex 3408f55c6e59..f2a53356cc7c 100644 --- a/test/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_attrlist/ec32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz b/test/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz Binary files differindex 13581a27d24c..19faaf701f76 100644 --- a/test/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_attrlist/ec64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz b/test/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz Binary files differnew file mode 100644 index 000000000000..b78ab0abd9b2 --- /dev/null +++ b/test/libdwarf/ts/dwarf_attrlist/ld_symver.o-64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/Makefile b/test/libdwarf/ts/dwarf_die_query/Makefile index efcf1bc97c4e..0f99aa3e1bbf 100644 --- a/test/libdwarf/ts/dwarf_die_query/Makefile +++ b/test/libdwarf/ts/dwarf_die_query/Makefile @@ -1,8 +1,8 @@ -# $Id: Makefile 2084 2011-10-27 04:48:12Z jkoshy $ +# $Id: Makefile 3075 2014-06-23 03:08:57Z kaiwang27 $ TOP= ../../../.. TS_SRCS= dwarf_die_query.c -TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 dto64-g1 +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 dto64-g1 ld_symver.o-64-g1 .include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/test/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz Binary files differindex 2cda689a7945..1fc085142117 100644 --- a/test/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_die_query/dt32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz Binary files differindex 211645acbf43..6a1a6fd54759 100644 --- a/test/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_die_query/dt64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz Binary files differindex 7b2d38d04585..2cd4ea5a2ff7 100644 --- a/test/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_die_query/dto64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/dwarf_die_query.c b/test/libdwarf/ts/dwarf_die_query/dwarf_die_query.c index 45b9c44d1abe..5c99fc230497 100644 --- a/test/libdwarf/ts/dwarf_die_query/dwarf_die_query.c +++ b/test/libdwarf/ts/dwarf_die_query/dwarf_die_query.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dwarf_die_query.c 2084 2011-10-27 04:48:12Z jkoshy $ + * $Id: dwarf_die_query.c 3075 2014-06-23 03:08:57Z kaiwang27 $ */ #include <assert.h> @@ -42,15 +42,18 @@ */ static void tp_dwarf_die_query(void); +static void tp_dwarf_die_query_types(void); static void tp_dwarf_die_query_sanity(void); static struct dwarf_tp dwarf_tp_array[] = { {"tp_dwarf_die_query", tp_dwarf_die_query}, + {"tp_dwarf_die_query_types", tp_dwarf_die_query_types}, {"tp_dwarf_die_query_sanity", tp_dwarf_die_query_sanity}, {NULL, NULL}, }; static int result = TET_UNRESOLVED; #include "driver.c" #include "die_traverse.c" +#include "die_traverse2.c" static void _dwarf_die_query(Dwarf_Die die) @@ -103,6 +106,27 @@ done: } static void +tp_dwarf_die_query_types(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + int fd; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_die_query); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + +static void tp_dwarf_die_query_sanity(void) { Dwarf_Debug dbg; diff --git a/test/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz Binary files differindex d54847f126ea..0dde7100876f 100644 --- a/test/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_die_query/ec32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz Binary files differindex 21559130a679..3c9890e18d00 100644 --- a/test/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_die_query/ec64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz b/test/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz Binary files differnew file mode 100644 index 000000000000..c8de24e2c300 --- /dev/null +++ b/test/libdwarf/ts/dwarf_die_query/ld_symver.o-64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_form/Makefile b/test/libdwarf/ts/dwarf_form/Makefile index a64bd6f6f2ba..a1f193ada1b2 100644 --- a/test/libdwarf/ts/dwarf_form/Makefile +++ b/test/libdwarf/ts/dwarf_form/Makefile @@ -1,8 +1,8 @@ -# $Id: Makefile 2084 2011-10-27 04:48:12Z jkoshy $ +# $Id: Makefile 3084 2014-09-02 22:08:13Z kaiwang27 $ TOP= ../../../.. TS_SRCS= dwarf_form.c -TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 .include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/test/libdwarf/ts/dwarf_form/dt32-g1.xml.gz b/test/libdwarf/ts/dwarf_form/dt32-g1.xml.gz Binary files differindex b15226e85f10..afc398d021aa 100644 --- a/test/libdwarf/ts/dwarf_form/dt32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_form/dt32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_form/dt64-g1.xml.gz b/test/libdwarf/ts/dwarf_form/dt64-g1.xml.gz Binary files differindex 62b6aa268730..257b4687bd50 100644 --- a/test/libdwarf/ts/dwarf_form/dt64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_form/dt64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_form/dwarf_form.c b/test/libdwarf/ts/dwarf_form/dwarf_form.c index 8567b5a14491..5ef73d3f486b 100644 --- a/test/libdwarf/ts/dwarf_form/dwarf_form.c +++ b/test/libdwarf/ts/dwarf_form/dwarf_form.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dwarf_form.c 2084 2011-10-27 04:48:12Z jkoshy $ + * $Id: dwarf_form.c 3084 2014-09-02 22:08:13Z kaiwang27 $ */ #include <assert.h> @@ -48,7 +48,7 @@ static struct dwarf_tp dwarf_tp_array[] = { }; static int result = TET_UNRESOLVED; #include "driver.c" -#include "die_traverse.c" +#include "die_traverse2.c" static void _dwarf_form(Dwarf_Die die) @@ -62,11 +62,14 @@ _dwarf_form(Dwarf_Die die) Dwarf_Unsigned uvalue; Dwarf_Signed svalue; Dwarf_Block *block; + Dwarf_Sig8 sig8; + Dwarf_Ptr ptr; Dwarf_Error de; char *str; int i, r; int r_formref, r_global_formref, r_formaddr, r_formflag; int r_formudata, r_formsdata, r_formblock, r_formstring; + int r_formsig8, r_formexprloc; r = dwarf_attrlist(die, &attrlist, &attrcount, &de); if (r == DW_DLV_ERROR) { @@ -141,6 +144,16 @@ _dwarf_form(Dwarf_Die die) TS_CHECK_INT(r_formstring); if (r_formstring == DW_DLV_OK) TS_CHECK_STRING(str); + + r_formsig8 = dwarf_formsig8(at, &sig8, &de); + TS_CHECK_INT(r_formsig8); + if (r_formsig8 == DW_DLV_OK) + TS_CHECK_BLOCK(sig8.signature, 8); + + r_formexprloc = dwarf_formexprloc(at, &uvalue, &ptr, &de); + TS_CHECK_INT(r_formexprloc); + if (r_formexprloc == DW_DLV_OK) + TS_CHECK_BLOCK(ptr, uvalue); } } @@ -155,7 +168,8 @@ tp_dwarf_form(void) TS_DWARF_INIT(dbg, fd, de); - TS_DWARF_DIE_TRAVERSE(dbg, _dwarf_form); + TS_DWARF_DIE_TRAVERSE2(dbg, 1, _dwarf_form); + TS_DWARF_DIE_TRAVERSE2(dbg, 0, _dwarf_form); if (result == TET_UNRESOLVED) result = TET_PASS; diff --git a/test/libdwarf/ts/dwarf_form/ec32-g1.xml.gz b/test/libdwarf/ts/dwarf_form/ec32-g1.xml.gz Binary files differindex 8342c21cf7e1..bf8b65ed07b4 100644 --- a/test/libdwarf/ts/dwarf_form/ec32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_form/ec32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_form/ec64-g1.xml.gz b/test/libdwarf/ts/dwarf_form/ec64-g1.xml.gz Binary files differindex b046c5b90237..1c964962fc4e 100644 --- a/test/libdwarf/ts/dwarf_form/ec64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_form/ec64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz b/test/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz Binary files differnew file mode 100644 index 000000000000..22c60db86842 --- /dev/null +++ b/test/libdwarf/ts/dwarf_form/ld_symver.o-64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_next_cu_header/Makefile b/test/libdwarf/ts/dwarf_next_cu_header/Makefile index ef798c118a56..ad29f1efa8ee 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/Makefile +++ b/test/libdwarf/ts/dwarf_next_cu_header/Makefile @@ -1,8 +1,8 @@ -# $Id: Makefile 2084 2011-10-27 04:48:12Z jkoshy $ +# $Id: Makefile 3073 2014-06-23 03:08:49Z kaiwang27 $ TOP= ../../../.. TS_SRCS= dwarf_next_cu_header.c -TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 +TS_DATA= dt32-g1 dt64-g1 ec32-g1 ec64-g1 ld_symver.o-64-g1 .include "${TOP}/mk/elftoolchain.tet.mk" diff --git a/test/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz b/test/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz Binary files differindex e9f788ca68f3..7ba737cc6e97 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_next_cu_header/dt32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz b/test/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz Binary files differindex 60dfb4202084..93a44424c7d1 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_next_cu_header/dt64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c b/test/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c index acfe506bb869..b5a580d49753 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c +++ b/test/libdwarf/ts/dwarf_next_cu_header/dwarf_next_cu_header.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010 Kai Wang + * Copyright (c) 2010,2014 Kai Wang * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: dwarf_next_cu_header.c 2084 2011-10-27 04:48:12Z jkoshy $ + * $Id: dwarf_next_cu_header.c 3073 2014-06-23 03:08:49Z kaiwang27 $ */ #include <assert.h> @@ -38,10 +38,12 @@ static void tp_dwarf_next_cu_header(void); static void tp_dwarf_next_cu_header_b(void); +static void tp_dwarf_next_cu_header_c(void); static void tp_dwarf_next_cu_header_loop(void); static struct dwarf_tp dwarf_tp_array[] = { {"tp_dwarf_next_cu_header", tp_dwarf_next_cu_header}, {"tp_dwarf_next_cu_header_b", tp_dwarf_next_cu_header_b}, + {"tp_dwarf_next_cu_header_c", tp_dwarf_next_cu_header_c}, {"tp_dwarf_next_cu_header_loop", tp_dwarf_next_cu_header_loop}, {NULL, NULL}, }; @@ -100,8 +102,8 @@ tp_dwarf_next_cu_header_b(void) TS_DWARF_INIT(dbg, fd, de); while (dwarf_next_cu_header_b(dbg, &cu_header_length, &cu_version, - &cu_abbrev_offset, &cu_pointer_size, &cu_offset_size, - &cu_extension_size, &cu_next_offset, &de) == DW_DLV_OK) { + &cu_abbrev_offset, &cu_pointer_size, &cu_offset_size, + &cu_extension_size, &cu_next_offset, &de) == DW_DLV_OK) { TS_CHECK_UINT(cu_header_length); TS_CHECK_UINT(cu_version); TS_CHECK_INT(cu_abbrev_offset); @@ -119,6 +121,64 @@ done: TS_RESULT(result); } +static void +tp_dwarf_next_cu_header_c(void) +{ + Dwarf_Debug dbg; + Dwarf_Error de; + Dwarf_Unsigned cu_header_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_Sig8 cu_type_sig; + Dwarf_Unsigned cu_type_offset; + Dwarf_Unsigned cu_next_offset; + int fd, result; + + result = TET_UNRESOLVED; + + TS_DWARF_INIT(dbg, fd, de); + + while (dwarf_next_cu_header_c(dbg, 1, &cu_header_length, &cu_version, + &cu_abbrev_offset, &cu_pointer_size, &cu_offset_size, + &cu_extension_size, NULL, NULL, &cu_next_offset, &de) == + DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_offset_size); + TS_CHECK_UINT(cu_extension_size); + TS_CHECK_UINT(cu_next_offset); + } + + do { + while (dwarf_next_cu_header_c(dbg, 0, &cu_header_length, + &cu_version, &cu_abbrev_offset, &cu_pointer_size, + &cu_offset_size, &cu_extension_size, &cu_type_sig, + &cu_type_offset, &cu_next_offset, &de) == DW_DLV_OK) { + TS_CHECK_UINT(cu_header_length); + TS_CHECK_UINT(cu_version); + TS_CHECK_INT(cu_abbrev_offset); + TS_CHECK_UINT(cu_pointer_size); + TS_CHECK_UINT(cu_offset_size); + TS_CHECK_UINT(cu_extension_size); + TS_CHECK_BLOCK(cu_type_sig.signature, 8); + TS_CHECK_UINT(cu_type_offset); + TS_CHECK_UINT(cu_next_offset); + } + } while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); + + if (result == TET_UNRESOLVED) + result = TET_PASS; + +done: + TS_DWARF_FINISH(dbg, de); + TS_RESULT(result); +} + #define _LOOP_COUNT 50 static void diff --git a/test/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz b/test/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz Binary files differindex 6efbf28a509d..c613d8ec741e 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_next_cu_header/ec32-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz b/test/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz Binary files differindex e03947ddbac5..180062815342 100644 --- a/test/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz +++ b/test/libdwarf/ts/dwarf_next_cu_header/ec64-g1.xml.gz diff --git a/test/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz b/test/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz Binary files differnew file mode 100644 index 000000000000..adf56ab1f756 --- /dev/null +++ b/test/libdwarf/ts/dwarf_next_cu_header/ld_symver.o-64-g1.xml.gz diff --git a/test/libelf/Makefile b/test/libelf/Makefile index 903221d9bafa..f7a3903e2b9e 100644 --- a/test/libelf/Makefile +++ b/test/libelf/Makefile @@ -1,36 +1,6 @@ -# $Id: Makefile 2137 2011-11-10 13:09:30Z jkoshy $ - -TOP = ../.. - -.include "${TOP}/mk/elftoolchain.tetvars.mk" - -.if !defined(TET_EXECUTE) -TET_EXECUTE= ${.OBJDIR} -.endif - -.if make(tccbuild) -TET_OPTIONS+= -b -.endif - -.if make(tccclean) -TET_OPTIONS+= -c -.endif - -.if make(execute) || make(test) -TET_OPTIONS+= -e -.endif - -.MAIN: all - -.PHONY: clobber execute tccbuild tccclean test - -execute tccbuild tccclean test: - TET_ROOT=${TET_ROOT} TET_EXECUTE=${TET_EXECUTE} \ - TET_SUITE_ROOT=${.CURDIR} ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . - -clobber: clean - rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} +# $Id: Makefile 3028 2014-04-18 16:20:43Z jkoshy $ +TOP= ../.. SUBDIR= tset -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/test/libelf/tset/Makefile b/test/libelf/tset/Makefile index 707a3ab82137..63e958691306 100644 --- a/test/libelf/tset/Makefile +++ b/test/libelf/tset/Makefile @@ -1,7 +1,9 @@ # -# $Id: Makefile 1638 2011-07-10 15:43:19Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ # +TOP= ../../.. + SUBDIR+= common # must be first SUBDIR+= abi @@ -55,4 +57,4 @@ SUBDIR+= gelf_getehdr SUBDIR+= gelf_newehdr SUBDIR+= gelf_xlate -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/libelf/tset/elf_update/update.m4 b/test/libelf/tset/elf_update/update.m4 index e1d3e6b33f53..5d7e789a8e9c 100644 --- a/test/libelf/tset/elf_update/update.m4 +++ b/test/libelf/tset/elf_update/update.m4 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: update.m4 2833 2012-12-30 16:16:51Z jkoshy $ + * $Id: update.m4 3081 2014-07-28 08:53:14Z jkoshy $ */ #include <sys/types.h> @@ -743,7 +743,7 @@ tcSectionType$2$1(void) goto done; } - sh->sh_type = SHT_NULL - 1; + sh->sh_type = SHT_LOOS - 1; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); if ((offset = elf_update(e, ELF_C_NULL)) != (off_t) -1) { @@ -774,6 +774,88 @@ FN(64,`lsb') FN(64,`msb') /* + * Verify that sections with unrecognized sh_type values in the + * range [SHT_LOUSER,SHT_HIUSER], [SHT_LOPROC,SHT_HIPROC], + * and [SHT_LOOS,SHT_HIOS] are accepted. + */ + +define(`ADD_SECTION',` + if ((scn = elf_newscn(e)) == NULL) { + TP_UNRESOLVED("elf_newscn() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + if ((sh = elf$1_getshdr(scn)) == NULL) { + TP_UNRESOLVED("elf$1_getshdr() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + sh->sh_type = $2; + if ((d = elf_newdata(scn)) == NULL) { + TP_UNRESOLVED("elf_newdata() failed: \"%s\".", + elf_errmsg(-1)); + goto done; + } + d->d_align = 1; + d->d_buf = NULL; + d->d_size = 0; + d->d_off = (off_t) 0; + (void) elf_flagdata(d, ELF_C_SET, ELF_F_DIRTY); + (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY);') +undefine(`FN') +define(`FN',` +void +tcSectionTypeOSUserProcDefined_$2$1(void) +{ + int error, fd, result; + off_t offset; + Elf *e; + Elf_Data *d; + Elf_Scn *scn; + Elf$1_Shdr *sh; + + TP_CHECK_INITIALIZATION(); + + TP_ANNOUNCE("TOUPPER($2)$1: user, OS and processor specific " + "section types are accepted.") ; + + result = TET_UNRESOLVED; + e = NULL; + fd = -1; + + _TS_OPEN_FILE(e, "newehdr.$2$1", ELF_C_READ, fd, goto done;); + + /* + * Create two new sections, one of type SHT_LOOS (0x60000000UL), + * and the other of type SHT_HIUSER (0xFFFFFFFFUL). These + * should be accepted as valid sections. + */ + ADD_SECTION($1,`SHT_LOOS') + ADD_SECTION($1,`SHT_HIUSER') + + if ((offset = elf_update(e, ELF_C_NULL)) == (off_t) -1) { + TP_FAIL("elf_update() failed."); + goto done; + } + + result = TET_PASS; + + done: + if (e) + (void) elf_end(e); + if (fd) + (void) close(fd); + tet_result(result); +}') + +FN(32,`lsb') +FN(32,`msb') +FN(64,`lsb') +FN(64,`msb') + +undefine(`ADD_SECTION') + +/* * An Elf_Data descriptor that is malformed in various ways * should be rejected. */ diff --git a/test/libelftc/Makefile b/test/libelftc/Makefile index c9f086cc7b8d..f7a3903e2b9e 100644 --- a/test/libelftc/Makefile +++ b/test/libelftc/Makefile @@ -1,36 +1,6 @@ -# $Id: Makefile 2826 2012-12-29 16:39:18Z jkoshy $ - -TOP = ../.. - -.include "${TOP}/mk/elftoolchain.tetvars.mk" - -.if !defined(TET_EXECUTE) -TET_EXECUTE= ${.OBJDIR} -.endif - -.if make(tccbuild) -TET_OPTIONS+= -b -.endif - -.if make(tccclean) -TET_OPTIONS+= -c -.endif - -.if make(execute) || make(test) -TET_OPTIONS+= -e -.endif - -.MAIN: all - -.PHONY: clobber execute tccbuild tccclean test - -execute tccbuild tccclean test: - TET_ROOT=${TET_ROOT} TET_EXECUTE=${TET_EXECUTE} \ - TET_SUITE_ROOT=${.CURDIR} ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . - -clobber: clean - rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} +# $Id: Makefile 3028 2014-04-18 16:20:43Z jkoshy $ +TOP= ../.. SUBDIR= tset -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/test/libelftc/tset/Makefile b/test/libelftc/tset/Makefile index f0ba944fee21..6602c88c37ca 100644 --- a/test/libelftc/tset/Makefile +++ b/test/libelftc/tset/Makefile @@ -1,7 +1,8 @@ -# $Id: Makefile 2861 2013-01-05 09:35:42Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ +TOP= ../../.. SUBDIR= SUBDIR+= elftc_string_table SUBDIR+= elftc_version -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/libelftc/tset/Makefile.tset b/test/libelftc/tset/Makefile.tset index b28e6f717b48..dc637a90263a 100644 --- a/test/libelftc/tset/Makefile.tset +++ b/test/libelftc/tset/Makefile.tset @@ -1,8 +1,9 @@ -# $Id: Makefile.tset 2845 2012-12-31 04:19:35Z jkoshy $ +# $Id: Makefile.tset 3021 2014-04-17 16:32:00Z jkoshy $ -# All the test cases in this test suite need -lelftc. -DPADD+= ${LIBELFTC} -LDADD+= -lelftc +# All the test cases in this test suite need -lelftc. In addition, +# a few need -lelf. +DPADD+= ${LIBELFTC} ${LIBELF} +LDADD+= -lelftc -lelf GENERATE_TEST_SCAFFOLDING= yes diff --git a/test/libelftc/tset/elftc_string_table/string_table.m4 b/test/libelftc/tset/elftc_string_table/string_table.m4 index 0c6f730686db..74e66c99c12b 100644 --- a/test/libelftc/tset/elftc_string_table/string_table.m4 +++ b/test/libelftc/tset/elftc_string_table/string_table.m4 @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: string_table.m4 2868 2013-01-06 13:28:47Z jkoshy $ + * $Id: string_table.m4 3021 2014-04-17 16:32:00Z jkoshy $ */ /* @@ -33,10 +33,12 @@ #include <errno.h> #include <fcntl.h> +#include <libelf.h> #include <libelftc.h> #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <unistd.h> #include "tet_api.h" diff --git a/test/nm/Makefile b/test/nm/Makefile index df34d664a64f..fc9f5d1667e6 100644 --- a/test/nm/Makefile +++ b/test/nm/Makefile @@ -1,36 +1,6 @@ -# $Id: Makefile 2137 2011-11-10 13:09:30Z jkoshy $ - -TOP = ../.. - -.include "${TOP}/mk/elftoolchain.tetvars.mk" - -.if !defined(TET_EXECUTE) -TET_EXECUTE= ${.OBJDIR} -.endif - -.if make(tccbuild) -TET_OPTIONS+= -b -.endif - -.if make(tccclean) -TET_OPTIONS+= -c -.endif - -.if make(execute) || make(test) -TET_OPTIONS+= -e -.endif - -.MAIN: all - -.PHONY: clobber execute tccbuild tccclean test - -execute tccbuild tccclean test: - TET_EXECUTE=${TET_EXECUTE} TET_SUITE_ROOT=${.CURDIR} \ - TET_ROOT=${TET_ROOT} ${TET_ROOT}/bin/tcc ${TET_OPTIONS} . - -clobber: clean - rm -rf ${TET_RESULTS_DIR} ${TET_TMP_DIR} +# $Id: Makefile 3028 2014-04-18 16:20:43Z jkoshy $ +TOP= ../.. SUBDIR= ts -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.tetbase.mk" diff --git a/test/nm/ts/Makefile b/test/nm/ts/Makefile index b5352371f7d7..6d23d32206bb 100644 --- a/test/nm/ts/Makefile +++ b/test/nm/ts/Makefile @@ -1,4 +1,6 @@ -# $Id: Makefile 2085 2011-10-27 05:06:47Z jkoshy $ +# $Id: Makefile 3025 2014-04-18 16:20:25Z jkoshy $ + +TOP= ../../.. SUBDIR+= nm_archive1 SUBDIR+= nm_archive2 @@ -9,4 +11,4 @@ SUBDIR+= nm_option SUBDIR+= nm_shared_object1 SUBDIR+= nm_shared_object2 -.include <bsd.subdir.mk> +.include "${TOP}/mk/elftoolchain.subdir.mk" diff --git a/test/tet/Makefile b/test/tet/Makefile index e5396862ce2d..602ff6771fd4 100644 --- a/test/tet/Makefile +++ b/test/tet/Makefile @@ -1,7 +1,7 @@ # # Build TET from source. # -# $Id: Makefile 2117 2011-11-09 05:48:03Z jkoshy $ +# $Id: Makefile 3024 2014-04-18 16:20:11Z jkoshy $ # TOP= ../.. @@ -41,7 +41,7 @@ clean: clobber: rm -rf ${TET_ROOT} ${TET_BUILD_MARKER} ${TET_PATCH_MARKER} -depend test: .SILENT +cleandepend depend test: .SILENT true .else |