aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-17 14:34:11 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-17 14:34:11 +0000
commitd356830d3d227b40603d19222ab35eb8f0f5c034 (patch)
tree603c3338aa5864e50427394e4863cb695e19330f
parent42bfa111d731278ff40f9ce45298e65a373c2064 (diff)
Notes
-rw-r--r--addr2line/addr2line.c6
-rw-r--r--ar/acplex.l3
-rw-r--r--ar/read.c5
-rw-r--r--common/_elftc.h15
-rw-r--r--common/elfdefinitions.h17
-rw-r--r--elfcopy/main.c56
-rw-r--r--elfcopy/sections.c4
-rw-r--r--elfdump/elfdump.c10
-rw-r--r--libdwarf/_libdwarf.h4
-rw-r--r--libdwarf/dwarf_attrval.c3
-rw-r--r--libdwarf/dwarf_get_AT_name.33
-rw-r--r--libdwarf/dwarf_get_arange_info.33
-rw-r--r--libdwarf/dwarf_get_section_max_offsets.36
-rw-r--r--libdwarf/dwarf_hasattr.33
-rw-r--r--libdwarf/dwarf_reloc.c6
-rw-r--r--libdwarf/dwarf_set_reloc_application.36
-rw-r--r--libdwarf/dwarf_whatattr.33
-rw-r--r--libdwarf/libdwarf.c4
-rw-r--r--libdwarf/libdwarf.h3
-rw-r--r--libdwarf/libdwarf_elf_init.c69
-rw-r--r--libdwarf/libdwarf_reloc.c10
-rw-r--r--libelf/_libelf_config.h8
-rw-r--r--libelf/elf.33
-rw-r--r--libelf/elf_scn.c8
-rw-r--r--libelf/libelf_ar_util.c6
-rw-r--r--libelf/libelf_convert.m412
-rw-r--r--nm/nm.110
-rw-r--r--nm/nm.c5
-rw-r--r--readelf/readelf.c254
29 files changed, 372 insertions, 173 deletions
diff --git a/addr2line/addr2line.c b/addr2line/addr2line.c
index b58b4b352a47..6dcf19ceca4a 100644
--- a/addr2line/addr2line.c
+++ b/addr2line/addr2line.c
@@ -40,7 +40,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: addr2line.c 2185 2011-11-19 16:07:16Z jkoshy $");
+ELFTC_VCSID("$Id: addr2line.c 3148 2015-02-15 18:47:39Z emaste $");
static struct option longopts[] = {
{"target" , required_argument, NULL, 'b'},
@@ -399,8 +399,10 @@ main(int argc, char **argv)
for (i = 0; i < argc; i++)
translate(dbg, argv[i]);
else
- while (fgets(line, sizeof(line), stdin) != NULL)
+ while (fgets(line, sizeof(line), stdin) != NULL) {
translate(dbg, line);
+ fflush(stdout);
+ }
dwarf_finish(dbg, &de);
diff --git a/ar/acplex.l b/ar/acplex.l
index 3100009fbb10..cde256f96499 100644
--- a/ar/acplex.l
+++ b/ar/acplex.l
@@ -34,7 +34,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: acplex.l 2130 2011-11-10 06:56:46Z jkoshy $");
+ELFTC_VCSID("$Id: acplex.l 3162 2015-02-15 21:43:41Z emaste $");
#include "acpyacc.h"
@@ -49,6 +49,7 @@ int yylex(void);
%}
+%option nounput
%option noyywrap
%%
diff --git a/ar/read.c b/ar/read.c
index 4e79ff2568ae..f047a430caef 100644
--- a/ar/read.c
+++ b/ar/read.c
@@ -39,7 +39,7 @@
#include "ar.h"
-ELFTC_VCSID("$Id: read.c 3102 2014-10-29 21:09:01Z jkoshy $");
+ELFTC_VCSID("$Id: read.c 3163 2015-02-15 21:43:51Z emaste $");
/*
* Handle read modes: 'x', 't' and 'p'.
@@ -90,7 +90,8 @@ ar_read_archive(struct bsdar *bsdar, int mode)
else
bsdar->options &= ~AR_BSD;
- name = archive_entry_pathname(entry);
+ if ((name = archive_entry_pathname(entry)) == NULL)
+ break;
/* Skip pseudo members. */
if (bsdar_is_pseudomember(bsdar, name))
diff --git a/common/_elftc.h b/common/_elftc.h
index 0b8c77c09115..d6c878402747 100644
--- a/common/_elftc.h
+++ b/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 2922 2013-03-17 22:53:15Z kaiwang27 $
+ * $Id: _elftc.h 3139 2015-01-05 03:17:06Z kaiwang27 $
*/
/**
@@ -76,10 +76,17 @@
* SUCH DAMAGE.
*/
+#ifndef LIST_FOREACH_SAFE
+#define LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = LIST_FIRST((head)); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
+#endif
+
#ifndef SLIST_FOREACH_SAFE
-#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SLIST_FIRST((head)); \
- (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
+#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = SLIST_FIRST((head)); \
+ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
(var) = (tvar))
#endif
diff --git a/common/elfdefinitions.h b/common/elfdefinitions.h
index f63dc7f2178d..f0a2fc2dade5 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 3110 2014-12-20 08:32:46Z kaiwang27 $
+ * $Id: elfdefinitions.h 3149 2015-02-15 19:00:06Z emaste $
*/
/*
@@ -1396,6 +1396,12 @@ _ELF_DEFINE_RELOC(R_386_8, 22) \
_ELF_DEFINE_RELOC(R_386_PC8, 23)
/*
+ */
+#define _ELF_DEFINE_AARCH64_RELOCATIONS() \
+_ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \
+_ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \
+
+/*
* These are the symbols used in the Sun ``Linkers and Loaders
* Guide'', Document No: 817-1984-17. See the X86_64 relocations list
* below for the spellings used in the ELF specification.
@@ -1948,14 +1954,21 @@ _ELF_DEFINE_RELOC(R_X86_64_TPOFF32, 23) \
_ELF_DEFINE_RELOC(R_X86_64_PC64, 24) \
_ELF_DEFINE_RELOC(R_X86_64_GOTOFF64, 25) \
_ELF_DEFINE_RELOC(R_X86_64_GOTPC32, 26) \
+_ELF_DEFINE_RELOC(R_X86_64_GOT64, 27) \
+_ELF_DEFINE_RELOC(R_X86_64_GOTPCREL64, 28) \
+_ELF_DEFINE_RELOC(R_X86_64_GOTPC64, 29) \
+_ELF_DEFINE_RELOC(R_X86_64_GOTPLT64, 30) \
+_ELF_DEFINE_RELOC(R_X86_64_PLTOFF64, 31) \
_ELF_DEFINE_RELOC(R_X86_64_SIZE32, 32) \
_ELF_DEFINE_RELOC(R_X86_64_SIZE64, 33) \
_ELF_DEFINE_RELOC(R_X86_64_GOTPC32_TLSDESC, 34) \
_ELF_DEFINE_RELOC(R_X86_64_TLSDESC_CALL, 35) \
-_ELF_DEFINE_RELOC(R_X86_64_TLSDESC, 36)
+_ELF_DEFINE_RELOC(R_X86_64_TLSDESC, 36) \
+_ELF_DEFINE_RELOC(R_X86_64_IRELATIVE, 37)
#define _ELF_DEFINE_RELOCATIONS() \
_ELF_DEFINE_386_RELOCATIONS() \
+_ELF_DEFINE_AARCH64_RELOCATIONS() \
_ELF_DEFINE_AMD64_RELOCATIONS() \
_ELF_DEFINE_ARM_RELOCATIONS() \
_ELF_DEFINE_IA64_RELOCATIONS() \
diff --git a/elfcopy/main.c b/elfcopy/main.c
index 0ba4e6864c86..e5bea86fb6fa 100644
--- a/elfcopy/main.c
+++ b/elfcopy/main.c
@@ -40,7 +40,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: main.c 3111 2014-12-20 08:33:01Z kaiwang27 $");
+ELFTC_VCSID("$Id: main.c 3156 2015-02-15 21:40:01Z emaste $");
enum options
{
@@ -210,7 +210,7 @@ static struct {
};
static int copy_from_tempfile(const char *src, const char *dst,
- int infd, int *outfd);
+ int infd, int *outfd, int in_place);
static void create_file(struct elfcopy *ecp, const char *src,
const char *dst);
static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv);
@@ -523,33 +523,39 @@ create_tempfile(char **fn, int *fd)
#undef _TEMPFILEPATH
}
+/*
+ * Copy temporary file with path src and file descriptor infd to path dst.
+ * If in_place is set act as if editing the file in place, avoiding rename()
+ * to preserve hard and symbolic links. Output file remains open, with file
+ * descriptor returned in outfd.
+ */
static int
-copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd)
+copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd,
+ int in_place)
{
int tmpfd;
/*
* First, check if we can use rename().
*/
- if (rename(src, dst) >= 0) {
- *outfd = infd;
- return (0);
- } else if (errno != EXDEV)
- return (-1);
-
- /*
- * If the rename() failed due to 'src' and 'dst' residing in
- * two different file systems, invoke a helper function in
- * libelftc to do the copy.
- */
-
- if (unlink(dst) < 0)
- return (-1);
+ if (in_place == 0) {
+ if (rename(src, dst) >= 0) {
+ *outfd = infd;
+ return (0);
+ } else if (errno != EXDEV)
+ return (-1);
+
+ /*
+ * If the rename() failed due to 'src' and 'dst' residing in
+ * two different file systems, invoke a helper function in
+ * libelftc to do the copy.
+ */
- if ((tmpfd = open(dst, O_CREAT | O_WRONLY, 0755)) < 0)
- return (-1);
+ if (unlink(dst) < 0)
+ return (-1);
+ }
- if (lseek(infd, 0, SEEK_SET) < 0)
+ if ((tmpfd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, 0755)) < 0)
return (-1);
if (elftc_copyfile(infd, tmpfd) < 0)
@@ -578,6 +584,7 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst)
struct stat sb;
char *tempfile, *elftemp;
int efd, ifd, ofd, ofd0, tfd;
+ int in_place;
tempfile = NULL;
@@ -718,10 +725,15 @@ copy_done:
#endif
if (tempfile != NULL) {
- if (dst == NULL)
+ in_place = 0;
+ if (dst == NULL) {
dst = src;
+ if (lstat(dst, &sb) != -1 &&
+ (sb.st_nlink > 1 || S_ISLNK(sb.st_mode)))
+ in_place = 1;
+ }
- if (copy_from_tempfile(tempfile, dst, ofd, &tfd) < 0)
+ if (copy_from_tempfile(tempfile, dst, ofd, &tfd, in_place) < 0)
err(EXIT_FAILURE, "creation of %s failed", dst);
free(tempfile);
diff --git a/elfcopy/sections.c b/elfcopy/sections.c
index 6c733f8a0f81..ee6d17278ee6 100644
--- a/elfcopy/sections.c
+++ b/elfcopy/sections.c
@@ -35,7 +35,7 @@
#include "elfcopy.h"
-ELFTC_VCSID("$Id: sections.c 3134 2014-12-23 10:43:59Z kaiwang27 $");
+ELFTC_VCSID("$Id: sections.c 3150 2015-02-15 19:07:46Z emaste $");
static void add_gnu_debuglink(struct elfcopy *ecp);
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@@ -777,6 +777,8 @@ resync_sections(struct elfcopy *ecp)
continue;
/* Align section offset. */
+ if (s->align == 0)
+ s->align = 1;
if (off <= s->off) {
if (!s->loadable)
s->off = roundup(off, s->align);
diff --git a/elfdump/elfdump.c b/elfdump/elfdump.c
index 1d62af723eb8..f7fc42644232 100644
--- a/elfdump/elfdump.c
+++ b/elfdump/elfdump.c
@@ -51,7 +51,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: elfdump.c 2728 2012-12-09 16:54:28Z kaiwang27 $");
+ELFTC_VCSID("$Id: elfdump.c 3146 2015-02-15 18:20:03Z emaste $");
#if defined(ELFTC_NEED_ELF_NOTE_DEFINITION)
#include "native-elf-format.h"
@@ -975,12 +975,11 @@ ac_detect_ar(int fd)
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, fd, 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);
}
@@ -1005,7 +1004,6 @@ ac_print_ar(struct elfdump *ed, int fd)
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, fd, 10240));
for(;;) {
@@ -1082,7 +1080,7 @@ ac_print_ar(struct elfdump *ed, int fd)
/* No need to continue if we only dump ARSYM. */
if (ed->flags & ONLY_ARSYM) {
AC(archive_read_close(a));
- AC(archive_read_finish(a));
+ AC(archive_read_free(a));
return;
}
continue;
@@ -1102,7 +1100,7 @@ ac_print_ar(struct elfdump *ed, int fd)
free(buff);
}
AC(archive_read_close(a));
- AC(archive_read_finish(a));
+ AC(archive_read_free(a));
}
#else /* USE_LIBARCHIVE_AR */
diff --git a/libdwarf/_libdwarf.h b/libdwarf/_libdwarf.h
index d2e74c15687a..06413beeb583 100644
--- a/libdwarf/_libdwarf.h
+++ b/libdwarf/_libdwarf.h
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libdwarf.h 3106 2014-12-19 16:00:58Z kaiwang27 $
+ * $Id: _libdwarf.h 3161 2015-02-15 21:43:36Z emaste $
*/
#ifndef __LIBDWARF_H_
@@ -49,7 +49,7 @@
struct _libdwarf_globals {
Dwarf_Handler errhand;
Dwarf_Ptr errarg;
- int applyrela;
+ int applyreloc;
};
extern struct _libdwarf_globals _libdwarf;
diff --git a/libdwarf/dwarf_attrval.c b/libdwarf/dwarf_attrval.c
index 3bddae9eceff..0dd38a491d84 100644
--- a/libdwarf/dwarf_attrval.c
+++ b/libdwarf/dwarf_attrval.c
@@ -26,7 +26,7 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: dwarf_attrval.c 2977 2014-01-21 20:13:31Z kaiwang27 $");
+ELFTC_VCSID("$Id: dwarf_attrval.c 3159 2015-02-15 21:43:27Z emaste $");
int
dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err)
@@ -125,6 +125,7 @@ dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_E
break;
case DW_FORM_data4:
*valp = (int32_t) at->u[0].s64;
+ break;
case DW_FORM_data8:
case DW_FORM_sdata:
*valp = at->u[0].s64;
diff --git a/libdwarf/dwarf_get_AT_name.3 b/libdwarf/dwarf_get_AT_name.3
index 5b5d5a1167a8..473adc331f3f 100644
--- a/libdwarf/dwarf_get_AT_name.3
+++ b/libdwarf/dwarf_get_AT_name.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: dwarf_get_AT_name.3 2071 2011-10-27 03:20:00Z jkoshy $
+.\" $Id: dwarf_get_AT_name.3 3142 2015-01-29 23:11:14Z jkoshy $
.\"
.Dd April 22, 2011
.Os
@@ -247,6 +247,7 @@ constants.
.It Fn dwarf_get_VIS_name
.Dv DW_VIS_*
constants.
+.El
.Sh RETURN VALUES
These functions return
.Dv DW_DLV_OK on success.
diff --git a/libdwarf/dwarf_get_arange_info.3 b/libdwarf/dwarf_get_arange_info.3
index e8dac7810a0d..3878edde19bb 100644
--- a/libdwarf/dwarf_get_arange_info.3
+++ b/libdwarf/dwarf_get_arange_info.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: dwarf_get_arange_info.3 2134 2011-11-10 08:40:14Z jkoshy $
+.\" $Id: dwarf_get_arange_info.3 3142 2015-01-29 23:11:14Z jkoshy $
.\"
.Dd April 16, 2011
.Os
@@ -102,6 +102,7 @@ One of the arguments
or
.Ar cu_die_offset
was NULL.
+.El
.Sh EXAMPLE
To loop through all the address lookup table entries, use:
.Bd -literal -offset indent
diff --git a/libdwarf/dwarf_get_section_max_offsets.3 b/libdwarf/dwarf_get_section_max_offsets.3
index 6f79341cd367..963d4ac3814e 100644
--- a/libdwarf/dwarf_get_section_max_offsets.3
+++ b/libdwarf/dwarf_get_section_max_offsets.3
@@ -22,9 +22,9 @@
.\" 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 $
+.\" $Id: dwarf_get_section_max_offsets.3 3141 2015-01-29 23:11:10Z jkoshy $
.\"
-.Dd July 27, 2014
+.Dd December 21, 2014
.Os
.Dt DWARF_GET_SECTION_MAX_OFFSETS
.Sh NAME
@@ -101,7 +101,7 @@ 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
+and thus cannot return the size of the
.Dq \&.debug_types
section.
.Sh RETURN VALUES
diff --git a/libdwarf/dwarf_hasattr.3 b/libdwarf/dwarf_hasattr.3
index 5b4699bd7778..58758482d318 100644
--- a/libdwarf/dwarf_hasattr.3
+++ b/libdwarf/dwarf_hasattr.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: dwarf_hasattr.3 2073 2011-10-27 03:30:47Z jkoshy $
+.\" $Id: dwarf_hasattr.3 3142 2015-01-29 23:11:14Z jkoshy $
.\"
.Dd April 17, 2010
.Os
@@ -85,6 +85,7 @@ Either of argument
or
.Va ret_bool
was NULL.
+.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,
diff --git a/libdwarf/dwarf_reloc.c b/libdwarf/dwarf_reloc.c
index 5e96db3c6fd8..0430e4db49ce 100644
--- a/libdwarf/dwarf_reloc.c
+++ b/libdwarf/dwarf_reloc.c
@@ -26,15 +26,15 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: dwarf_reloc.c 2075 2011-10-27 03:47:28Z jkoshy $");
+ELFTC_VCSID("$Id: dwarf_reloc.c 3161 2015-02-15 21:43:36Z emaste $");
int
dwarf_set_reloc_application(int apply)
{
int oldapply;
- oldapply = _libdwarf.applyrela;
- _libdwarf.applyrela = apply;
+ oldapply = _libdwarf.applyreloc;
+ _libdwarf.applyreloc = apply;
return (oldapply);
}
diff --git a/libdwarf/dwarf_set_reloc_application.3 b/libdwarf/dwarf_set_reloc_application.3
index d53c746d1be2..db40cbb2522a 100644
--- a/libdwarf/dwarf_set_reloc_application.3
+++ b/libdwarf/dwarf_set_reloc_application.3
@@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: dwarf_set_reloc_application.3 2075 2011-10-27 03:47:28Z jkoshy $
+.\" $Id: dwarf_set_reloc_application.3 3161 2015-02-15 21:43:36Z emaste $
.\"
-.Dd June 26, 2011
+.Dd February 11, 2015
.Os
.Dt DWARF_SET_RELOC_APPLICATION 3
.Sh NAME
@@ -47,6 +47,8 @@ handled by the DWARF(3) library.
If the argument
.Ar apply
holds a non-zero value, the library will process all the relevant
+.Dq ".rel"
+and
.Dq ".rela"
relocation sections and will apply the relocation records found to
their corresponding DWARF sections.
diff --git a/libdwarf/dwarf_whatattr.3 b/libdwarf/dwarf_whatattr.3
index 7c9a6d04bfcb..a975d3ec7d8a 100644
--- a/libdwarf/dwarf_whatattr.3
+++ b/libdwarf/dwarf_whatattr.3
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: dwarf_whatattr.3 2075 2011-10-27 03:47:28Z jkoshy $
+.\" $Id: dwarf_whatattr.3 3142 2015-01-29 23:11:14Z jkoshy $
.\"
.Dd May 22, 2010
.Os
@@ -72,6 +72,7 @@ Either of argument
or
.Va retcode
was NULL.
+.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,
diff --git a/libdwarf/libdwarf.c b/libdwarf/libdwarf.c
index 5f487624717f..b2406cb73fb9 100644
--- a/libdwarf/libdwarf.c
+++ b/libdwarf/libdwarf.c
@@ -26,10 +26,10 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: libdwarf.c 2070 2011-10-27 03:05:32Z jkoshy $");
+ELFTC_VCSID("$Id: libdwarf.c 3161 2015-02-15 21:43:36Z emaste $");
struct _libdwarf_globals _libdwarf = {
.errhand = NULL,
.errarg = NULL,
- .applyrela = 1
+ .applyreloc = 1
};
diff --git a/libdwarf/libdwarf.h b/libdwarf/libdwarf.h
index 9a4a89984769..fdbcb4e05b63 100644
--- a/libdwarf/libdwarf.h
+++ b/libdwarf/libdwarf.h
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: libdwarf.h 3064 2014-06-06 19:35:55Z kaiwang27 $
+ * $Id: libdwarf.h 3149 2015-02-15 19:00:06Z emaste $
*/
#ifndef _LIBDWARF_H_
@@ -439,6 +439,7 @@ enum Dwarf_ISA {
DW_ISA_SPARC,
DW_ISA_X86,
DW_ISA_X86_64,
+ DW_ISA_AARCH64,
DW_ISA_MAX
};
diff --git a/libdwarf/libdwarf_elf_init.c b/libdwarf/libdwarf_elf_init.c
index 1e374f2d793e..af2d370b980c 100644
--- a/libdwarf/libdwarf_elf_init.c
+++ b/libdwarf/libdwarf_elf_init.c
@@ -26,7 +26,7 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: libdwarf_elf_init.c 2972 2013-12-23 06:46:04Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_elf_init.c 3161 2015-02-15 21:43:36Z emaste $");
static const char *debug_name[] = {
".debug_abbrev",
@@ -50,32 +50,46 @@ static const char *debug_name[] = {
};
static void
-_dwarf_elf_apply_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
- Elf_Data *symtab_data, int endian)
+_dwarf_elf_write_reloc(Dwarf_Debug dbg, Elf_Data *symtab_data, int endian,
+ void *buf, uint64_t offset, GElf_Xword r_info, GElf_Sxword r_addend)
{
- Dwarf_Unsigned type;
- GElf_Rela rela;
GElf_Sym sym;
- size_t symndx;
- uint64_t offset;
- int size, j;
+ int size;
+
+ if (gelf_getsym(symtab_data, GELF_R_SYM(r_info), &sym) == NULL)
+ return;
+ if ((size = _dwarf_get_reloc_size(dbg, GELF_R_TYPE(r_info))) == 0)
+ return; /* Unknown or non-absolute relocation. */
+ if (endian == ELFDATA2MSB)
+ _dwarf_write_msb(buf, &offset, sym.st_value + r_addend, size);
+ else
+ _dwarf_write_lsb(buf, &offset, sym.st_value + r_addend, size);
+}
- j = 0;
- while (gelf_getrela(rel_data, j++, &rela) != NULL) {
- symndx = GELF_R_SYM(rela.r_info);
- type = GELF_R_TYPE(rela.r_info);
+static void
+_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
+ Elf_Data *symtab_data, int endian)
+{
+ GElf_Rel rel;
+ int j;
- if (gelf_getsym(symtab_data, symndx, &sym) == NULL)
- continue;
+ j = 0;
+ while (gelf_getrel(rel_data, j++, &rel) != NULL)
+ _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
+ rel.r_offset, rel.r_info, 0);
+}
- offset = rela.r_offset;
- size = _dwarf_get_reloc_size(dbg, type);
+static void
+_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
+ Elf_Data *symtab_data, int endian)
+{
+ GElf_Rela rela;
+ int j;
- if (endian == ELFDATA2MSB)
- _dwarf_write_msb(buf, &offset, rela.r_addend, size);
- else
- _dwarf_write_lsb(buf, &offset, rela.r_addend, size);
- }
+ j = 0;
+ while (gelf_getrela(rel_data, j++, &rela) != NULL)
+ _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
+ rela.r_offset, rela.r_info, rela.r_addend);
}
static int
@@ -104,7 +118,8 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
return (DW_DLE_ELF);
}
- if (sh.sh_type != SHT_RELA || sh.sh_size == 0)
+ if ((sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA) ||
+ sh.sh_size == 0)
continue;
if (sh.sh_info == shndx && sh.sh_link == symtab) {
@@ -125,8 +140,12 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
}
memcpy(ed->ed_alloc, ed->ed_data->d_buf,
ed->ed_data->d_size);
- _dwarf_elf_apply_reloc(dbg, ed->ed_alloc, rel,
- symtab_data, eh.e_ident[EI_DATA]);
+ if (sh.sh_type == SHT_REL)
+ _dwarf_elf_apply_rel_reloc(dbg, ed->ed_alloc,
+ rel, symtab_data, eh.e_ident[EI_DATA]);
+ else
+ _dwarf_elf_apply_rela_reloc(dbg, ed->ed_alloc,
+ rel, symtab_data, eh.e_ident[EI_DATA]);
return (DW_DLE_NONE);
}
@@ -282,7 +301,7 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error)
}
}
- if (_libdwarf.applyrela) {
+ if (_libdwarf.applyreloc) {
if (_dwarf_elf_relocate(dbg, elf,
&e->eo_data[j], elf_ndxscn(scn), symtab_ndx,
symtab_data, error) != DW_DLE_NONE)
diff --git a/libdwarf/libdwarf_reloc.c b/libdwarf/libdwarf_reloc.c
index ea916772aadb..96bb785845fe 100644
--- a/libdwarf/libdwarf_reloc.c
+++ b/libdwarf/libdwarf_reloc.c
@@ -26,7 +26,7 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: libdwarf_reloc.c 2948 2013-05-30 21:25:52Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_reloc.c 3149 2015-02-15 19:00:06Z emaste $");
Dwarf_Unsigned
_dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
@@ -35,6 +35,8 @@ _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64)
assert(dbg != NULL);
switch (dbg->dbgp_isa) {
+ case DW_ISA_AARCH64:
+ return (is64 ? R_AARCH64_ABS64 : R_AARCH64_ABS32);
case DW_ISA_X86:
return (R_386_32);
case DW_ISA_X86_64:
@@ -62,6 +64,12 @@ _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type)
switch (dbg->dbg_machine) {
case EM_NONE:
break;
+ case EM_AARCH64:
+ if (rel_type == R_AARCH64_ABS32)
+ return (4);
+ else if (rel_type == R_AARCH64_ABS64)
+ return (8);
+ break;
case EM_ARM:
if (rel_type == R_ARM_ABS32)
return (4);
diff --git a/libelf/_libelf_config.h b/libelf/_libelf_config.h
index b9442fdc81d0..45d8714b2ae6 100644
--- a/libelf/_libelf_config.h
+++ b/libelf/_libelf_config.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: _libelf_config.h 2287 2011-12-04 06:45:47Z jkoshy $
+ * $Id: _libelf_config.h 3143 2015-02-15 17:57:38Z emaste $
*/
#ifdef __DragonFly__
@@ -53,6 +53,12 @@
#define LIBELF_BYTEORDER ELFDATA2LSB
#define LIBELF_CLASS ELFCLASS64
+#elif defined(__aarch64__)
+
+#define LIBELF_ARCH EM_AARCH64
+#define LIBELF_BYTEORDER ELFDATA2LSB
+#define LIBELF_CLASS ELFCLASS64
+
#elif defined(__arm__)
#define LIBELF_ARCH EM_ARM
diff --git a/libelf/elf.3 b/libelf/elf.3
index 97677eb205d6..618b4f7d92ab 100644
--- a/libelf/elf.3
+++ b/libelf/elf.3
@@ -21,7 +21,7 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
-.\" $Id: elf.3 3082 2014-07-28 09:13:33Z jkoshy $
+.\" $Id: elf.3 3142 2015-01-29 23:11:14Z jkoshy $
.\"
.Dd July 28, 2014
.Os
@@ -413,7 +413,6 @@ Section types in the range
.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
in the ELF library.
diff --git a/libelf/elf_scn.c b/libelf/elf_scn.c
index f80711579d59..f07f6ae9ea16 100644
--- a/libelf/elf_scn.c
+++ b/libelf/elf_scn.c
@@ -36,7 +36,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: elf_scn.c 3013 2014-03-23 06:16:59Z jkoshy $");
+ELFTC_VCSID("$Id: elf_scn.c 3147 2015-02-15 18:45:23Z emaste $");
/*
* Load an ELF section table and create a list of Elf_Scn structures.
@@ -59,8 +59,10 @@ _libelf_load_section_headers(Elf *e, void *ehdr)
assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0);
#define CHECK_EHDR(E,EH) do { \
- if (fsz != (EH)->e_shentsize || \
- shoff + fsz * shnum > e->e_rawsize) { \
+ if (shoff > e->e_rawsize || \
+ fsz != (EH)->e_shentsize || \
+ shnum > SIZE_MAX / fsz || \
+ fsz * shnum > e->e_rawsize - shoff) { \
LIBELF_SET_ERROR(HEADER, 0); \
return (0); \
} \
diff --git a/libelf/libelf_ar_util.c b/libelf/libelf_ar_util.c
index 7e6ec4068f69..7b824fb579a9 100644
--- a/libelf/libelf_ar_util.c
+++ b/libelf/libelf_ar_util.c
@@ -34,7 +34,7 @@
#include "_libelf.h"
#include "_libelf_ar.h"
-ELFTC_VCSID("$Id: libelf_ar_util.c 3013 2014-03-23 06:16:59Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_ar_util.c 3157 2015-02-15 21:42:02Z emaste $");
/*
* Convert a string bounded by `start' and `start+sz' (exclusive) to a
@@ -278,8 +278,8 @@ _libelf_ar_open(Elf *e, int reporterror)
* Handle special archive members for the SVR4 format.
*/
if (arh.ar_name[0] == '/') {
-
- assert(sz > 0);
+ if (sz == 0)
+ goto error;
e->e_flags |= LIBELF_F_AR_VARIANT_SVR4;
diff --git a/libelf/libelf_convert.m4 b/libelf/libelf_convert.m4
index fc9cf394a24d..f400367c3619 100644
--- a/libelf/libelf_convert.m4
+++ b/libelf/libelf_convert.m4
@@ -32,7 +32,7 @@
#include "_libelf.h"
-ELFTC_VCSID("$Id: libelf_convert.m4 3009 2014-03-23 01:49:59Z jkoshy $");
+ELFTC_VCSID("$Id: libelf_convert.m4 3158 2015-02-15 21:42:07Z emaste $");
/* WARNING: GENERATED FROM __file__. */
@@ -1007,6 +1007,11 @@ _libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src,
descsz = en->n_descsz;
type = en->n_type;
+ sz = namesz;
+ ROUNDUP2(sz, 4U);
+ sz += descsz;
+ ROUNDUP2(sz, 4U);
+
SWAP_WORD(namesz);
SWAP_WORD(descsz);
SWAP_WORD(type);
@@ -1017,11 +1022,6 @@ _libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src,
src += sizeof(Elf_Note);
- ROUNDUP2(namesz, 4U);
- ROUNDUP2(descsz, 4U);
-
- sz = namesz + descsz;
-
if (count < sz)
sz = count;
diff --git a/nm/nm.1 b/nm/nm.1
index 0ae9a22a6afa..35439e47fa11 100644
--- a/nm/nm.1
+++ b/nm/nm.1
@@ -22,9 +22,9 @@
.\" (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: nm.1 2377 2012-01-03 07:10:59Z jkoshy $
+.\" $Id: nm.1 3145 2015-02-15 18:04:37Z emaste $
.\"
-.Dd January 3, 2012
+.Dd February 15, 2015
.Os
.Dt NM 1
.Sh NAME
@@ -36,6 +36,7 @@
.Op Fl -defined-only
.Op Fl -demangle Ns Op = Ns style
.Op Fl -dynamic
+.Op Fl -extern-only
.Op Fl -help
.Op Fl -line-numbers
.Op Fl -no-demangle
@@ -107,6 +108,8 @@ is not specified, it is taken to be
.It Fl -dynamic
Only display dynamic symbols.
This option is only meaningful for shared libraries.
+.It Fl -extern-only
+Only display information about global (external) symbols.
.It Fl -help
Display a help message and exit.
.It Fl -format Ns = Ns Ar format
@@ -200,7 +203,8 @@ Only display information for global and static symbols.
.It Fl f
Produce full output (default).
.It Fl g
-Only display information about global (external) symbols.
+Equivalent to specifying option
+.Fl -extern-only .
.It Fl h
Equivalent to specifying option
.Fl -help .
diff --git a/nm/nm.c b/nm/nm.c
index 9afe0baa9b63..f9849660f659 100644
--- a/nm/nm.c
+++ b/nm/nm.c
@@ -48,7 +48,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: nm.c 3124 2014-12-21 05:46:28Z kaiwang27 $");
+ELFTC_VCSID("$Id: nm.c 3145 2015-02-15 18:04:37Z emaste $");
/* symbol information list */
STAILQ_HEAD(sym_head, sym_entry);
@@ -248,6 +248,7 @@ static const struct option nm_longopts[] = {
{ "defined-only", no_argument, &nm_opts.def_only, 1},
{ "demangle", optional_argument, NULL, 'C' },
{ "dynamic", no_argument, NULL, 'D' },
+ { "extern-only", no_argument, NULL, 'g' },
{ "format", required_argument, NULL, 'F' },
{ "help", no_argument, NULL, 'h' },
{ "line-numbers", no_argument, NULL, 'l' },
@@ -2042,7 +2043,7 @@ usage(int exitcode)
\n -f Produce full output (default).\
\n --format=format Display output in specific format. Allowed\
\n formats are: \"bsd\", \"posix\" and \"sysv\".\
-\n -g Display only global symbol information.\
+\n -g, --extern-only Display only global symbol information.\
\n -h, --help Show this help message.\
\n -l, --line-numbers Display filename and linenumber using\
\n debugging information.\
diff --git a/readelf/readelf.c b/readelf/readelf.c
index 16159ad09ea9..775172646ffa 100644
--- a/readelf/readelf.c
+++ b/readelf/readelf.c
@@ -46,7 +46,7 @@
#include "_elftc.h"
-ELFTC_VCSID("$Id: readelf.c 3110 2014-12-20 08:32:46Z kaiwang27 $");
+ELFTC_VCSID("$Id: readelf.c 3155 2015-02-15 19:15:57Z emaste $");
/*
* readelf(1) options.
@@ -320,8 +320,15 @@ 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);
static void load_sections(struct readelf *re);
static const char *mips_abi_fp(uint64_t fp);
-static const char *note_type(unsigned int osabi, unsigned int et,
+static const char *note_type(const char *note_name, unsigned int et,
unsigned int nt);
+static const char *note_type_freebsd(unsigned int nt);
+static const char *note_type_freebsd_core(unsigned int nt);
+static const char *note_type_linux_core(unsigned int nt);
+static const char *note_type_gnu(unsigned int nt);
+static const char *note_type_netbsd(unsigned int nt);
+static const char *note_type_openbsd(unsigned int nt);
+static const char *note_type_unknown(unsigned int nt);
static const char *option_kind(uint8_t kind);
static const char *phdr_type(unsigned int ptype);
static const char *ppc_abi_fp(uint64_t fp);
@@ -1472,6 +1479,20 @@ r_type(unsigned int mach, unsigned int type)
case 21: return "R_X86_64_DTPOFF32";
case 22: return "R_X86_64_GOTTPOFF";
case 23: return "R_X86_64_TPOFF32";
+ case 24: return "R_X86_64_PC64";
+ case 25: return "R_X86_64_GOTOFF64";
+ case 26: return "R_X86_64_GOTPC32";
+ case 27: return "R_X86_64_GOT64";
+ case 28: return "R_X86_64_GOTPCREL64";
+ case 29: return "R_X86_64_GOTPC64";
+ case 30: return "R_X86_64_GOTPLT64";
+ case 31: return "R_X86_64_PLTOFF64";
+ case 32: return "R_X86_64_SIZE32";
+ case 33: return "R_X86_64_SIZE64";
+ case 34: return "R_X86_64_GOTPC32_TLSDESC";
+ case 35: return "R_X86_64_TLSDESC_CALL";
+ case 36: return "R_X86_64_TLSDESC";
+ case 37: return "R_X86_64_IRELATIVE";
default: return "";
}
default: return "";
@@ -1479,62 +1500,130 @@ r_type(unsigned int mach, unsigned int type)
}
static const char *
-note_type(unsigned int osabi, unsigned int et, unsigned int nt)
+note_type(const char *name, unsigned int et, unsigned int nt)
+{
+ if ((strcmp(name, "CORE") == 0 || strcmp(name, "LINUX") == 0) &&
+ et == ET_CORE)
+ return note_type_linux_core(nt);
+ else if (strcmp(name, "FreeBSD") == 0)
+ if (et == ET_CORE)
+ return note_type_freebsd_core(nt);
+ else
+ return note_type_freebsd(nt);
+ else if (strcmp(name, "GNU") == 0 && et != ET_CORE)
+ return note_type_gnu(nt);
+ else if (strcmp(name, "NetBSD") == 0 && et != ET_CORE)
+ return note_type_netbsd(nt);
+ else if (strcmp(name, "OpenBSD") == 0 && et != ET_CORE)
+ return note_type_openbsd(nt);
+ return note_type_unknown(nt);
+}
+
+static const char *
+note_type_freebsd(unsigned int nt)
{
- static char s_nt[32];
+ switch (nt) {
+ case 1: return "NT_FREEBSD_ABI_TAG";
+ case 2: return "NT_FREEBSD_NOINIT_TAG";
+ case 3: return "NT_FREEBSD_ARCH_TAG";
+ default: return (note_type_unknown(nt));
+ }
+}
- if (et == ET_CORE) {
- switch (nt) {
- case NT_PRSTATUS:
- return "NT_PRSTATUS (Process status)";
- case NT_FPREGSET:
- return "NT_FPREGSET (Floating point information)";
- case NT_PRPSINFO:
- return "NT_PRPSINFO (Process information)";
- case NT_AUXV:
- return "NT_AUXV (Auxiliary vector)";
- case NT_PRXFPREG:
- return "NT_PRXFPREG (Linux user_xfpregs structure)";
- case NT_PSTATUS:
- return "NT_PSTATUS (Linux process status)";
- case NT_FPREGS:
- return "NT_FPREGS (Linux floating point regset)";
- case NT_PSINFO:
- return "NT_PSINFO (Linux process information)";
- case NT_LWPSTATUS:
- return "NT_LWPSTATUS (Linux lwpstatus_t type)";
- case NT_LWPSINFO:
- return "NT_LWPSINFO (Linux lwpinfo_t type)";
- default:
- snprintf(s_nt, sizeof(s_nt), "<unknown: %u>", nt);
- return (s_nt);
- }
- } else {
- switch (nt) {
- case NT_ABI_TAG:
- switch (osabi) {
- case ELFOSABI_FREEBSD:
- return "NT_FREEBSD_ABI_TAG";
- case ELFOSABI_NETBSD:
- return "NT_NETBSD_IDENT";
- case ELFOSABI_OPENBSD:
- return "NT_OPENBSD_IDENT";
- default:
- return "NT_GNU_ABI_TAG";
- }
- case NT_GNU_HWCAP:
- return "NT_GNU_HWCAP (Hardware capabilities)";
- case NT_GNU_BUILD_ID:
- return "NT_GNU_BUILD_ID (Build id set by ld(1))";
- case NT_GNU_GOLD_VERSION:
- return "NT_GNU_GOLD_VERSION (GNU gold version)";
- default:
- snprintf(s_nt, sizeof(s_nt), "<unknown: %u>", nt);
- return (s_nt);
- }
+static const char *
+note_type_freebsd_core(unsigned int nt)
+{
+ switch (nt) {
+ case 1: return "NT_PRSTATUS";
+ case 2: return "NT_FPREGSET";
+ case 3: return "NT_PRPSINFO";
+ case 7: return "NT_THRMISC";
+ case 8: return "NT_PROCSTAT_PROC";
+ case 9: return "NT_PROCSTAT_FILES";
+ case 10: return "NT_PROCSTAT_VMMAP";
+ case 11: return "NT_PROCSTAT_GROUPS";
+ case 12: return "NT_PROCSTAT_UMASK";
+ case 13: return "NT_PROCSTAT_RLIMIT";
+ case 14: return "NT_PROCSTAT_OSREL";
+ case 15: return "NT_PROCSTAT_PSSTRINGS";
+ case 16: return "NT_PROCSTAT_AUXV";
+ case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
+ default: return (note_type_unknown(nt));
+ }
+}
+
+static const char *
+note_type_linux_core(unsigned int nt)
+{
+ switch (nt) {
+ case 1: return "NT_PRSTATUS (Process status)";
+ case 2: return "NT_FPREGSET (Floating point information)";
+ case 3: return "NT_PRPSINFO (Process information)";
+ case 4: return "NT_TASKSTRUCT (Task structure)";
+ case 6: return "NT_AUXV (Auxiliary vector)";
+ case 10: return "NT_PSTATUS (Linux process status)";
+ case 12: return "NT_FPREGS (Linux floating point regset)";
+ case 13: return "NT_PSINFO (Linux process information)";
+ case 16: return "NT_LWPSTATUS (Linux lwpstatus_t type)";
+ case 17: return "NT_LWPSINFO (Linux lwpinfo_t type)";
+ case 18: return "NT_WIN32PSTATUS (win32_pstatus structure)";
+ case 0x100: return "NT_PPC_VMX (ppc Altivec registers)";
+ case 0x102: return "NT_PPC_VSX (ppc VSX registers)";
+ case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)";
+ case 0x300: return "NT_S390_HIGH_GPRS (s390 upper register halves)";
+ case 0x301: return "NT_S390_TIMER (s390 timer register)";
+ case 0x302: return "NT_S390_TODCMP (s390 TOD comparator register)";
+ case 0x303: return "NT_S390_TODPREG (s390 TOD programmable register)";
+ case 0x304: return "NT_S390_CTRS (s390 control registers)";
+ case 0x305: return "NT_S390_PREFIX (s390 prefix register)";
+ case 0x400: return "NT_ARM_VFP (arm VFP registers)";
+ case 0x46494c45UL: return "NT_FILE (mapped files)";
+ case 0x46E62B7FUL: return "NT_PRXFPREG (Linux user_xfpregs structure)";
+ case 0x53494749UL: return "NT_SIGINFO (siginfo_t data)";
+ default: return (note_type_unknown(nt));
+ }
+}
+
+static const char *
+note_type_gnu(unsigned int nt)
+{
+ switch (nt) {
+ case 1: return "NT_GNU_ABI_TAG";
+ case 2: return "NT_GNU_HWCAP (Hardware capabilities)";
+ case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))";
+ case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)";
+ default: return (note_type_unknown(nt));
+ }
+}
+
+static const char *
+note_type_netbsd(unsigned int nt)
+{
+ switch (nt) {
+ case 1: return "NT_NETBSD_IDENT";
+ default: return (note_type_unknown(nt));
}
}
+static const char *
+note_type_openbsd(unsigned int nt)
+{
+ switch (nt) {
+ case 1: return "NT_OPENBSD_IDENT";
+ default: return (note_type_unknown(nt));
+ }
+}
+
+static const char *
+note_type_unknown(unsigned int nt)
+{
+ static char s_nt[32];
+
+ snprintf(s_nt, sizeof(s_nt),
+ nt >= 0x100 ? "<unknown: 0x%x>" : "<unknown: %u>", nt);
+ return (s_nt);
+}
+
static struct {
const char *name;
int value;
@@ -3080,6 +3169,10 @@ 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) {
@@ -3132,6 +3225,10 @@ 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) {
@@ -3579,25 +3676,38 @@ static void
dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off)
{
Elf_Note *note;
- const char *end;
+ const char *end, *name;
printf("\nNotes at offset %#010jx with length %#010jx:\n",
(uintmax_t) off, (uintmax_t) sz);
printf(" %-13s %-15s %s\n", "Owner", "Data size", "Description");
end = buf + sz;
while (buf < end) {
+ if (buf + sizeof(*note) > end) {
+ warnx("invalid note header");
+ return;
+ }
note = (Elf_Note *)(uintptr_t) buf;
- printf(" %-13s %#010jx", (char *)(uintptr_t) (note + 1),
- (uintmax_t) note->n_descsz);
- printf(" %s\n", note_type(re->ehdr.e_ident[EI_OSABI],
- re->ehdr.e_type, note->n_type));
- buf += sizeof(Elf_Note);
- if (re->ec == ELFCLASS32)
- buf += roundup2(note->n_namesz, 4) +
- roundup2(note->n_descsz, 4);
- else
- buf += roundup2(note->n_namesz, 8) +
- roundup2(note->n_descsz, 8);
+ name = (char *)(uintptr_t)(note + 1);
+ /*
+ * The name field is required to be nul-terminated, and
+ * n_namesz includes the terminating nul in observed
+ * implementations (contrary to the ELF-64 spec). A special
+ * case is needed for cores generated by some older Linux
+ * versions, which write a note named "CORE" without a nul
+ * terminator and n_namesz = 4.
+ */
+ if (note->n_namesz == 0)
+ name = "";
+ else if (note->n_namesz == 4 && strncmp(name, "CORE", 4) == 0)
+ name = "CORE";
+ else if (strnlen(name, note->n_namesz) >= note->n_namesz)
+ name = "<invalid>";
+ printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz);
+ printf(" %s\n", note_type(name, re->ehdr.e_type,
+ note->n_type));
+ buf += sizeof(Elf_Note) + roundup2(note->n_namesz, 4) +
+ roundup2(note->n_descsz, 4);
}
}
@@ -4132,14 +4242,22 @@ dump_attributes(struct readelf *re)
len = d->d_size - 1;
p++;
while (len > 0) {
+ if (len < 4) {
+ warnx("truncated attribute section length");
+ break;
+ }
seclen = re->dw_decode(&p, 4);
if (seclen > len) {
warnx("invalid attribute section length");
break;
}
len -= seclen;
- printf("Attribute Section: %s\n", (char *) p);
nlen = strlen((char *) p) + 1;
+ if (nlen + 4 > seclen) {
+ warnx("invalid attribute section name");
+ break;
+ }
+ printf("Attribute Section: %s\n", (char *) p);
p += nlen;
seclen -= nlen + 4;
while (seclen > 0) {
@@ -6609,10 +6727,8 @@ load_sections(struct readelf *re)
return;
}
- if ((scn = elf_getscn(re->elf, 0)) == NULL) {
- warnx("elf_getscn failed: %s", elf_errmsg(-1));
+ if ((scn = elf_getscn(re->elf, 0)) == NULL)
return;
- }
(void) elf_errno();
do {