diff --git a/contrib/elftoolchain/addr2line/addr2line.c b/contrib/elftoolchain/addr2line/addr2line.c index 86e72822907..9863fcdc634 100644 --- a/contrib/elftoolchain/addr2line/addr2line.c +++ b/contrib/elftoolchain/addr2line/addr2line.c @@ -39,7 +39,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: addr2line.c 3197 2015-05-12 21:01:31Z emaste $"); +ELFTC_VCSID("$Id: addr2line.c 3249 2015-10-04 08:11:30Z kaiwang27 $"); static struct option longopts[] = { {"target" , required_argument, NULL, 'b'}, @@ -61,7 +61,7 @@ Usage: %s [options] hexaddress...\n\ Map program addresses to source file names and line numbers.\n\n\ Options:\n\ -b TGT | --target=TGT (Accepted but ignored).\n\ - -e EXE | --exec=EXE Use program \"EXE\" to translate addresses.\n\ + -e EXE | --exe=EXE Use program \"EXE\" to translate addresses.\n\ -f | --functions Display function names.\n\ -j NAME | --section=NAME Values are offsets into section \"NAME\".\n\ -s | --basename Only show the base name for each file name.\n\ @@ -123,8 +123,7 @@ handle_high_pc(Dwarf_Die die, Dwarf_Unsigned lopc, Dwarf_Unsigned *hipc) } static void -search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, - const char **rlt_func) +search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, char **rlt_func) { Dwarf_Die ret_die, spec_die; Dwarf_Error de; @@ -133,10 +132,11 @@ search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, Dwarf_Off ref; Dwarf_Attribute sub_at, spec_at; char *func0; + const char *func1; int ret; if (*rlt_func != NULL) - return; + goto done; if (dwarf_tag(die, &tag, &de)) { warnx("dwarf_tag: %s", dwarf_errmsg(de)); @@ -153,16 +153,19 @@ search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, /* Found it! */ - *rlt_func = unknown; + if ((*rlt_func = strdup(unknown)) == NULL) + err(EXIT_FAILURE, "strdup"); ret = dwarf_attr(die, DW_AT_name, &sub_at, &de); if (ret == DW_DLV_ERROR) - return; + goto done; if (ret == DW_DLV_OK) { - if (dwarf_formstring(sub_at, &func0, &de)) - *rlt_func = unknown; - else - *rlt_func = func0; - return; + if (dwarf_formstring(sub_at, &func0, &de) == + DW_DLV_OK) { + free(*rlt_func); + if ((*rlt_func = strdup(func0)) == NULL) + err(EXIT_FAILURE, "strdup"); + } + goto done; } /* @@ -171,15 +174,19 @@ search_func(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr addr, * referenced by DW_AT_specification. */ if (dwarf_attr(die, DW_AT_specification, &spec_at, &de)) - return; + goto done; if (dwarf_global_formref(spec_at, &ref, &de)) - return; + goto done; if (dwarf_offdie(dbg, ref, &spec_die, &de)) - return; - if (dwarf_attrval_string(spec_die, DW_AT_name, rlt_func, &de)) - *rlt_func = unknown; + goto done; + if (dwarf_attrval_string(spec_die, DW_AT_name, &func1, &de) == + DW_DLV_OK) { + free(*rlt_func); + if ((*rlt_func = strdup(func1)) == NULL) + err(EXIT_FAILURE, "strdup"); + } - return; + goto done; } cont_search: @@ -197,19 +204,22 @@ cont_search: errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) search_func(dbg, ret_die, addr, rlt_func); + +done: + dwarf_dealloc(dbg, die, DW_DLA_DIE); } static void translate(Dwarf_Debug dbg, const char* addrstr) { - Dwarf_Die die; + Dwarf_Die die, ret_die; Dwarf_Line *lbuf; Dwarf_Error de; Dwarf_Half tag; Dwarf_Unsigned lopc, hipc, addr, lineno, plineno; Dwarf_Signed lcount; Dwarf_Addr lineaddr, plineaddr; - const char *funcname; + char *funcname; char *file, *file0, *pfile; char demangled[1024]; int i, ret; @@ -218,23 +228,29 @@ translate(Dwarf_Debug dbg, const char* addrstr) addr += section_base; lineno = 0; file = unknown; + lbuf = NULL; + lcount = 0; while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { die = NULL; - while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { + while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) { + if (die != NULL) + dwarf_dealloc(dbg, die, DW_DLA_DIE); + die = ret_die; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); - goto out; + goto next_cu; } + /* XXX: What about DW_TAG_partial_unit? */ if (tag == DW_TAG_compile_unit) break; } - if (die == NULL) { + if (ret_die == NULL) { warnx("could not find DW_TAG_compile_unit die"); - goto out; + goto next_cu; } if (!dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) && !dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) { @@ -243,17 +259,17 @@ translate(Dwarf_Debug dbg, const char* addrstr) * this CU. */ if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK) - continue; + goto next_cu; if (addr < lopc || addr >= hipc) - continue; + goto next_cu; } switch (dwarf_srclines(die, &lbuf, &lcount, &de)) { case DW_DLV_OK: break; case DW_DLV_NO_ENTRY: - /* If one CU lacks debug info, just skip it. */ - continue; + /* If a CU lacks debug info, just skip it. */ + goto next_cu; default: warnx("dwarf_srclines: %s", dwarf_errmsg(de)); goto out; @@ -289,25 +305,37 @@ translate(Dwarf_Debug dbg, const char* addrstr) plineno = lineno; pfile = file; } + next_cu: + if (die != NULL) { + dwarf_dealloc(dbg, die, DW_DLA_DIE); + die = NULL; + } } out: funcname = NULL; - if (ret == DW_DLV_OK && func) + if (ret == DW_DLV_OK && func) { search_func(dbg, die, addr, &funcname); + die = NULL; + } if (func) { if (funcname == NULL) - funcname = unknown; + if ((funcname = strdup(unknown)) == NULL) + err(EXIT_FAILURE, "strdup"); if (demangle && !elftc_demangle(funcname, demangled, sizeof(demangled), 0)) printf("%s\n", demangled); else printf("%s\n", funcname); + free(funcname); } (void) printf("%s:%ju\n", base ? basename(file) : file, lineno); + if (die != NULL) + dwarf_dealloc(dbg, die, DW_DLA_DIE); + /* * Reset internal CU pointer, so we will start from the first CU * next round. diff --git a/contrib/elftoolchain/ar/ar.1 b/contrib/elftoolchain/ar/ar.1 index 2bfa908d6ed..f4cd9340724 100644 --- a/contrib/elftoolchain/ar/ar.1 +++ b/contrib/elftoolchain/ar/ar.1 @@ -21,9 +21,9 @@ .\" out of the use of this software, even if advised of the possibility of .\" such damage. .\" -.\" $Id: ar.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: ar.1 3230 2015-07-27 17:11:38Z emaste $ .\" -.Dd December 10, 2012 +.Dd July 27, 2015 .Os .Dt AR 1 .Sh NAME @@ -66,6 +66,7 @@ .Op Fl f .Op Fl F Ar flavor | Fl -flavor Ar flavor .Op Fl s | Fl S +.Op Fl U .Op Fl v .Op Fl z .Ar archive @@ -83,6 +84,7 @@ .Op Fl j .Op Fl s | Fl S .Op Fl u +.Op Fl U .Op Fl v .Op Fl z .Ar archive @@ -91,6 +93,7 @@ .Fl s .Op Fl D .Op Fl j +.Op Fl U .Op Fl z .Ar archive .Nm @@ -203,6 +206,11 @@ and 0644 instead of file mode from the members named by arguments .Ar . This ensures that checksums on the resulting archives are reproducible when member contents are identical. +If multiple +.Fl D +and +.Fl U +options are specified on the command line, the final one takes precedence. .It Fl f Synonymous with option .Fl T . @@ -335,6 +343,19 @@ option, the members specified by arguments .Ar will be extracted only if they are newer than the corresponding files in the file system. +.It Fl U +When used in combination with the +.Fl r +or +.Fl q +option, insert the real mtime, uid and gid, and file mode values +from the members named by arguments +.Ar . +If multiple +.Fl D +and +.Fl U +options are specified on the command line, the final one takes precedence. .It Fl v Provide verbose output. When used with the diff --git a/contrib/elftoolchain/ar/ar.c b/contrib/elftoolchain/ar/ar.c index ceecbd93920..62f0e55d5d3 100644 --- a/contrib/elftoolchain/ar/ar.c +++ b/contrib/elftoolchain/ar/ar.c @@ -72,7 +72,7 @@ #include "ar.h" -ELFTC_VCSID("$Id: ar.c 3183 2015-04-10 16:18:42Z emaste $"); +ELFTC_VCSID("$Id: ar.c 3243 2015-08-31 19:28:45Z emaste $"); enum options { @@ -123,7 +123,7 @@ main(int argc, char **argv) len = strlen(bsdar->progname); if (len >= strlen("ranlib") && strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) { - while ((opt = getopt_long(argc, argv, "tDV", longopts, + while ((opt = getopt_long(argc, argv, "tDUV", longopts, NULL)) != -1) { switch(opt) { case 't': @@ -132,6 +132,9 @@ main(int argc, char **argv) case 'D': bsdar->options |= AR_D; break; + case 'U': + bsdar->options &= ~AR_D; + break; case 'V': bsdar_version(); break; @@ -148,7 +151,7 @@ main(int argc, char **argv) ranlib_usage(); bsdar->options |= AR_S; - for (;(bsdar->filename = *argv++) != NULL;) + while ((bsdar->filename = *argv++) != NULL) ar_write_archive(bsdar, 's'); exit(EXIT_SUCCESS); @@ -169,7 +172,7 @@ main(int argc, char **argv) } } - while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtuVvxz", + while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtUuVvxz", longopts, NULL)) != -1) { switch(opt) { case 'a': @@ -237,6 +240,9 @@ main(int argc, char **argv) case 't': set_mode(bsdar, opt); break; + case 'U': + bsdar->options &= ~AR_D; + break; case 'u': bsdar->options |= AR_U; break; @@ -400,7 +406,8 @@ Usage: %s [options] archive file...\n\ -D Use fixed metadata, for consistent archive checksums.\n\ -F FORMAT | --flavor=FORMAT\n\ Create archives with the specified format.\n\ - -S Do not generate an archive symbol table.\n" + -S Do not generate an archive symbol table.\n\ + -U Use original metadata, for unique archive checksums.\n" static void bsdar_usage(void) @@ -415,6 +422,7 @@ Usage: %s [options] archive...\n\ Options:\n\ -t (This option is accepted, but ignored).\n\ -D Use fixed metadata, for consistent archive checksums.\n\ + -U Use original metadata, for unique archive checksums.\n\ -V Print a version identifier and exit.\n" static void diff --git a/contrib/elftoolchain/brandelf/brandelf.1 b/contrib/elftoolchain/brandelf/brandelf.1 index 1c2e485e44e..8df5fa8cc86 100644 --- a/contrib/elftoolchain/brandelf/brandelf.1 +++ b/contrib/elftoolchain/brandelf/brandelf.1 @@ -1,5 +1,4 @@ -.\" Copyright (c) 1997 -.\" John-Mark Gurney. All rights reserved. +.\" Copyright 1997 John-Mark Gurney. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -9,11 +8,8 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the author nor the names of any co-contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. .\" -.\" THIS SOFTWARE IS PROVIDED BY John-Mark Gurney AND CONTRIBUTORS ``AS IS'' +.\" 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 @@ -26,7 +22,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD: src/usr.bin/brandelf/brandelf.1,v 1.17 2007/03/09 14:36:18 ru Exp $ -.\" $Id: brandelf.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: brandelf.1 3235 2015-07-31 16:44:47Z emaste $ .\" .Dd October 27, 2014 .Dt BRANDELF 1 @@ -148,4 +144,4 @@ manual page first appeared in .Fx 2.2 . .Sh AUTHORS This manual page was written by -.An John-Mark Gurney Aq Mt gurney_j@efn.org . +.An John-Mark Gurney Aq Mt jmg@FreeBSD.org . diff --git a/contrib/elftoolchain/brandelf/brandelf.c b/contrib/elftoolchain/brandelf/brandelf.c index 5f5e6317b7b..cbe5d6cabbb 100644 --- a/contrib/elftoolchain/brandelf/brandelf.c +++ b/contrib/elftoolchain/brandelf/brandelf.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 2008 Hyogeol Lee * Copyright (c) 2000, 2001 David O'Brien - * Copyright (c) 1996 Søren Schmidt + * Copyright (c) 1996 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: brandelf.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: brandelf.c 3234 2015-07-31 12:35:09Z emaste $"); static int elftype(const char *); static const char *iselftype(int); diff --git a/contrib/elftoolchain/common/_elftc.h b/contrib/elftoolchain/common/_elftc.h index 6769519a16d..94272ef6aba 100644 --- a/contrib/elftoolchain/common/_elftc.h +++ b/contrib/elftoolchain/common/_elftc.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: _elftc.h 3209 2015-05-17 13:40:46Z kaiwang27 $ + * $Id: _elftc.h 3244 2015-08-31 19:53:08Z emaste $ */ /** @@ -372,7 +372,8 @@ extern const char *__progname; #if defined(__APPLE__) -#include +#include +#define htobe32(x) OSSwapHostToBigInt32(x) #define roundup2 roundup #define ELFTC_BYTE_ORDER _BYTE_ORDER @@ -382,6 +383,7 @@ extern const char *__progname; #define ELFTC_HAVE_MMAP 1 #define ELFTC_HAVE_STRMODE 1 +#define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 #endif /* __APPLE__ */ diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h index 21b415bb069..ab7001fb82e 100644 --- a/contrib/elftoolchain/common/elfdefinitions.h +++ b/contrib/elftoolchain/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 3198 2015-05-14 18:36:19Z emaste $ + * $Id: elfdefinitions.h 3247 2015-09-22 16:57:51Z emaste $ */ /* @@ -859,6 +859,12 @@ enum { #define GRP_MASKOS 0x0ff00000 /* OS-specific flags */ #define GRP_MASKPROC 0xf0000000 /* processor-specific flags */ +/* + * Flags / mask for .gnu.versym sections. + */ +#define VERSYM_VERSION 0x7fff +#define VERSYM_HIDDEN 0x8000 + /* * Flags used by program header table entries. */ @@ -1183,6 +1189,8 @@ _ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD, 0x70000028UL, \ "obsolete") \ _ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, \ "runtime procedure descriptor table exception information") \ +_ELF_DEFINE_SHT(SHT_MIPS_ABIFLAGS, 0x7000002AUL, \ + "ABI flags") \ _ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ "SPARC-specific data") \ _ELF_DEFINE_SHT(SHT_AMD64_UNWIND, 0x70000001UL, \ @@ -1865,6 +1873,50 @@ _ELF_DEFINE_RELOC(R_PPC64_DTPREL16_HIGHESTA, 106) \ _ELF_DEFINE_RELOC(R_PPC64_TLSGD, 107) \ _ELF_DEFINE_RELOC(R_PPC64_TLSLD, 108) +#define _ELF_DEFINE_RISCV_RELOCATIONS() \ +_ELF_DEFINE_RELOC(R_RISCV_NONE, 0) \ +_ELF_DEFINE_RELOC(R_RISCV_32, 1) \ +_ELF_DEFINE_RELOC(R_RISCV_64, 2) \ +_ELF_DEFINE_RELOC(R_RISCV_RELATIVE, 3) \ +_ELF_DEFINE_RELOC(R_RISCV_COPY, 4) \ +_ELF_DEFINE_RELOC(R_RISCV_JUMP_SLOT, 5) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_DTPMOD32, 6) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_DTPMOD64, 7) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_DTPREL32, 8) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_DTPREL64, 9) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_TPREL32, 10) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_TPREL64, 11) \ +_ELF_DEFINE_RELOC(R_RISCV_BRANCH, 16) \ +_ELF_DEFINE_RELOC(R_RISCV_JAL, 17) \ +_ELF_DEFINE_RELOC(R_RISCV_CALL, 18) \ +_ELF_DEFINE_RELOC(R_RISCV_CALL_PLT, 19) \ +_ELF_DEFINE_RELOC(R_RISCV_GOT_HI20, 20) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_GOT_HI20, 21) \ +_ELF_DEFINE_RELOC(R_RISCV_TLS_GD_HI20, 22) \ +_ELF_DEFINE_RELOC(R_RISCV_PCREL_HI20, 23) \ +_ELF_DEFINE_RELOC(R_RISCV_PCREL_LO12_I, 24) \ +_ELF_DEFINE_RELOC(R_RISCV_PCREL_LO12_S, 25) \ +_ELF_DEFINE_RELOC(R_RISCV_HI20, 26) \ +_ELF_DEFINE_RELOC(R_RISCV_LO12_I, 27) \ +_ELF_DEFINE_RELOC(R_RISCV_LO12_S, 28) \ +_ELF_DEFINE_RELOC(R_RISCV_TPREL_HI20, 29) \ +_ELF_DEFINE_RELOC(R_RISCV_TPREL_LO12_I, 30) \ +_ELF_DEFINE_RELOC(R_RISCV_TPREL_LO12_S, 31) \ +_ELF_DEFINE_RELOC(R_RISCV_TPREL_ADD, 32) \ +_ELF_DEFINE_RELOC(R_RISCV_ADD8, 33) \ +_ELF_DEFINE_RELOC(R_RISCV_ADD16, 34) \ +_ELF_DEFINE_RELOC(R_RISCV_ADD32, 35) \ +_ELF_DEFINE_RELOC(R_RISCV_ADD64, 36) \ +_ELF_DEFINE_RELOC(R_RISCV_SUB8, 37) \ +_ELF_DEFINE_RELOC(R_RISCV_SUB16, 38) \ +_ELF_DEFINE_RELOC(R_RISCV_SUB32, 39) \ +_ELF_DEFINE_RELOC(R_RISCV_SUB64, 40) \ +_ELF_DEFINE_RELOC(R_RISCV_GNU_VTINHERIT, 41) \ +_ELF_DEFINE_RELOC(R_RISCV_GNU_VTENTRY, 42) \ +_ELF_DEFINE_RELOC(R_RISCV_ALIGN 43) \ +_ELF_DEFINE_RELOC(R_RISCV_RVC_BRANCH, 44) \ +_ELF_DEFINE_RELOC(R_RISCV_RVC_JUMP, 45) + #define _ELF_DEFINE_SPARC_RELOCATIONS() \ _ELF_DEFINE_RELOC(R_SPARC_NONE, 0) \ _ELF_DEFINE_RELOC(R_SPARC_8, 1) \ diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c index a6fd25d5f33..02516efd96b 100644 --- a/contrib/elftoolchain/elfcopy/sections.c +++ b/contrib/elftoolchain/elfcopy/sections.c @@ -34,7 +34,7 @@ #include "elfcopy.h" -ELFTC_VCSID("$Id: sections.c 3220 2015-05-24 23:42:39Z kaiwang27 $"); +ELFTC_VCSID("$Id: sections.c 3225 2015-06-06 02:35:23Z kaiwang27 $"); static void add_gnu_debuglink(struct elfcopy *ecp); static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); diff --git a/contrib/elftoolchain/elfdump/elfdump.1 b/contrib/elftoolchain/elfdump/elfdump.1 index eae7262900a..e586ab23c56 100644 --- a/contrib/elftoolchain/elfdump/elfdump.1 +++ b/contrib/elftoolchain/elfdump/elfdump.1 @@ -23,7 +23,7 @@ .\" SUCH DAMAGE. .\" .\" $FreeBSD: src/usr.bin/elfdump/elfdump.1,v 1.6 2005/01/18 13:43:48 ru Exp $ -.\" $Id: elfdump.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: elfdump.1 3231 2015-07-30 13:47:56Z emaste $ .\" .Dd August 25, 2011 .Dt ELFDUMP 1 @@ -54,7 +54,7 @@ The options are as follows: .It Fl a Dump all information. .It Fl c -Dump shared headers. +Dump section headers. .It Fl d Dump dynamic symbols. .It Fl e diff --git a/contrib/elftoolchain/elfdump/elfdump.c b/contrib/elftoolchain/elfdump/elfdump.c index cb499d18f2c..baf99eee1e9 100644 --- a/contrib/elftoolchain/elfdump/elfdump.c +++ b/contrib/elftoolchain/elfdump/elfdump.c @@ -50,7 +50,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: elfdump.c 3198 2015-05-14 18:36:19Z emaste $"); +ELFTC_VCSID("$Id: elfdump.c 3250 2015-10-06 13:56:15Z emaste $"); #if defined(ELFTC_NEED_ELF_NOTE_DEFINITION) #include "native-elf-format.h" @@ -205,11 +205,11 @@ d_tags(uint64_t tag) case 0x6ffffef5: return "DT_GNU_HASH"; case 0x6ffffef8: return "DT_GNU_CONFLICT"; case 0x6ffffef9: return "DT_GNU_LIBLIST"; - case 0x6ffffefa: return "DT_SUNW_CONFIG"; - case 0x6ffffefb: return "DT_SUNW_DEPAUDIT"; - case 0x6ffffefc: return "DT_SUNW_AUDIT"; - case 0x6ffffefd: return "DT_SUNW_PLTPAD"; - case 0x6ffffefe: return "DT_SUNW_MOVETAB"; + case 0x6ffffefa: return "DT_CONFIG"; + case 0x6ffffefb: return "DT_DEPAUDIT"; + case 0x6ffffefc: return "DT_AUDIT"; + case 0x6ffffefd: return "DT_PLTPAD"; + case 0x6ffffefe: return "DT_MOVETAB"; case 0x6ffffeff: return "DT_SYMINFO (DT_ADDRRNGHI)"; case 0x6ffffff9: return "DT_RELACOUNT"; case 0x6ffffffa: return "DT_RELCOUNT"; @@ -244,11 +244,14 @@ e_machines(unsigned int mach) case EM_860: return "EM_860"; case EM_MIPS: return "EM_MIPS"; case EM_PPC: return "EM_PPC"; + case EM_PPC64: return "EM_PPC64"; case EM_ARM: return "EM_ARM"; case EM_ALPHA: return "EM_ALPHA (legacy)"; case EM_SPARCV9:return "EM_SPARCV9"; case EM_IA_64: return "EM_IA_64"; case EM_X86_64: return "EM_X86_64"; + case EM_AARCH64:return "EM_AARCH64"; + case EM_RISCV: return "EM_RISCV"; } snprintf(machdesc, sizeof(machdesc), "(unknown machine) -- type 0x%x", mach); @@ -271,11 +274,12 @@ static const char *ei_data[] = { "ELFDATANONE", "ELFDATA2LSB", "ELFDATA2MSB" }; -static const char *ei_abis[] = { +static const char *ei_abis[256] = { "ELFOSABI_NONE", "ELFOSABI_HPUX", "ELFOSABI_NETBSD", "ELFOSABI_LINUX", - "ELFOSABI_HURD", "ELFOSABI_86OPEN", "ELFOSABI_SOLARIS", - "ELFOSABI_MONTEREY", "ELFOSABI_IRIX", "ELFOSABI_FREEBSD", - "ELFOSABI_TRU64", "ELFOSABI_MODESTO", "ELFOSABI_OPENBSD" + "ELFOSABI_HURD", "ELFOSABI_86OPEN", "ELFOSABI_SOLARIS", "ELFOSABI_AIX", + "ELFOSABI_IRIX", "ELFOSABI_FREEBSD", "ELFOSABI_TRU64", + "ELFOSABI_MODESTO", "ELFOSABI_OPENBSD", + [255] = "ELFOSABI_STANDALONE" }; static const char *p_types[] = { @@ -330,6 +334,7 @@ sh_types(u_int64_t sht) { case 18: return "SHT_SYMTAB_SHNDX"; /* 0x60000000 - 0x6fffffff operating system-specific semantics */ case 0x6ffffff0: return "XXX:VERSYM"; + case 0x6ffffff4: return "SHT_SUNW_dof"; case 0x6ffffff6: return "SHT_GNU_HASH"; case 0x6ffffff7: return "SHT_GNU_LIBLIST"; case 0x6ffffffc: return "XXX:VERDEF"; @@ -818,6 +823,7 @@ static void elf_print_checksum(struct elfdump *ed); static void find_gotrel(struct elfdump *ed, struct section *gs, struct rel_entry *got); static struct spec_name *find_name(struct elfdump *ed, const char *name); +static int get_ent_count(const struct section *s, int *ent_count); static const char *get_symbol_name(struct elfdump *ed, int symtab, int i); static const char *get_string(struct elfdump *ed, int strtab, size_t off); static void get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs); @@ -1625,6 +1631,24 @@ elf_print_shdr(struct elfdump *ed) } } +/* + * Return number of entries in the given section. We'd prefer ent_count be a + * size_t, but libelf APIs already use int for section indices. + */ +static int +get_ent_count(const struct section *s, int *ent_count) +{ + if (s->entsize == 0) { + warnx("section %s has entry size 0", s->name); + return (0); + } else if (s->sz / s->entsize > INT_MAX) { + warnx("section %s has invalid section count", s->name); + return (0); + } + *ent_count = (int)(s->sz / s->entsize); + return (1); +} + /* * Retrieve the content of the corresponding SHT_SUNW_versym section for * a symbol table section. @@ -1656,7 +1680,9 @@ get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs) } *vs = data->d_buf; - *nvs = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, nvs)) + *nvs = 0; } /* @@ -1687,7 +1713,9 @@ elf_print_symtab(struct elfdump *ed, int i) } vs = NULL; nvs = 0; - len = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; if (ed->flags & SOLARIS_FMT) { if (ed->ec == ELFCLASS32) PRT(" index value "); @@ -1786,7 +1814,9 @@ elf_print_dynamic(struct elfdump *ed) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } - len = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; for (i = 0; i < len; i++) { if (gelf_getdyn(data, i, &dyn) != &dyn) { warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); @@ -1912,7 +1942,9 @@ elf_print_rela(struct elfdump *ed, struct section *s, Elf_Data *data) } else PRT("\nrelocation with addend (%s):\n", s->name); r.type = SHT_RELA; - len = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; for (j = 0; j < len; j++) { if (gelf_getrela(data, j, &r.u_r.rela) != &r.u_r.rela) { warnx("gelf_getrela failed: %s", @@ -1941,7 +1973,9 @@ elf_print_rel(struct elfdump *ed, struct section *s, Elf_Data *data) } else PRT("\nrelocation (%s):\n", s->name); r.type = SHT_REL; - len = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; for (j = 0; j < len; j++) { if (gelf_getrel(data, j, &r.u_r.rel) != &r.u_r.rel) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); @@ -2042,7 +2076,9 @@ find_gotrel(struct elfdump *ed, struct section *gs, struct rel_entry *got) } memset(&r, 0, sizeof(struct rel_entry)); r.type = s->type; - len = data->d_size / s->entsize; + assert(data->d_size == s->sz); + if (!get_ent_count(s, &len)) + return; for (j = 0; j < len; j++) { if (s->type == SHT_REL) { if (gelf_getrel(data, j, &r.u_r.rel) != @@ -2086,9 +2122,11 @@ elf_print_got_section(struct elfdump *ed, struct section *s) return; } + if (!get_ent_count(s, &len)) + return; if (ed->flags & SOLARIS_FMT) - PRT("\nGlobal Offset Table Section: %s (%jd entries)\n", - s->name, s->sz / s->entsize); + PRT("\nGlobal Offset Table Section: %s (%d entries)\n", + s->name, len); else PRT("\nglobal offset table: %s\n", s->name); (void) elf_errno(); @@ -2115,7 +2153,7 @@ elf_print_got_section(struct elfdump *ed, struct section *s) warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); return; } - len = dst.d_size / s->entsize; + assert(dst.d_size == s->sz); if (ed->flags & SOLARIS_FMT) { /* * In verbose/Solaris mode, we search the relocation sections @@ -2503,7 +2541,8 @@ elf_print_gnu_hash(struct elfdump *ed, struct section *s) shift2 = buf[3]; buf += 4; ds = &ed->sl[s->link]; - dynsymcount = ds->sz / ds->entsize; + if (!get_ent_count(ds, &dynsymcount)) + return; nchain = dynsymcount - symndx; if (data->d_size != 4 * sizeof(uint32_t) + maskwords * (ed->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + diff --git a/contrib/elftoolchain/libdwarf/dwarf_sections.c b/contrib/elftoolchain/libdwarf/dwarf_sections.c index 172573ba98f..dc676a383b8 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_sections.c +++ b/contrib/elftoolchain/libdwarf/dwarf_sections.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_sections.c 3036 2014-05-05 19:19:31Z kaiwang27 $"); +ELFTC_VCSID("$Id: dwarf_sections.c 3226 2015-06-23 13:00:16Z emaste $"); #define SET(N, V) \ do { \ diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index e4ebe2698d3..8e4688a0ff6 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -47,7 +47,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: readelf.c 3223 2015-05-25 20:37:57Z emaste $"); +ELFTC_VCSID("$Id: readelf.c 3250 2015-10-06 13:56:15Z emaste $"); /* * readelf(1) options. @@ -1378,6 +1378,51 @@ r_type(unsigned int mach, unsigned int type) case 116: return "R_PPC_EMB_RELSDA"; default: return ""; } + case EM_RISCV: + switch(type) { + case 0: return "R_RISCV_NONE"; + case 1: return "R_RISCV_32"; + case 2: return "R_RISCV_64"; + case 3: return "R_RISCV_RELATIVE"; + case 4: return "R_RISCV_COPY"; + case 5: return "R_RISCV_JUMP_SLOT"; + case 6: return "R_RISCV_TLS_DTPMOD32"; + case 7: return "R_RISCV_TLS_DTPMOD64"; + case 8: return "R_RISCV_TLS_DTPREL32"; + case 9: return "R_RISCV_TLS_DTPREL64"; + case 10: return "R_RISCV_TLS_TPREL32"; + case 11: return "R_RISCV_TLS_TPREL64"; + case 16: return "R_RISCV_BRANCH"; + case 17: return "R_RISCV_JAL"; + case 18: return "R_RISCV_CALL"; + case 19: return "R_RISCV_CALL_PLT"; + case 20: return "R_RISCV_GOT_HI20"; + case 21: return "R_RISCV_TLS_GOT_HI20"; + case 22: return "R_RISCV_TLS_GD_HI20"; + case 23: return "R_RISCV_PCREL_HI20"; + case 24: return "R_RISCV_PCREL_LO12_I"; + case 25: return "R_RISCV_PCREL_LO12_S"; + case 26: return "R_RISCV_HI20"; + case 27: return "R_RISCV_LO12_I"; + case 28: return "R_RISCV_LO12_S"; + case 29: return "R_RISCV_TPREL_HI20"; + case 30: return "R_RISCV_TPREL_LO12_I"; + case 31: return "R_RISCV_TPREL_LO12_S"; + case 32: return "R_RISCV_TPREL_ADD"; + case 33: return "R_RISCV_ADD8"; + case 34: return "R_RISCV_ADD16"; + case 35: return "R_RISCV_ADD32"; + case 36: return "R_RISCV_ADD64"; + case 37: return "R_RISCV_SUB8"; + case 38: return "R_RISCV_SUB16"; + case 39: return "R_RISCV_SUB32"; + case 40: return "R_RISCV_SUB64"; + case 41: return "R_RISCV_GNU_VTINHERIT"; + case 42: return "R_RISCV_GNU_VTENTRY"; + case 43: return "R_RISCV_ALIGN"; + case 44: return "R_RISCV_RVC_BRANCH"; + case 45: return "R_RISCV_RVC_JUMP"; + } case EM_SPARC: case EM_SPARCV9: switch(type) { @@ -3179,6 +3224,9 @@ dump_rel(struct readelf *re, struct section *s, Elf_Data *d) uint64_t symval; int i, len; + if (s->link >= re->shnum) + return; + #define REL_HDR "r_offset", "r_info", "r_type", "st_value", "st_name" #define REL_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ r_type(re->ehdr.e_machine, ELF32_R_TYPE(r.r_info)), \ @@ -3204,10 +3252,6 @@ dump_rel(struct readelf *re, struct section *s, Elf_Data *d) warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } - if (s->link >= re->shnum) { - warnx("invalid section link index %u", s->link); - continue; - } symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); if (re->ec == ELFCLASS32) { @@ -3236,6 +3280,9 @@ dump_rela(struct readelf *re, struct section *s, Elf_Data *d) uint64_t symval; int i, len; + if (s->link >= re->shnum) + return; + #define RELA_HDR "r_offset", "r_info", "r_type", "st_value", \ "st_name + r_addend" #define RELA_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ @@ -3262,10 +3309,6 @@ dump_rela(struct readelf *re, struct section *s, Elf_Data *d) warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } - if (s->link >= re->shnum) { - warnx("invalid section link index %u", s->link); - continue; - } symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); if (re->ec == ELFCLASS32) { @@ -3321,9 +3364,13 @@ dump_symtab(struct readelf *re, int i) Elf_Data *d; GElf_Sym sym; const char *name; - int elferr, stab, j, len; + uint32_t stab; + int elferr, j, len; + uint16_t vs; s = &re->sl[i]; + if (s->link >= re->shnum) + return; stab = s->link; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { @@ -3358,14 +3405,15 @@ dump_symtab(struct readelf *re, int i) /* Append symbol version string for SHT_DYNSYM symbol table. */ if (s->type == SHT_DYNSYM && re->ver != NULL && re->vs != NULL && re->vs[j] > 1) { - if (re->vs[j] & 0x8000 || - re->ver[re->vs[j] & 0x7fff].type == 0) - printf("@%s (%d)", - re->ver[re->vs[j] & 0x7fff].name, - re->vs[j] & 0x7fff); + vs = re->vs[j] & VERSYM_VERSION; + if (vs >= re->ver_sz || re->ver[vs].name == NULL) { + warnx("invalid versym version index %u", vs); + break; + } + if (re->vs[j] & VERSYM_HIDDEN || re->ver[vs].type == 0) + printf("@%s (%d)", re->ver[vs].name, vs); else - printf("@@%s (%d)", re->ver[re->vs[j]].name, - re->vs[j]); + printf("@@%s (%d)", re->ver[vs].name, vs); } putchar('\n'); } @@ -3594,6 +3642,8 @@ dump_gnu_hash(struct readelf *re, struct section *s) symndx = buf[1]; maskwords = buf[2]; buf += 4; + if (s->link >= re->shnum) + return; ds = &re->sl[s->link]; if (!get_ent_count(ds, &dynsymcount)) return; @@ -3800,6 +3850,8 @@ dump_verdef(struct readelf *re, int dump) if ((s = re->vd_s) == NULL) return; + if (s->link >= re->shnum) + return; if (re->ver == NULL) { re->ver_sz = 16; @@ -3873,6 +3925,8 @@ dump_verneed(struct readelf *re, int dump) if ((s = re->vn_s) == NULL) return; + if (s->link >= re->shnum) + return; if (re->ver == NULL) { re->ver_sz = 16; @@ -3937,6 +3991,7 @@ static void dump_versym(struct readelf *re) { int i; + uint16_t vs; if (re->vs_s == NULL || re->ver == NULL || re->vs == NULL) return; @@ -3947,12 +4002,16 @@ dump_versym(struct readelf *re) putchar('\n'); printf(" %03x:", i); } - if (re->vs[i] & 0x8000) - printf(" %3xh %-12s ", re->vs[i] & 0x7fff, - re->ver[re->vs[i] & 0x7fff].name); + vs = re->vs[i] & VERSYM_VERSION; + if (vs >= re->ver_sz || re->ver[vs].name == NULL) { + warnx("invalid versym version index %u", re->vs[i]); + break; + } + if (re->vs[i] & VERSYM_HIDDEN) + printf(" %3xh %-12s ", vs, + re->ver[re->vs[i] & VERSYM_VERSION].name); else - printf(" %3x %-12s ", re->vs[i], - re->ver[re->vs[i]].name); + printf(" %3x %-12s ", vs, re->ver[re->vs[i]].name); } putchar('\n'); } @@ -4031,6 +4090,8 @@ dump_liblist(struct readelf *re) s = &re->sl[i]; if (s->type != SHT_GNU_LIBLIST) continue; + if (s->link >= re->shnum) + continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); @@ -4097,6 +4158,8 @@ dump_section_groups(struct readelf *re) s = &re->sl[i]; if (s->type != SHT_GROUP) continue; + if (s->link >= re->shnum) + continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); @@ -6669,7 +6732,8 @@ get_symbol_name(struct readelf *re, int symtab, int i) if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && re->sl[sym.st_shndx].name != NULL) return (re->sl[sym.st_shndx].name); - if ((name = elf_strptr(re->elf, s->link, sym.st_name)) == NULL) + if (s->link >= re->shnum || + (name = elf_strptr(re->elf, s->link, sym.st_name)) == NULL) return (""); return (name); @@ -6860,6 +6924,9 @@ load_sections(struct readelf *re) warnx("section index of '%s' out of range", name); continue; } + if (sh.sh_link >= re->shnum) + warnx("section link %llu of '%s' out of range", + (unsigned long long)sh.sh_link, name); s = &re->sl[ndx]; s->name = name; s->scn = scn; diff --git a/contrib/elftoolchain/size/size.c b/contrib/elftoolchain/size/size.c index 40d75f8c43f..cdbe3e4efda 100644 --- a/contrib/elftoolchain/size/size.c +++ b/contrib/elftoolchain/size/size.c @@ -38,7 +38,7 @@ #include "_elftc.h" -ELFTC_VCSID("$Id: size.c 3183 2015-04-10 16:18:42Z emaste $"); +ELFTC_VCSID("$Id: size.c 3242 2015-08-07 12:47:11Z emaste $"); #define BUF_SIZE 1024 #define ELF_ALIGN(val,x) (((val)+(x)-1) & ~((x)-1)) @@ -444,7 +444,6 @@ handle_phdr(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr, if (elf == NULL || elfhdr == NULL || phdr == NULL) return; - size = addr = 0; split = (phdr->p_memsz > 0) && (phdr->p_filesz > 0) && (phdr->p_memsz > phdr->p_filesz);