Import elftoolchain rev 3163

From svn.code.sf.net/p/elftoolchain/code
This commit is contained in:
Ed Maste 2015-02-17 14:34:11 +00:00
parent 42bfa111d7
commit d356830d3d
29 changed files with 372 additions and 173 deletions

View File

@ -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);

View File

@ -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
%%

View File

@ -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))

View File

@ -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

View File

@ -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 $
*/
/*
@ -1395,6 +1395,12 @@ _ELF_DEFINE_RELOC(R_386_PC16, 21) \
_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
@ -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() \

View File

@ -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 (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 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 (unlink(dst) < 0)
return (-1);
if ((tmpfd = open(dst, O_CREAT | O_WRONLY, 0755)) < 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 @@ create_file(struct elfcopy *ecp, const char *src, const char *dst)
#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);

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 ,

View File

@ -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);
}

View File

@ -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.

View File

@ -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 ,

View File

@ -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
};

View File

@ -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
};

View File

@ -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,
_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)
{
GElf_Sym sym;
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);
}
static void
_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
Elf_Data *symtab_data, int endian)
{
Dwarf_Unsigned type;
GElf_Rela rela;
GElf_Sym sym;
size_t symndx;
uint64_t offset;
int size, j;
GElf_Rel rel;
int j;
j = 0;
while (gelf_getrela(rel_data, j++, &rela) != NULL) {
symndx = GELF_R_SYM(rela.r_info);
type = GELF_R_TYPE(rela.r_info);
while (gelf_getrel(rel_data, j++, &rel) != NULL)
_dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
rel.r_offset, rel.r_info, 0);
}
if (gelf_getsym(symtab_data, symndx, &sym) == NULL)
continue;
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;
offset = rela.r_offset;
size = _dwarf_get_reloc_size(dbg, type);
if (endian == ELFDATA2MSB)
_dwarf_write_msb(buf, &offset, rela.r_addend, size);
else
_dwarf_write_lsb(buf, &offset, rela.r_addend, size);
}
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)

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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); \
} \

View File

@ -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;

View File

@ -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;

10
nm/nm.1
View File

@ -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 .

View File

@ -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.\

View File

@ -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,60 +1500,128 @@ 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)
{
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));
}
}
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];
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);
}
}
snprintf(s_nt, sizeof(s_nt),
nt >= 0x100 ? "<unknown: 0x%x>" : "<unknown: %u>", nt);
return (s_nt);
}
static struct {
@ -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 {