Update elftoolchain to upstream rev 3130

This includes a number of libdwarf improvements (particularly DWARF4
related) and updates to elftoolchain tools such as strip(1). It also
includes a large number of miscellaneous fixes (memory leaks, sign and
cast warnings, integer overflow and underflow, etc.).

This is a merge of r276167,276170-276172 from the
projects/elftoolchain-update-r3130 branch.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Ed Maste 2014-12-29 19:16:40 +00:00
commit b4e9f2392c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276371
94 changed files with 3138 additions and 1230 deletions

View file

@ -1,4 +1,4 @@
# $Id: Makefile 2606 2012-10-02 17:52:57Z jkoshy $
# $Id: Makefile 3022 2014-04-17 18:05:58Z jkoshy $
TOP= ..
@ -12,4 +12,7 @@ all depend obj:
clean clobber:
rm -f ${CLEANFILES}
cleandepend:
rm -f .depend
.include "${TOP}/mk/elftoolchain.inc.mk"

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 2950 2013-06-15 13:36:02Z jkoshy $
* $Id: elfdefinitions.h 3110 2014-12-20 08:32:46Z kaiwang27 $
*/
/*
@ -821,7 +821,8 @@ enum {
EM__LAST__
};
/* Older synonyms. */
/* Other synonyms. */
#define EM_AMD64 EM_X86_64
#define EM_ARC_A5 EM_ARC_COMPACT
/*
@ -2114,11 +2115,11 @@ typedef struct {
/* 64-bit entry. */
typedef struct {
Elf64_Word l_name;
Elf64_Word l_time_stamp;
Elf64_Word l_checksum;
Elf64_Word l_version;
Elf64_Word l_flags;
Elf64_Word l_name; /* The name of a shared object. */
Elf64_Word l_time_stamp; /* 32-bit timestamp. */
Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */
Elf64_Word l_version; /* Interface version string index. */
Elf64_Word l_flags; /* Flags (LL_*). */
} Elf64_Lib;
#define _ELF_DEFINE_LL_FLAGS() \
@ -2366,12 +2367,12 @@ typedef struct {
/* 64 bit PHDR entry. */
typedef struct {
Elf64_Word p_type; /* Type of segment. */
Elf64_Word p_flags; /* File offset to segment. */
Elf64_Off p_offset; /* Virtual address in memory. */
Elf64_Addr p_vaddr; /* Physical address (if relevant). */
Elf64_Addr p_paddr; /* Size of segment in file. */
Elf64_Xword p_filesz; /* Size of segment in memory. */
Elf64_Xword p_memsz; /* Segment flags. */
Elf64_Word p_flags; /* Segment flags. */
Elf64_Off p_offset; /* File offset to segment. */
Elf64_Addr p_vaddr; /* Virtual address in memory. */
Elf64_Addr p_paddr; /* Physical address (if relevant). */
Elf64_Xword p_filesz; /* Size of segment in file. */
Elf64_Xword p_memsz; /* Size of segment in memory. */
Elf64_Xword p_align; /* Alignment constraints. */
} Elf64_Phdr;
@ -2455,11 +2456,11 @@ typedef struct {
typedef struct {
Elf64_Word st_name; /* index of symbol's name */
unsigned char st_info; /* value for the symbol */
unsigned char st_other; /* size of associated data */
Elf64_Half st_shndx; /* type and binding attributes */
Elf64_Addr st_value; /* visibility */
Elf64_Xword st_size; /* index of related section */
unsigned char st_info; /* type and binding attributes */
unsigned char st_other; /* visibility */
Elf64_Half st_shndx; /* index of related section */
Elf64_Addr st_value; /* value for the symbol */
Elf64_Xword st_size; /* size of associated data */
} Elf64_Sym;
#define ELF32_ST_BIND(I) ((I) >> 4)

View file

@ -40,7 +40,7 @@
#include "elfcopy.h"
ELFTC_VCSID("$Id: archive.c 2370 2011-12-29 12:48:12Z jkoshy $");
ELFTC_VCSID("$Id: archive.c 3102 2014-10-29 21:09:01Z jkoshy $");
#define _ARMAG_LEN 8 /* length of ar magic string */
#define _ARHDR_LEN 60 /* length of ar header */
@ -350,7 +350,6 @@ ac_detect_ar(int ifd)
r = -1;
if ((a = archive_read_new()) == NULL)
return (0);
archive_read_support_filter_none(a);
archive_read_support_format_ar(a);
if (archive_read_open_fd(a, ifd, 10240) == ARCHIVE_OK)
r = archive_read_next_header(a, &entry);
@ -386,7 +385,6 @@ ac_read_objs(struct elfcopy *ecp, int ifd)
err(EXIT_FAILURE, "lseek failed");
if ((a = archive_read_new()) == NULL)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
archive_read_support_filter_none(a);
archive_read_support_format_ar(a);
AC(archive_read_open_fd(a, ifd, 10240));
for(;;) {
@ -449,7 +447,6 @@ ac_write_objs(struct elfcopy *ecp, int ofd)
if ((a = archive_write_new()) == NULL)
errx(EXIT_FAILURE, "%s", archive_error_string(a));
archive_write_set_format_ar_svr4(a);
archive_write_add_filter_none(a);
AC(archive_write_open_fd(a, ofd));
/* Write the archive symbol table, even if it's empty. */

View file

@ -40,7 +40,7 @@
#include "elfcopy.h"
ELFTC_VCSID("$Id: main.c 2970 2013-12-01 15:22:12Z kaiwang27 $");
ELFTC_VCSID("$Id: main.c 3111 2014-12-20 08:33:01Z kaiwang27 $");
enum options
{

View file

@ -35,7 +35,7 @@
#include "elfcopy.h"
ELFTC_VCSID("$Id: sections.c 2358 2011-12-19 18:22:32Z kaiwang27 $");
ELFTC_VCSID("$Id: sections.c 3126 2014-12-21 08:03:31Z kaiwang27 $");
static void add_gnu_debuglink(struct elfcopy *ecp);
static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
@ -372,6 +372,14 @@ create_scn(struct elfcopy *ecp)
is_remove_reloc_sec(ecp, ish.sh_info))
continue;
/*
* Section groups should be removed if symbol table will
* be removed. (section group's signature stored in symbol
* table)
*/
if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL)
continue;
/* Get section flags set by user. */
sec_flags = get_section_flags(ecp, name);

View file

@ -35,7 +35,7 @@
#include "elfcopy.h"
ELFTC_VCSID("$Id: segments.c 2542 2012-08-12 16:14:15Z kaiwang27 $");
ELFTC_VCSID("$Id: segments.c 3113 2014-12-20 08:33:29Z kaiwang27 $");
static void insert_to_inseg_list(struct segment *seg, struct section *sec);
@ -73,13 +73,15 @@ add_to_inseg_list(struct elfcopy *ecp, struct section *s)
*/
loadable = 0;
STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) {
if (s->off < seg->off)
if (s->off < seg->off || (s->vma < seg->addr && !s->pseudo))
continue;
if (s->off + s->sz > seg->off + seg->fsz &&
s->type != SHT_NOBITS)
continue;
if (s->off + s->sz > seg->off + seg->msz)
continue;
if (s->vma + s->sz > seg->addr + seg->msz)
continue;
insert_to_inseg_list(seg, s);
if (seg->type == PT_LOAD)
@ -97,7 +99,7 @@ adjust_addr(struct elfcopy *ecp)
struct section *s, *s0;
struct segment *seg;
struct sec_action *sac;
uint64_t dl, lma, old_vma, start, end;
uint64_t dl, lma, start, end;
int found, i;
/*
@ -114,8 +116,6 @@ adjust_addr(struct elfcopy *ecp)
s->lma += ecp->change_addr;
if (!s->pseudo) {
old_vma = s->vma;
/* Apply global VMA adjustment. */
if (ecp->change_addr != 0)
s->vma += ecp->change_addr;

View file

@ -34,7 +34,7 @@
#include "elfcopy.h"
ELFTC_VCSID("$Id: symbols.c 2971 2013-12-01 15:22:21Z kaiwang27 $");
ELFTC_VCSID("$Id: symbols.c 3019 2014-04-17 14:53:40Z jkoshy $");
/* Symbol table buffer structure. */
struct symbuf {
@ -300,7 +300,7 @@ generate_symbols(struct elfcopy *ecp)
GElf_Sym sym;
Elf_Data* id;
Elf_Scn *is;
size_t ishstrndx, namelen, ndx, nsyms, sc, symndx;
size_t ishstrndx, namelen, ndx, sc, symndx;
int ec, elferr, i;
if (elf_getshstrndx(ecp->ein, &ishstrndx) == 0)
@ -320,7 +320,6 @@ generate_symbols(struct elfcopy *ecp)
st_buf->lcap = 64;
st_buf->lsz = 1; /* '\0' at start. */
st_buf->gsz = 0;
nsyms = 0;
ecp->symtab->sz = 0;
ecp->strtab->sz = 0;

View file

@ -1,4 +1,4 @@
# $Id: Makefile 2937 2013-04-27 04:48:23Z jkoshy $
# $Id: Makefile 3097 2014-09-02 22:10:18Z kaiwang27 $
TOP= ${.CURDIR}/..
@ -42,6 +42,7 @@ SRCS= \
dwarf_pubtypes.c \
dwarf_ranges.c \
dwarf_reloc.c \
dwarf_sections.c \
dwarf_seterror.c \
dwarf_str.c \
dwarf_types.c \
@ -115,6 +116,7 @@ MAN= dwarf.3 \
dwarf_add_weakname.3 \
dwarf_attr.3 \
dwarf_attrlist.3 \
dwarf_attroffset.3 \
dwarf_attrval_signed.3 \
dwarf_child.3 \
dwarf_dealloc.3 \
@ -154,6 +156,7 @@ MAN= dwarf.3 \
dwarf_get_cie_info.3 \
dwarf_get_cie_of_fde.3 \
dwarf_get_cu_die_offset.3 \
dwarf_get_die_infotypes_flag.3 \
dwarf_get_elf.3 \
dwarf_get_fde_at_pc.3 \
dwarf_get_fde_info_for_all_regs.3 \
@ -175,6 +178,7 @@ MAN= dwarf.3 \
dwarf_get_relocation_info.3 \
dwarf_get_relocation_info_count.3 \
dwarf_get_section_bytes.3 \
dwarf_get_section_max_offsets.3 \
dwarf_get_str.3 \
dwarf_get_types.3 \
dwarf_get_vars.3 \
@ -192,6 +196,7 @@ MAN= dwarf.3 \
dwarf_new_expr.3 \
dwarf_new_fde.3 \
dwarf_next_cu_header.3 \
dwarf_next_types_section.3 \
dwarf_object_init.3 \
dwarf_producer_init.3 \
dwarf_producer_set_isa.3 \
@ -220,7 +225,9 @@ MLINKS+= \
dwarf_attrval_signed.3 dwarf_attrval_string.3 \
dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \
dwarf_child.3 dwarf_offdie.3 \
dwarf_child.3 dwarf_offdie_b.3 \
dwarf_child.3 dwarf_siblingof.3 \
dwarf_child.3 dwarf_siblingof_b.3 \
dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \
dwarf_dealloc.3 dwarf_funcs_dealloc.3 \
dwarf_dealloc.3 dwarf_globals_dealloc.3 \
@ -234,6 +241,7 @@ MLINKS+= \
dwarf_dieoffset.3 dwarf_die_CU_offset.3 \
dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \
dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \
dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset_b.3 \
dwarf_finish.3 dwarf_object_finish.3 \
dwarf_formref.3 dwarf_global_formref.3 \
dwarf_formudata.3 dwarf_formsdata.3 \
@ -273,6 +281,7 @@ MLINKS+= \
dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \
dwarf_get_pubtypes.3 dwarf_pubtypename.3 \
dwarf_get_ranges.3 dwarf_get_ranges_a.3 \
dwarf_get_section_max_offsets.3 dwarf_get_section_max_offsets_b.3 \
dwarf_get_types.3 dwarf_type_die_offset.3 \
dwarf_get_types.3 dwarf_type_cu_offset.3 \
dwarf_get_types.3 dwarf_type_name_offsets.3 \
@ -291,6 +300,7 @@ MLINKS+= \
dwarf_highpc.3 dwarf_bitoffset.3 \
dwarf_highpc.3 dwarf_bitsize.3 \
dwarf_highpc.3 dwarf_bytesize.3 \
dwarf_highpc.3 dwarf_highpc_b.3 \
dwarf_highpc.3 dwarf_lowpc.3 \
dwarf_highpc.3 dwarf_srclang.3 \
dwarf_lineno.3 dwarf_lineaddr.3 \
@ -302,6 +312,9 @@ MLINKS+= \
dwarf_lineno.3 dwarf_line_srcfileno.3 \
dwarf_loclist.3 dwarf_loclist_n.3 \
dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \
dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_b.3 \
dwarf_next_cu_header.3 dwarf_next_cu_header_b.3 \
dwarf_next_cu_header.3 dwarf_next_cu_header_c.3 \
dwarf_producer_init.3 dwarf_producer_init_b.3 \
dwarf_seterrarg.3 dwarf_seterrhand.3 \
dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \

View file

@ -1,4 +1,4 @@
/* $Id: Version.map 2576 2012-09-13 09:16:11Z jkoshy $ */
/* $Id: Version.map 3085 2014-09-02 22:08:23Z kaiwang27 $ */
R1.0 {
global:
@ -39,6 +39,7 @@ global:
dwarf_arrayorder;
dwarf_attr;
dwarf_attrlist;
dwarf_attroffset;
dwarf_attrval_flag;
dwarf_attrval_signed;
dwarf_attrval_string;
@ -116,6 +117,8 @@ global:
dwarf_get_cie_of_fde;
dwarf_get_cu_die_offset;
dwarf_get_cu_die_offset_given_cu_header_offset;
dwarf_get_cu_die_offset_given_cu_header_offset_b;
dwarf_get_die_infotypes_flag;
dwarf_get_elf;
dwarf_get_fde_at_pc;
dwarf_get_fde_info_for_all_regs3;
@ -139,6 +142,8 @@ global:
dwarf_get_relocation_info;
dwarf_get_relocation_info_count;
dwarf_get_section_bytes;
dwarf_get_section_max_offsets;
dwarf_get_section_max_offsets_b;
dwarf_get_str;
dwarf_get_types;
dwarf_get_vars;
@ -152,6 +157,7 @@ global:
dwarf_hasattr;
dwarf_hasform;
dwarf_highpc;
dwarf_highpc_b;
dwarf_init;
dwarf_line_srcfileno;
dwarf_lineaddr;
@ -166,6 +172,7 @@ global:
dwarf_loclist;
dwarf_loclist_from_expr;
dwarf_loclist_from_expr_a;
dwarf_loclist_from_expr_b;
dwarf_loclist_n;
dwarf_lowpc;
dwarf_new_die;
@ -173,9 +180,12 @@ global:
dwarf_new_fde;
dwarf_next_cu_header;
dwarf_next_cu_header_b;
dwarf_next_cu_header_c;
dwarf_next_types_section;
dwarf_object_finish;
dwarf_object_init;
dwarf_offdie;
dwarf_offdie_b;
dwarf_producer_finish;
dwarf_producer_init;
dwarf_producer_init_b;
@ -196,6 +206,7 @@ global:
dwarf_seterrarg;
dwarf_seterrhand;
dwarf_siblingof;
dwarf_siblingof_b;
dwarf_srcfiles;
dwarf_srclang;
dwarf_srclines;

View file

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2009-2011 Kai Wang
* Copyright (c) 2009-2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libdwarf.h 2075 2011-10-27 03:47:28Z jkoshy $
* $Id: _libdwarf.h 3106 2014-12-19 16:00:58Z kaiwang27 $
*/
#ifndef __LIBDWARF_H_
@ -89,6 +89,7 @@ extern struct _libdwarf_globals _libdwarf;
goto gen_fail; \
} while(0)
typedef struct _Dwarf_CU *Dwarf_CU;
struct _Dwarf_AttrDef {
uint64_t ad_attrib; /* DW_AT_XXX */
@ -147,14 +148,6 @@ struct _Dwarf_Die {
STAILQ_ENTRY(_Dwarf_Die) die_pro_next; /* Next die in pro-die list. */
};
struct _Dwarf_Loclist {
Dwarf_Locdesc **ll_ldlist; /* Array of Locdesc pointer. */
int ll_ldlen; /* Number of Locdesc. */
Dwarf_Unsigned ll_offset; /* Offset in .debug_loc section. */
Dwarf_Unsigned ll_length; /* Length (in bytes) of the loclist. */
TAILQ_ENTRY(_Dwarf_Loclist) ll_next; /* Next loclist in list. */
};
struct _Dwarf_P_Expr_Entry {
Dwarf_Loc ee_loc; /* Location expression. */
Dwarf_Unsigned ee_sym; /* Optional related reloc sym index. */
@ -265,6 +258,8 @@ struct _Dwarf_Cie {
Dwarf_Half cie_version; /* CIE version. */
uint8_t *cie_augment; /* CIE augmentation (UTF-8). */
Dwarf_Unsigned cie_ehdata; /* Optional EH Data. */
uint8_t cie_addrsize; /* Address size. (DWARF4) */
uint8_t cie_segmentsize; /* Segment size. (DWARF4) */
Dwarf_Unsigned cie_caf; /* Code alignment factor. */
Dwarf_Signed cie_daf; /* Data alignment factor. */
Dwarf_Unsigned cie_ra; /* Return address register. */
@ -333,11 +328,14 @@ struct _Dwarf_CU {
uint64_t cu_lineno_offset; /* Offset into .debug_lineno. */
uint8_t cu_pointer_size;/* Number of bytes in pointer. */
uint8_t cu_dwarf_size; /* CU section dwarf size. */
Dwarf_Sig8 cu_type_sig; /* Type unit's signature. */
uint64_t cu_type_offset; /* Type unit's type offset. */
Dwarf_Off cu_next_offset; /* Offset to the next CU. */
uint64_t cu_1st_offset; /* First DIE offset. */
int cu_pass2; /* Two pass DIE traverse. */
Dwarf_LineInfo cu_lineinfo; /* Ptr to Dwarf_LineInfo. */
Dwarf_Abbrev cu_abbrev_hash; /* Abbrev hash table. */
Dwarf_Bool cu_is_info; /* Compilation/type unit flag. */
STAILQ_ENTRY(_Dwarf_CU) cu_next; /* Next compilation unit. */
};
@ -399,17 +397,21 @@ struct _Dwarf_Debug {
Dwarf_Section *dbg_section; /* Dwarf section list. */
Dwarf_Section *dbg_info_sec; /* Pointer to info section. */
Dwarf_Off dbg_info_off; /* Current info section offset. */
Dwarf_Section *dbg_types_sec; /* Pointer to type section. */
Dwarf_Off dbg_types_off; /* Current types section offset. */
Dwarf_Unsigned dbg_seccnt; /* Total number of dwarf sections. */
int dbg_mode; /* Access mode. */
int dbg_pointer_size; /* Object address size. */
int dbg_offset_size; /* DWARF offset size. */
int dbg_info_loaded; /* Flag indicating all CU loaded. */
int dbg_types_loaded; /* Flag indicating all TU loaded. */
Dwarf_Half dbg_machine; /* ELF machine architecture. */
Dwarf_Handler dbg_errhand; /* Error handler. */
Dwarf_Ptr dbg_errarg; /* Argument to the error handler. */
STAILQ_HEAD(, _Dwarf_CU) dbg_cu;/* List of compilation units. */
STAILQ_HEAD(, _Dwarf_CU) dbg_tu;/* List of type units. */
Dwarf_CU dbg_cu_current; /* Ptr to the current CU. */
TAILQ_HEAD(, _Dwarf_Loclist) dbg_loclist; /* List of location list. */
Dwarf_CU dbg_tu_current; /* Ptr to the current TU. */
Dwarf_NameSec dbg_globals; /* Ptr to pubnames lookup section. */
Dwarf_NameSec dbg_pubtypes; /* Ptr to pubtypes lookup section. */
Dwarf_NameSec dbg_weaks; /* Ptr to weaknames lookup section. */
@ -532,13 +534,15 @@ int _dwarf_elf_get_section_info(void *, Dwarf_Half,
Dwarf_Obj_Access_Section *, int *);
void _dwarf_expr_cleanup(Dwarf_P_Debug);
int _dwarf_expr_into_block(Dwarf_P_Expr, Dwarf_Error *);
Dwarf_Section *_dwarf_find_next_types_section(Dwarf_Debug, Dwarf_Section *);
Dwarf_Section *_dwarf_find_section(Dwarf_Debug, const char *);
void _dwarf_frame_cleanup(Dwarf_Debug);
int _dwarf_frame_fde_add_inst(Dwarf_P_Fde, Dwarf_Small,
Dwarf_Unsigned, Dwarf_Unsigned, Dwarf_Error *);
int _dwarf_frame_gen(Dwarf_P_Debug, Dwarf_Error *);
int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t *, Dwarf_Unsigned,
Dwarf_Frame_Op **, Dwarf_Signed *, Dwarf_Error *);
int _dwarf_frame_get_fop(Dwarf_Debug, uint8_t, uint8_t *,
Dwarf_Unsigned, Dwarf_Frame_Op **, Dwarf_Signed *,
Dwarf_Error *);
int _dwarf_frame_get_internal_table(Dwarf_Fde, Dwarf_Addr,
Dwarf_Regtable3 **, Dwarf_Addr *, Dwarf_Error *);
int _dwarf_frame_interal_table_init(Dwarf_Debug, Dwarf_Error *);
@ -553,9 +557,12 @@ Dwarf_Unsigned _dwarf_get_reloc_type(Dwarf_P_Debug, int);
int _dwarf_get_reloc_size(Dwarf_Debug, Dwarf_Unsigned);
void _dwarf_info_cleanup(Dwarf_Debug);
int _dwarf_info_first_cu(Dwarf_Debug, Dwarf_Error *);
int _dwarf_info_first_tu(Dwarf_Debug, Dwarf_Error *);
int _dwarf_info_gen(Dwarf_P_Debug, Dwarf_Error *);
int _dwarf_info_load(Dwarf_Debug, int, Dwarf_Error *);
int _dwarf_info_load(Dwarf_Debug, Dwarf_Bool, Dwarf_Bool,
Dwarf_Error *);
int _dwarf_info_next_cu(Dwarf_Debug, Dwarf_Error *);
int _dwarf_info_next_tu(Dwarf_Debug, Dwarf_Error *);
void _dwarf_info_pro_cleanup(Dwarf_P_Debug);
int _dwarf_init(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Handler,
Dwarf_Ptr, Dwarf_Error *);
@ -563,20 +570,19 @@ int _dwarf_lineno_gen(Dwarf_P_Debug, Dwarf_Error *);
int _dwarf_lineno_init(Dwarf_Die, uint64_t, Dwarf_Error *);
void _dwarf_lineno_cleanup(Dwarf_LineInfo);
void _dwarf_lineno_pro_cleanup(Dwarf_P_Debug);
int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *, uint8_t *,
uint64_t, uint8_t, Dwarf_Error *);
int _dwarf_loc_fill_locdesc(Dwarf_Debug, Dwarf_Locdesc *,
uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t,
Dwarf_Error *);
int _dwarf_loc_fill_locexpr(Dwarf_Debug, Dwarf_Locdesc **,
uint8_t *, uint64_t, uint8_t, Dwarf_Error *);
uint8_t *, uint64_t, uint8_t, uint8_t, uint8_t,
Dwarf_Error *);
int _dwarf_loc_add(Dwarf_Die, Dwarf_Attribute, Dwarf_Error *);
int _dwarf_loc_expr_add_atom(Dwarf_Debug, uint8_t *, uint8_t *,
Dwarf_Small, Dwarf_Unsigned, Dwarf_Unsigned, int *,
Dwarf_Error *);
int _dwarf_loclist_find(Dwarf_Debug, Dwarf_CU, uint64_t,
Dwarf_Loclist *, Dwarf_Error *);
void _dwarf_loclist_cleanup(Dwarf_Debug);
void _dwarf_loclist_free(Dwarf_Loclist);
int _dwarf_loclist_add(Dwarf_Debug, Dwarf_CU, uint64_t,
Dwarf_Loclist *, Dwarf_Error *);
Dwarf_Locdesc ***, Dwarf_Signed *, Dwarf_Unsigned *,
Dwarf_Error *);
void _dwarf_macinfo_cleanup(Dwarf_Debug);
int _dwarf_macinfo_gen(Dwarf_P_Debug, Dwarf_Error *);
int _dwarf_macinfo_init(Dwarf_Debug, Dwarf_Error *);
@ -633,6 +639,7 @@ void _dwarf_strtab_cleanup(Dwarf_Debug);
int _dwarf_strtab_gen(Dwarf_P_Debug, Dwarf_Error *);
char *_dwarf_strtab_get_table(Dwarf_Debug);
int _dwarf_strtab_init(Dwarf_Debug, Dwarf_Error *);
void _dwarf_type_unit_cleanup(Dwarf_Debug);
void _dwarf_write_block(void *, uint64_t *, uint8_t *, uint64_t);
int _dwarf_write_block_alloc(uint8_t **, uint64_t *, uint64_t *,
uint8_t *, uint64_t, Dwarf_Error *);

View file

@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
.\" $Id: dwarf.3 2075 2011-10-27 03:47:28Z jkoshy $
.\" $Id: dwarf.3 3130 2014-12-21 20:06:29Z jkoshy $
.\"
.Dd September 17, 2011
.Dd December 21, 2014
.Os
.Dt DWARF 3
.Sh NAME
@ -217,6 +217,8 @@ attribute.
Retrieve an attribute descriptor.
.It Fn dwarf_attrlist
Retrieve attribute descriptors for a debugging information entry.
.It Fn dwarf_attroffset
Retrieve the section-relative offset of an attribute descriptor.
.It Fn dwarf_attrval_flag
Retrieve a
.Dv DW_AT_FORM_flag
@ -309,10 +311,17 @@ Retrieve range information from an FDE descriptor.
.El
.It Compilation Units
.Bl -tag -compact
.It Fn dwarf_get_cu_die_offset_given_cu_header_offset
.It Xo
.Fn dwarf_get_cu_die_offset_given_cu_header_offset ,
.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b
.Xc
Retrieve the offset of the debugging information entry for a
compilation unit.
.It Fn dwarf_next_cu_header , Fn dwarf_next_cu_header_b
compilation or type unit.
.It Xo
.Fn dwarf_next_cu_header ,
.Fn dwarf_next_cu_header_b ,
.Fn dwarf_next_cu_header_c
.Xc
Step through compilation units in a debug context.
.El
.It Debugging Information Entries
@ -329,13 +338,15 @@ Returns the
attribute for a debugging information entry.
.It Fn dwarf_dieoffset
Retrieves the offset for a debugging information entry.
.It Fn dwarf_highpc
.It Fn dwarf_get_die_infotypes_flag
Indicate the originating section for a debugging information entry.
.It Fn dwarf_highpc , Fn dwarf_highpc_b
Return the highest PC value for a debugging information entry.
.It Fn dwarf_lowpc
Return the lowest PC value for a debugging information entry.
.It Fn dwarf_offdie
.It Fn dwarf_offdie , Fn dwarf_offdie_b
Retrieve a debugging information entry given an offset.
.It Fn dwarf_siblingof
.It Fn dwarf_siblingof , Fn dwarf_siblingof_b
Retrieve the sibling descriptor for a debugging information entry.
.It Fn dwarf_srclang
Retrive the source language attribute for a debugging information
@ -416,7 +427,11 @@ Return line number information for a compilation unit.
Retrieve a location list entry.
.It Fn dwarf_loclist , Fn dwarf_loclist_n
Retrieve location expressions.
.It Fn dwarf_loclist_from_expr , Fn dwarf_loclist_from_expr_a
.It Xo
.Fn dwarf_loclist_from_expr ,
.Fn dwarf_loclist_from_expr_a ,
.Fn dwarf_loclist_from_expr_b
.Xc
Translate a location expression into a location descriptor.
.El
.It Error Handling
@ -513,6 +528,10 @@ and
.Bl -tag -compact
.It Fn dwarf_get_pubtypes , Fn dwarf_get_types
Retrieve descriptors for user-defined types.
.It Fn dwarf_next_types_section
Step through
.Dq \&.debug_types
sections in a debug context.
.It Fn dwarf_pubtype_cu_offset , Fn dwarf_type_cu_offset
Return the offset for the compilation unit for a type.
.It Fn dwarf_pubtype_die_offset , Fn dwarf_type_die_offset
@ -699,9 +718,16 @@ addition to the per-debug context handlers supported by the SGI/GNU
API, see the subsection
.Sx Error Handling
above.
.El
.Ss Extensions
The following APIs are extensions specific to this implementation:
.Bl -bullet -compact
.It
The following API is an extension:
.Fn dwarf_producer_set_isa .
.Fn dwarf_attroffset
.It
.Fn dwarf_next_types_section
.It
.Fn dwarf_producer_set_isa
.El
.Sh SEE ALSO
.Xr elf 3

View file

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: dwarf.h 2075 2011-10-27 03:47:28Z jkoshy $
* $Id: dwarf.h 3052 2014-05-26 20:36:24Z kaiwang27 $
*/
#ifndef _DWARF_H_
@ -93,6 +93,19 @@
#define DW_TAG_lo_user 0x4080
#define DW_TAG_hi_user 0xffff
/* GNU extensions. */
#define DW_TAG_format_label 0x4101
#define DW_TAG_function_template 0x4102
#define DW_TAG_class_template 0x4103
#define DW_TAG_GNU_BINCL 0x4104
#define DW_TAG_GNU_EINCL 0x4105
#define DW_TAG_GNU_template_template_parameter 0x4106
#define DW_TAG_GNU_template_template_param 0x4106
#define DW_TAG_GNU_template_parameter_pack 0x4107
#define DW_TAG_GNU_formal_parameter_pack 0x4108
#define DW_TAG_GNU_call_site 0x4109
#define DW_TAG_GNU_call_site_parameter 0x410a
#define DW_CHILDREN_no 0x00
#define DW_CHILDREN_yes 0x01
@ -195,6 +208,32 @@
#define DW_AT_lo_user 0x2000
#define DW_AT_hi_user 0x3fff
/* GNU extensions. */
#define DW_AT_sf_names 0x2101
#define DW_AT_src_info 0x2102
#define DW_AT_mac_info 0x2103
#define DW_AT_src_coords 0x2104
#define DW_AT_body_begin 0x2105
#define DW_AT_body_end 0x2106
#define DW_AT_GNU_vector 0x2107
#define DW_AT_GNU_guarded_by 0x2108
#define DW_AT_GNU_pt_guarded_by 0x2109
#define DW_AT_GNU_guarded 0x210a
#define DW_AT_GNU_pt_guarded 0x210b
#define DW_AT_GNU_locks_excluded 0x210c
#define DW_AT_GNU_exclusive_locks_required 0x210d
#define DW_AT_GNU_shared_locks_required 0x210e
#define DW_AT_GNU_odr_signature 0x210f
#define DW_AT_GNU_template_name 0x2110
#define DW_AT_GNU_call_site_value 0x2111
#define DW_AT_GNU_call_site_data_value 0x2112
#define DW_AT_GNU_call_site_target 0x2113
#define DW_AT_GNU_call_site_target_clobbered 0x2114
#define DW_AT_GNU_tail_call 0x2115
#define DW_AT_GNU_all_tail_call_sites 0x2116
#define DW_AT_GNU_all_call_sites 0x2117
#define DW_AT_GNU_all_source_call_sites 0x2118
#define DW_FORM_addr 0x01
#define DW_FORM_block2 0x03
#define DW_FORM_block4 0x04
@ -220,6 +259,8 @@
#define DW_FORM_exprloc 0x18
#define DW_FORM_flag_present 0x19
#define DW_FORM_ref_sig8 0x20
#define DW_FORM_GNU_ref_alt 0x1f20
#define DW_FORM_GNU_strp_alt 0x1f21
#define DW_OP_addr 0x03
#define DW_OP_deref 0x06
@ -376,9 +417,23 @@
#define DW_OP_implicit_value 0x9e
#define DW_OP_stack_value 0x9f
#define DW_OP_lo_user 0xe0
#define DW_OP_GNU_push_tls_address 0xe0
#define DW_OP_hi_user 0xff
/* GNU extensions. */
#define DW_OP_GNU_push_tls_address 0xe0
#define DW_OP_GNU_uninit 0xf0
#define DW_OP_GNU_encoded_addr 0xf1
#define DW_OP_GNU_implicit_pointer 0xf2
#define DW_OP_GNU_entry_value 0xf3
#define DW_OP_GNU_const_type 0xf4
#define DW_OP_GNU_regval_type 0xf5
#define DW_OP_GNU_deref_type 0xf6
#define DW_OP_GNU_convert 0xf7
#define DW_OP_GNU_reinterpret 0xf9
#define DW_OP_GNU_parameter_ref 0xfa
#define DW_OP_GNU_addr_index 0xfb
#define DW_OP_GNU_const_index 0xfc
#define DW_ATE_address 0x1
#define DW_ATE_boolean 0x2
#define DW_ATE_complex_float 0x3

View file

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_attr.3 2072 2011-10-27 03:26:49Z jkoshy $
.\" $Id: dwarf_attr.3 3093 2014-09-02 22:09:40Z kaiwang27 $
.\"
.Dd April 8, 2010
.Os
@ -113,6 +113,7 @@ in argument
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attrlist 3 ,
.Xr dwarf_attroffset 3 ,
.Xr dwarf_hasattr 3 ,
.Xr dwarf_hasform 3 ,
.Xr dwarf_whatattr 3 ,

View file

@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_attr.c 2072 2011-10-27 03:26:49Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $");
int
dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp,
@ -113,6 +113,23 @@ dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool,
return (DW_DLV_OK);
}
int
dwarf_attroffset(Dwarf_Attribute at, Dwarf_Off *ret_off, Dwarf_Error *error)
{
Dwarf_Debug dbg;
dbg = at != NULL ? at->at_die->die_dbg : NULL;
if (at == NULL || ret_off == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
*ret_off = at->at_offset;
return (DW_DLV_OK);
}
int
dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error)
{
@ -138,9 +155,18 @@ dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error)
int
dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error)
{
return (dwarf_highpc_b(die, ret_highpc, NULL, NULL, error));
}
int
dwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form,
enum Dwarf_Form_Class *ret_class, Dwarf_Error *error)
{
Dwarf_Attribute at;
Dwarf_Debug dbg;
Dwarf_CU cu;
dbg = die != NULL ? die->die_dbg : NULL;
@ -156,6 +182,17 @@ dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error)
*ret_highpc = at->u[0].u64;
if (ret_form != NULL) {
*ret_form = at->at_form;
}
if (ret_class != NULL) {
cu = die->die_cu;
*ret_class = dwarf_get_form_class(cu->cu_version,
DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8,
at->at_form);
}
return (DW_DLV_OK);
}

View file

@ -0,0 +1,86 @@
.\" Copyright (c) 2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_attroffset.3 3115 2014-12-20 18:26:46Z jkoshy $
.\"
.Dd December 20, 2014
.Os
.Dt DWARF_ATTROFFSET 3
.Sh NAME
.Nm dwarf_attroffset
.Nd retrieve the section-relative offset of an attribute descriptor
.Sh LIBRARY
.Lb libdwarf
.Sh SYNOPSIS
.In libdwarf.h
.Ft int
.Fo dwarf_attroffset
.Fa "Dwarf_Attribute at"
.Fa "Dwarf_Off *ret_off"
.Fa "Dwarf_Error *err"
.Fc
.Sh DESCRIPTION
Function
.Fn dwarf_attroffset
retrieves the section-relative offset of the attribute descriptor
referenced by argument
.Ar at .
.Pp
Argument
.Ar ret_off
should point to a location that is to hold the returned
section-relative offset.
If argument
.Ar err
is non-NULL, it is used to return an error descriptor in case of an
error.
.Sh RETURN VALUES
On success, function
.Fn dwarf_attroffset
returns
.Dv DW_DLV_OK .
.Pp
In case of an error, it returns
.Dv DW_DLV_ERROR
and sets argument
.Ar err .
.Sh COMPATIBILITY
This function is an extension to the
.Xr DWARF 3
API.
.Sh ERRORS
The
.Fn dwarf_attroffset
function may fail with the following errors:
.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT"
.It Bq Er DW_DLE_ARGUMENT
Either of the arguments
.Ar at
or
.Ar ret_off
was NULL.
.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_attrval.c 2977 2014-01-21 20:13:31Z kaiwang27 $");
int
dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err)

View file

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_attrval_signed.3 2072 2011-10-27 03:26:49Z jkoshy $
.\" $Id: dwarf_attrval_signed.3 2980 2014-01-21 20:15:54Z kaiwang27 $
.\"
.Dd January 18, 2014
.Os

View file

@ -1,4 +1,4 @@
.\" Copyright (c) 2010 Kai Wang
.\" Copyright (c) 2010,2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,15 +22,17 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_child.3 2122 2011-11-09 15:35:14Z jkoshy $
.\" $Id: dwarf_child.3 3127 2014-12-21 19:09:19Z jkoshy $
.\"
.Dd November 9, 2011
.Dd December 21, 2014
.Os
.Dt DWARF_CHILD 3
.Sh NAME
.Nm dwarf_child ,
.Nm dwarf_offdie ,
.Nm dwarf_offdie_b ,
.Nm dwarf_siblingof ,
.Nm dwarf_offdie
.Nm dwarf_siblingof_b
.Nd retrieve DWARF Debugging Information Entry descriptors
.Sh LIBRARY
.Lb libdwarf
@ -39,6 +41,21 @@
.Ft int
.Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err"
.Ft int
.Fo dwarf_offdie
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Off offset"
.Fa "Dwarf_Die *ret_die"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_offdie_b
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Off offset"
.Fa "Dwarf_Bool is_info"
.Fa "Dwarf_Die *ret_die"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_siblingof
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Die die"
@ -46,10 +63,11 @@
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_offdie
.Fo dwarf_siblingof_b
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Off offset"
.Fa "Dwarf_Die die"
.Fa "Dwarf_Die *ret_die"
.Fa "Dwarf_Bool is_info"
.Fa "Dwarf_Error *err"
.Fc
.Sh DESCRIPTION
@ -92,6 +110,34 @@ may be used together to traverse the tree of debugging information
entry descriptors for a compilation unit.
.Pp
Function
.Fn dwarf_siblingof_b
is identical to the function
.Fn dwarf_siblingof
except that it can retrieve the sibling descriptor from either the
current compilation unit or type unit.
If argument
.Ar is_info
is non-zero, the function behaves identically to function
.Fn dwarf_siblingof .
If argument
.Ar is_info
is zero, the descriptor referred by argument
.Ar die
should be associated with a debugging information entry in the
type unit.
The function will store the sibling of the descriptor in the location
pointed to by argument
.Ar ret_die .
If argument
.Ar is_info
is zero and argument
.Ar die
is
.Dv NULL ,
the first debugging information entry descriptor for the
current type unit will be returned.
.Pp
Function
.Fn dwarf_offdie
retrieves the debugging information entry descriptor at global offset
.Ar offset
@ -101,6 +147,31 @@ section of the object associated with argument
.Ar dbg .
The returned descriptor is written to the location pointed to by argument
.Ar ret_die .
.Pp
Function
.Fn dwarf_offdie_b
is identical to the function
.Fn dwarf_offdie
except that it can retrieve the debugging information entry descriptor at
global offset
.Ar offset
from either of the
.Dq .debug_info
and
.Dq .debug_types
sections of the object associated with argument
.Ar dbg .
If argument
.Ar is_info
is non-zero, the function will retrieve the debugging information
entry from the
.Dq .debug_info
section, otherwise the function will retrieve the debugging
information entry from the
.Dq .debug_types
section.
The returned descriptor is written to the location pointed to by argument
.Ar ret_die .
.Ss Memory Management
The memory area used for the
.Vt Dwarf_Die
@ -128,14 +199,18 @@ argument
if it is not NULL.
.It Bq Er DW_DLV_NO_ENTRY
For functions
.Fn dwarf_child
.Fn dwarf_child ,
.Fn dwarf_siblingof
and
.Fn dwarf_siblingof ,
.Fn dwarf_siblingof_b ,
the descriptor denoted by argument
.Ar die
did not have a child or sibling.
For function
.Fn dwarf_offdie ,
.Pp
For functions
.Fn dwarf_offdie
and
.Fn dwarf_offdie_b ,
there was no debugging information entry at the offset specified by
argument
.Ar offset .
@ -199,4 +274,5 @@ do {
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_errmsg 3 ,
.Xr dwarf_get_die_infotypes_flag.3 ,
.Xr dwarf_next_cu_header 3

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,14 +27,15 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_cu.c 2072 2011-10-27 03:26:49Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_cu.c 3041 2014-05-18 15:11:03Z kaiwang27 $");
int
dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
Dwarf_Error *error)
dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info,
Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error)
{
Dwarf_CU cu;
int ret;
@ -43,10 +45,17 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
return (DW_DLV_ERROR);
}
if (dbg->dbg_cu_current == NULL)
ret = _dwarf_info_first_cu(dbg, error);
else
ret = _dwarf_info_next_cu(dbg, error);
if (is_info) {
if (dbg->dbg_cu_current == NULL)
ret = _dwarf_info_first_cu(dbg, error);
else
ret = _dwarf_info_next_cu(dbg, error);
} else {
if (dbg->dbg_tu_current == NULL)
ret = _dwarf_info_first_tu(dbg, error);
else
ret = _dwarf_info_next_tu(dbg, error);
}
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
@ -54,11 +63,19 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
} else if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
if (dbg->dbg_cu_current == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
if (is_info) {
if (dbg->dbg_cu_current == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
cu = dbg->dbg_cu_current;
} else {
if (dbg->dbg_tu_current == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
cu = dbg->dbg_tu_current;
}
cu = dbg->dbg_cu_current;
if (cu_length)
*cu_length = cu->cu_length;
@ -81,11 +98,32 @@ dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
*cu_extension_size = 4;
}
if (cu_next_offset)
*cu_next_offset = dbg->dbg_cu_current->cu_next_offset;
*cu_next_offset = cu->cu_next_offset;
if (!is_info) {
if (type_signature)
*type_signature = cu->cu_type_sig;
if (type_offset)
*type_offset = cu->cu_type_offset;
}
return (DW_DLV_OK);
}
int
dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
Dwarf_Error *error)
{
return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version,
cu_abbrev_offset, cu_pointer_size, cu_offset_size,
cu_extension_size, NULL, NULL, cu_next_offset, error));
}
int
dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
@ -97,3 +135,27 @@ dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset,
error));
}
int
dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error)
{
/* Free resource allocated for current .debug_types section. */
_dwarf_type_unit_cleanup(dbg);
dbg->dbg_types_loaded = 0;
dbg->dbg_types_off = 0;
/* Reset type unit pointer. */
dbg->dbg_tu_current = NULL;
/* Search for the next .debug_types section. */
dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg,
dbg->dbg_types_sec);
if (dbg->dbg_types_sec == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
return (DW_DLV_OK);
}

View file

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2009,2011 Kai Wang
* Copyright (c) 2009,2011,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,12 +27,13 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_die.c 2073 2011-10-27 03:30:47Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $");
int
dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error)
{
Dwarf_Debug dbg;
Dwarf_Section *ds;
Dwarf_CU cu;
int ret;
@ -48,9 +49,9 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error)
dbg = die->die_dbg;
cu = die->die_cu;
ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu,
cu->cu_dwarf_size, die->die_next_off, cu->cu_next_offset,
ret_die, 0, error);
ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec;
ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size,
die->die_next_off, cu->cu_next_offset, ret_die, 0, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
@ -62,11 +63,12 @@ dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *error)
}
int
dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
Dwarf_Error *error)
dwarf_siblingof_b(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
Dwarf_Bool is_info, Dwarf_Error *error)
{
Dwarf_CU cu;
Dwarf_Attribute at;
Dwarf_Section *ds;
uint64_t offset;
int ret, search_sibling;
@ -75,15 +77,27 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
return (DW_DLV_ERROR);
}
if ((cu = dbg->dbg_cu_current) == NULL) {
ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec;
cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current;
if (cu == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_DIE_NO_CU_CONTEXT);
return (DW_DLV_ERROR);
}
/* Application requests the first DIE in this CU. */
if (die == NULL)
return (dwarf_offdie(dbg, cu->cu_1st_offset, ret_die,
error));
return (dwarf_offdie_b(dbg, cu->cu_1st_offset, is_info,
ret_die, error));
/*
* Check if the `is_info' flag matches the debug section the
* DIE belongs to.
*/
if (is_info != die->die_cu->cu_is_info) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
/*
* If the DIE doesn't have any children, its sibling sits next
@ -108,9 +122,8 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
}
}
ret = _dwarf_die_parse(die->die_dbg, dbg->dbg_info_sec, cu,
cu->cu_dwarf_size, offset, cu->cu_next_offset, ret_die,
search_sibling, error);
ret = _dwarf_die_parse(die->die_dbg, ds, cu, cu->cu_dwarf_size, offset,
cu->cu_next_offset, ret_die, search_sibling, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
@ -121,21 +134,31 @@ dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
return (DW_DLV_OK);
}
int
dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *ret_die,
Dwarf_Error *error)
{
return (dwarf_siblingof_b(dbg, die, ret_die, 1, error));
}
static int
_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off offset,
Dwarf_Die *ret_die, Dwarf_Error *error)
_dwarf_search_die_within_cu(Dwarf_Debug dbg, Dwarf_Section *s, Dwarf_CU cu,
Dwarf_Off offset, Dwarf_Die *ret_die, Dwarf_Error *error)
{
assert(dbg != NULL && cu != NULL && ret_die != NULL);
return (_dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size,
return (_dwarf_die_parse(dbg, s, cu, cu->cu_dwarf_size,
offset, cu->cu_next_offset, ret_die, 0, error));
}
int
dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die,
Dwarf_Error *error)
dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Bool is_info,
Dwarf_Die *ret_die, Dwarf_Error *error)
{
Dwarf_Section *ds;
Dwarf_CU cu;
int ret;
@ -144,11 +167,13 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die,
return (DW_DLV_ERROR);
}
ds = is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec;
cu = is_info ? dbg->dbg_cu_current : dbg->dbg_tu_current;
/* First search the current CU. */
if (dbg->dbg_cu_current != NULL) {
cu = dbg->dbg_cu_current;
if (cu != NULL) {
if (offset > cu->cu_offset && offset < cu->cu_next_offset) {
ret = _dwarf_search_die_within_cu(dbg, cu, offset,
ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset,
ret_die, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
@ -160,27 +185,52 @@ dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die,
}
/* Search other CUs. */
ret = _dwarf_info_load(dbg, 1, error);
ret = _dwarf_info_load(dbg, 1, is_info, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
if (offset < cu->cu_offset || offset > cu->cu_next_offset)
continue;
ret = _dwarf_search_die_within_cu(dbg, cu, offset,
ret_die, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
} else if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
return (DW_DLV_OK);
if (is_info) {
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
if (offset < cu->cu_offset ||
offset > cu->cu_next_offset)
continue;
ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset,
ret_die, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
} else if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
return (DW_DLV_OK);
}
} else {
STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) {
if (offset < cu->cu_offset ||
offset > cu->cu_next_offset)
continue;
ret = _dwarf_search_die_within_cu(dbg, ds, cu, offset,
ret_die, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
} else if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
return (DW_DLV_OK);
}
}
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
int
dwarf_offdie(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Die *ret_die,
Dwarf_Error *error)
{
return (dwarf_offdie_b(dbg, offset, 1, ret_die, error));
}
int
dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *error)
{
@ -293,9 +343,9 @@ dwarf_die_abbrev_code(Dwarf_Die die)
}
int
dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset,
Dwarf_Error *error)
dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg,
Dwarf_Off in_cu_header_offset, Dwarf_Bool is_info,
Dwarf_Off *out_cu_die_offset, Dwarf_Error *error)
{
Dwarf_CU cu;
@ -304,10 +354,19 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
return (DW_DLV_ERROR);
}
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
if (cu->cu_offset == in_cu_header_offset) {
*out_cu_die_offset = cu->cu_1st_offset;
break;
if (is_info) {
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
if (cu->cu_offset == in_cu_header_offset) {
*out_cu_die_offset = cu->cu_1st_offset;
break;
}
}
} else {
STAILQ_FOREACH(cu, &dbg->dbg_tu, cu_next) {
if (cu->cu_offset == in_cu_header_offset) {
*out_cu_die_offset = cu->cu_1st_offset;
break;
}
}
}
@ -319,6 +378,16 @@ dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
return (DW_DLV_OK);
}
int
dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
Dwarf_Off in_cu_header_offset, Dwarf_Off *out_cu_die_offset,
Dwarf_Error *error)
{
return (dwarf_get_cu_die_offset_given_cu_header_offset_b(dbg,
in_cu_header_offset, 1, out_cu_die_offset, error));
}
int
dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size,
Dwarf_Error *error)
@ -333,3 +402,12 @@ dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Half *addr_size,
return (DW_DLV_OK);
}
Dwarf_Bool
dwarf_get_die_infotypes_flag(Dwarf_Die die)
{
assert(die != NULL);
return (die->die_cu->cu_is_info);
}

View file

@ -1,4 +1,4 @@
.\" Copyright (c) 2010 Kai Wang
.\" Copyright (c) 2010,2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,16 +22,17 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_dieoffset.3 2073 2011-10-27 03:30:47Z jkoshy $
.\" $Id: dwarf_dieoffset.3 3129 2014-12-21 20:06:26Z jkoshy $
.\"
.Dd April 17, 2010
.Dd December 21, 2014
.Os
.Dt DWARF_DIEOFFSET 3
.Sh NAME
.Nm dwarf_die_CU_offset ,
.Nm dwarf_die_CU_offset_range ,
.Nm dwarf_dieoffset ,
.Nm dwarf_get_cu_die_offset_given_cu_header_offset
.Nm dwarf_get_cu_die_offset_given_cu_header_offset ,
.Nm dwarf_get_cu_die_offset_given_cu_header_offset_b
.Nd return offsets of DWARF debugging information entries
.Sh LIBRARY
.Lb libdwarf
@ -63,6 +64,14 @@
.Fa "Dwarf_Off *out_cu_die_offset"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_get_cu_die_offset_given_cu_header_offset_b
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Off in_cu_header_offset"
.Fa "Dwarf_Bool is_info"
.Fa "Dwarf_Off *out_cu_die_offset"
.Fa "Dwarf_Error *err"
.Fc
.Sh DESCRIPTION
These functions are used to retrieve offsets for DWARF debugging
information entries.
@ -114,7 +123,7 @@ an error.
.Pp
Function
.Fn dwarf_get_cu_die_offset_given_cu_header_offset
returns the offset for the debugging information entry for a
returns the offset for the first debugging information entry for a
compilation unit, given an offset to the header of the compilation
unit.
Argument
@ -131,8 +140,30 @@ If argument
.Ar err
is non-NULL, it will be used to return an error descriptor in case of
an error.
.Pp
Function
.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b
behaves identically to the function
.Fn dwarf_get_cu_die_offset_given_cu_header_offset
when the argument
.Ar is_info
is non-zero.
When the argument
.Ar is_info
is zero, function
.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b
returns the offset for the first debugging information entry for a
type unit, given an offset to the header of the type unit in argument
.Ar in_cu_header_offset .
Argument
.Ar out_cu_die_offset
points to a location that will hold the returned offset.
If the argument
.Ar err
is non-NULL, it will be used to return an error descriptor in case of
an error.
.Sh RETURN VALUES
On success, these functions returns
On success, these functions return
.Dv DW_DLV_OK .
In case of an error, these functions return
.Dv DW_DLV_ERROR
@ -141,11 +172,13 @@ and set argument
.Pp
Function
.Fn dwarf_get_cu_die_offset_given_cu_header_offset
and
.Fn dwarf_get_cu_die_offset_given_cu_header_offset_b
returns
.Dv DW_DLV_NO_ENTRY
and sets argument
.Ar err
if there is no compilation unit located at the
if there is no compilation or type unit located at the
offset specified in argument
.Ar in_cu_header_offset .
.Sh ERRORS
@ -169,4 +202,5 @@ specified an unknown offset.
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_next_cu_header 3 ,
.Xr dwarf_offdie 3
.Xr dwarf_offdie 3 ,
.Xr dwarf_offdie_b 3

View file

@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_dump.c 2073 2011-10-27 03:30:47Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_dump.c 3052 2014-05-26 20:36:24Z kaiwang27 $");
int
dwarf_get_ACCESS_name(unsigned access, const char **s)
@ -250,6 +250,54 @@ dwarf_get_AT_name(unsigned attr, const char **s)
*s = "DW_AT_visibility"; break;
case DW_AT_vtable_elem_location:
*s = "DW_AT_vtable_elem_location"; break;
case DW_AT_sf_names:
*s = "DW_AT_sf_names"; break;
case DW_AT_src_info:
*s = "DW_AT_src_info"; break;
case DW_AT_mac_info:
*s = "DW_AT_mac_info"; break;
case DW_AT_src_coords:
*s = "DW_AT_src_coords"; break;
case DW_AT_body_begin:
*s = "DW_AT_body_begin"; break;
case DW_AT_body_end:
*s = "DW_AT_body_end"; break;
case DW_AT_GNU_vector:
*s = "DW_AT_GNU_vector"; break;
case DW_AT_GNU_guarded_by:
*s = "DW_AT_GNU_guarded_by"; break;
case DW_AT_GNU_pt_guarded_by:
*s = "DW_AT_GNU_pt_guarded_by"; break;
case DW_AT_GNU_guarded:
*s = "DW_AT_GNU_guarded"; break;
case DW_AT_GNU_pt_guarded:
*s = "DW_AT_GNU_pt_guarded"; break;
case DW_AT_GNU_locks_excluded:
*s = "DW_AT_GNU_locks_excluded"; break;
case DW_AT_GNU_exclusive_locks_required:
*s = "DW_AT_GNU_exclusive_locks_required"; break;
case DW_AT_GNU_shared_locks_required:
*s = "DW_AT_GNU_shared_locks_required"; break;
case DW_AT_GNU_odr_signature:
*s = "DW_AT_GNU_odr_signature"; break;
case DW_AT_GNU_template_name:
*s = "DW_AT_GNU_template_name"; break;
case DW_AT_GNU_call_site_value:
*s = "DW_AT_GNU_call_site_value"; break;
case DW_AT_GNU_call_site_data_value:
*s = "DW_AT_GNU_call_site_data_value"; break;
case DW_AT_GNU_call_site_target:
*s = "DW_AT_GNU_call_site_target"; break;
case DW_AT_GNU_call_site_target_clobbered:
*s = "DW_AT_GNU_call_site_target_clobbered"; break;
case DW_AT_GNU_tail_call:
*s = "DW_AT_GNU_tail_call"; break;
case DW_AT_GNU_all_tail_call_sites:
*s = "DW_AT_GNU_all_tail_call_sites"; break;
case DW_AT_GNU_all_call_sites:
*s = "DW_AT_GNU_all_call_sites"; break;
case DW_AT_GNU_all_source_call_sites:
*s = "DW_AT_GNU_all_source_call_sites"; break;
default:
return (DW_DLV_NO_ENTRY);
}
@ -1094,6 +1142,30 @@ dwarf_get_OP_name(unsigned op, const char **s)
*s = "DW_OP_stack_value"; break;
case DW_OP_GNU_push_tls_address:
*s = "DW_OP_GNU_push_tls_address"; break;
case DW_OP_GNU_uninit:
*s = "DW_OP_GNU_uninit"; break;
case DW_OP_GNU_encoded_addr:
*s = "DW_OP_GNU_encoded_addr"; break;
case DW_OP_GNU_implicit_pointer:
*s = "DW_OP_GNU_implicit_pointer"; break;
case DW_OP_GNU_entry_value:
*s = "DW_OP_GNU_entry_value"; break;
case DW_OP_GNU_const_type:
*s = "DW_OP_GNU_const_type"; break;
case DW_OP_GNU_regval_type:
*s = "DW_OP_GNU_regval_type"; break;
case DW_OP_GNU_deref_type:
*s = "DW_OP_GNU_deref_type"; break;
case DW_OP_GNU_convert:
*s = "DW_OP_GNU_convert"; break;
case DW_OP_GNU_reinterpret:
*s = "DW_OP_GNU_reinterpret"; break;
case DW_OP_GNU_parameter_ref:
*s = "DW_OP_GNU_parameter_ref"; break;
case DW_OP_GNU_addr_index:
*s = "DW_OP_GNU_addr_index"; break;
case DW_OP_GNU_const_index:
*s = "DW_OP_GNU_const_index"; break;
default:
return (DW_DLV_NO_ENTRY);
}
@ -1244,6 +1316,26 @@ dwarf_get_TAG_name(unsigned tag, const char **s)
*s = "DW_TAG_volatile_type"; break;
case DW_TAG_with_stmt:
*s = "DW_TAG_with_stmt"; break;
case DW_TAG_format_label:
*s = "DW_TAG_format_label"; break;
case DW_TAG_function_template:
*s = "DW_TAG_function_template"; break;
case DW_TAG_class_template:
*s = "DW_TAG_class_template"; break;
case DW_TAG_GNU_BINCL:
*s = "DW_TAG_GNU_BINCL"; break;
case DW_TAG_GNU_EINCL:
*s = "DW_TAG_GNU_EINCL"; break;
case DW_TAG_GNU_template_template_param:
*s = "DW_TAG_GNU_template_template_param"; break;
case DW_TAG_GNU_template_parameter_pack:
*s = "DW_TAG_GNU_template_parameter_pack"; break;
case DW_TAG_GNU_formal_parameter_pack:
*s = "DW_TAG_GNU_formal_parameter_pack"; break;
case DW_TAG_GNU_call_site:
*s = "DW_TAG_GNU_call_site"; break;
case DW_TAG_GNU_call_site_parameter:
*s = "DW_TAG_GNU_call_site_parameter"; break;
default:
return (DW_DLV_NO_ENTRY);
}

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_errmsg.c 2576 2012-09-13 09:16:11Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_errmsg.c 2975 2014-01-21 20:08:04Z kaiwang27 $");
static const char *_libdwarf_errors[] = {
#define DEFINE_ERROR(N,S) [DW_DLE_##N] = S

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $");
int
dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list,
@ -539,8 +539,8 @@ dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction,
return (DW_DLV_ERROR);
}
ret = _dwarf_frame_get_fop(dbg, instruction, len, ret_oplist, ret_opcnt,
error);
ret = _dwarf_frame_get_fop(dbg, cie->cie_addrsize, instruction, len,
ret_oplist, ret_opcnt, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);

View file

@ -0,0 +1,73 @@
.\" Copyright (c) 2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_get_die_infotypes_flag.3 3118 2014-12-20 20:30:06Z jkoshy $
.\"
.Dd December 20, 2014
.Os
.Dt DWARF_GET_DIE_INFOTYPES_FLAG 3
.Sh NAME
.Nm dwarf_get_die_infotypes_flag
.Nd indicate the originating DWARF section for a DIE
.Sh LIBRARY
.Lb libdwarf
.Sh SYNOPSIS
.In libdwarf.h
.Ft Dwarf_Bool
.Fo dwarf_get_die_infotypes_flag
.Fa "Dwarf_Die die"
.Fc
.Sh DESCRIPTION
Function
.Fn dwarf_get_die_infotypes_flag
returns a flag indicating the originating DWARF section for the
debugging information entry referenced by argument
.Ar die .
.Pp
Argument
.Ar die
should reference a valid debugging information entry descriptor.
.Sh RETURN VALUES
Function
.Fn dwarf_get_die_infotypes_flag
returns a non-zero value if argument
.Ar die
originates in the
.Dq .debug_info
section.
.Pp
It returns zero if argument
.Ar die
originates in the
.Dq .debug_types
section.
.Sh ERRORS
Function
.Fn dwarf_get_die_infotypes_flag
always succeeds.
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_next_cu_header_c 3 ,
.Xr dwarf_offdie_b 3 ,
.Xr dwarf_siblingof_b 3

View file

@ -0,0 +1,116 @@
.\" Copyright (c) 2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_get_section_max_offsets.3 3098 2014-09-02 22:18:29Z kaiwang27 $
.\"
.Dd July 27, 2014
.Os
.Dt DWARF_GET_SECTION_MAX_OFFSETS
.Sh NAME
.Nm dwarf_get_section_max_offsets ,
.Nm dwarf_get_section_max_offsets_b
.Nd return the size of DWARF sections
.Sh LIBRARY
.Lb libdwarf
.Sh SYNOPSIS
.In libdwarf.h
.Ft int
.Fo dwarf_get_section_max_offsets
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Unsigned *debug_info"
.Fa "Dwarf_Unsigned *debug_abbrev"
.Fa "Dwarf_Unsigned *debug_line"
.Fa "Dwarf_Unsigned *debug_loc"
.Fa "Dwarf_Unsigned *debug_aranges"
.Fa "Dwarf_Unsigned *debug_macinfo"
.Fa "Dwarf_Unsigned *debug_pubnames"
.Fa "Dwarf_Unsigned *debug_str"
.Fa "Dwarf_Unsigned *debug_frame"
.Fa "Dwarf_Unsigned *debug_ranges"
.Fa "Dwarf_Unsigned *debug_pubtypes"
.Fc
.Ft int
.Fo dwarf_get_section_max_offsets_b
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Unsigned *debug_info"
.Fa "Dwarf_Unsigned *debug_abbrev"
.Fa "Dwarf_Unsigned *debug_line"
.Fa "Dwarf_Unsigned *debug_loc"
.Fa "Dwarf_Unsigned *debug_aranges"
.Fa "Dwarf_Unsigned *debug_macinfo"
.Fa "Dwarf_Unsigned *debug_pubnames"
.Fa "Dwarf_Unsigned *debug_str"
.Fa "Dwarf_Unsigned *debug_frame"
.Fa "Dwarf_Unsigned *debug_ranges"
.Fa "Dwarf_Unsigned *debug_pubtypes"
.Fa "Dwarf_Unsigned *debug_types"
.Fc
.Sh DESCRIPTION
Function
.Fn dwarf_get_section_max_offsets_b
retrieves the sizes of the DWARF sections in a DWARF debug context.
Argument
.Ar dbg
should reference a DWARF debug context allocated using
.Xr dwarf_init 3 .
The function stores the size of each DWARF section to the location
pointed to by the argument corresponding to the section name.
If a DWARF section does not exist, the location pointed to by the
argument corresponding to that section will be set to zero.
.Pp
A value of NULL may be used for any of the arguments
.Ar debug_info ,
.Ar debug_abbrev ,
.Ar debug_line ,
.Ar debug_loc ,
.Ar debug_aranges ,
.Ar debug_macinfo ,
.Ar debug_pubnames ,
.Ar debug_str ,
.Ar debug_frame ,
.Ar debug_ranges ,
.Ar debug_pubtypes
and
.Ar debug_types
if the caller is not interested in the respective section size.
.Pp
Function
.Fn dwarf_get_section_max_offsets
is identical to function
.Fn dwarf_get_section_max_offsets_b
except that it does not provide argument
.Ar debug_types ,
thus it can not retrieve the size of the
.Dq \&.debug_types
section.
.Sh RETURN VALUES
On success, these functions return
.Dv DW_DLV_OK .
If argument
.Ar dbg
is NULL, they return
.Dv DW_DLV_ERROR .
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_init 3

View file

@ -1,4 +1,4 @@
.\" Copyright (c) 2010 Kai Wang
.\" Copyright (c) 2010,2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,9 +22,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_highpc.3 2073 2011-10-27 03:30:47Z jkoshy $
.\" $Id: dwarf_highpc.3 3092 2014-09-02 22:09:30Z kaiwang27 $
.\"
.Dd April 7, 2010
.Dd July 22, 2014
.Os
.Dt DWARF_HIGHPC 3
.Sh NAME
@ -33,6 +33,7 @@
.Nm dwarf_bitsize ,
.Nm dwarf_bytesize ,
.Nm dwarf_highpc ,
.Nm dwarf_highpc_b ,
.Nm dwarf_lowpc ,
.Nm dwarf_srclang
.Nd retrieve the value of a DWARF attribute
@ -71,6 +72,14 @@
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_highpc_b
.Fa "Dwarf_Die die"
.Fa "Dwarf_Addr *ret_highpc"
.Fa "Dwarf_Half *ret_form"
.Fa "enum Dwarf_Form_Class *ret_class"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_lowpc
.Fa "Dwarf_Die die"
.Fa "Dwarf_Addr *ret_lowpc"
@ -114,6 +123,10 @@ attribute value.
Retrieve the
.Dv DW_AT_high_pc
attribute value.
.It Fn dwarf_highpc_b
Retrieve the
.Dv DW_AT_high_pc
attribute value.
.It Fn dwarf_lowpc
Retrieve the
.Dv DW_AT_low_pc
@ -123,6 +136,23 @@ Retrieve the
.Dv DW_AT_language
attribute value.
.El
.Pp
Function
.Fn dwarf_highpc_b
is an enhanced version of function
.Fn dwarf_highpc .
It sets the location specified by argument
.Ar ret_form
to the form code of the attribute
.Dv DW_AT_high_pc ,
and sets the location specified by argument
.Ar ret_class
to the class of that form.
A value of NULL may be used for either of the arguments
.Ar ret_form
or
.Ar ret_class
if the caller is not interested in the respective value.
.Sh RETURN VALUES
These functions return
.Dv DW_DLV_OK on success.
@ -159,4 +189,5 @@ had no requested attribute.
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,
.Xr dwarf_attrlist 3 ,
.Xr dwarf_hasattr 3
.Xr dwarf_hasattr 3 ,
.Xr dwarf_get_form_class 3

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 $");
int
dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount,
@ -75,8 +75,8 @@ dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount,
return (DW_DLV_OK);
}
if ((li->li_lnarray = malloc(*linecount *
sizeof(struct _Dwarf_Line))) == NULL) {
if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) ==
NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLV_ERROR);
}

View file

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009 Kai Wang
* Copyright (c) 2009,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,13 +26,37 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_loclist.c 2074 2011-10-27 03:34:33Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_loclist.c 3066 2014-06-06 19:36:06Z kaiwang27 $");
static int
copy_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *dst, Dwarf_Locdesc *src,
Dwarf_Error *error)
{
assert(src != NULL && dst != NULL);
dst->ld_lopc = src->ld_lopc;
dst->ld_hipc = src->ld_hipc;
dst->ld_cents = src->ld_cents;
if (dst->ld_cents > 0) {
dst->ld_s = calloc(dst->ld_cents, sizeof(Dwarf_Loc));
if (dst->ld_s == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
memcpy(dst->ld_s, src->ld_s, src->ld_cents *
sizeof(Dwarf_Loc));
} else
dst->ld_s = NULL;
return (DW_DLE_NONE);
}
int
dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf,
Dwarf_Signed *listlen, Dwarf_Error *error)
{
Dwarf_Loclist ll;
Dwarf_Debug dbg;
int ret;
@ -69,26 +93,41 @@ dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf,
/* FALLTHROUGH */
case DW_FORM_sec_offset:
ret = _dwarf_loclist_find(dbg, at->at_die->die_cu,
at->u[0].u64, &ll, error);
at->u[0].u64, llbuf, listlen, NULL, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, ret);
return (DW_DLV_NO_ENTRY);
}
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
*llbuf = ll->ll_ldlist;
*listlen = ll->ll_ldlen;
return (DW_DLV_OK);
case DW_FORM_block:
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_exprloc:
if (at->at_ld == NULL) {
ret = _dwarf_loc_add(at->at_die, at, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
}
*llbuf = &at->at_ld;
*llbuf = calloc(1, sizeof(Dwarf_Locdesc *));
if (*llbuf == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLV_ERROR);
}
(*llbuf)[0] = calloc(1, sizeof(Dwarf_Locdesc));
if ((*llbuf)[0] == NULL) {
free(*llbuf);
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLV_ERROR);
}
if (copy_locdesc(dbg, (*llbuf)[0], at->at_ld, error) !=
DW_DLE_NONE) {
free((*llbuf)[0]);
free(*llbuf);
return (DW_DLV_ERROR);
}
*listlen = 1;
return (DW_DLV_OK);
default:
@ -107,75 +146,27 @@ int
dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen, Dwarf_Error *error)
{
Dwarf_Loclist ll;
Dwarf_Debug dbg;
int ret;
Dwarf_Locdesc **_llbuf;
int i, ret;
dbg = at != NULL ? at->at_die->die_dbg : NULL;
ret = dwarf_loclist_n(at, &_llbuf, listlen, error);
if (ret != DW_DLV_OK)
return (ret);
if (at == NULL || llbuf == NULL || listlen == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
/* Only return the first location description of the list. */
*llbuf = _llbuf[0];
/* Free the rest of the list. */
for (i = 1; i < *listlen; i++) {
if (_llbuf[i]->ld_s)
free(_llbuf[i]->ld_s);
free(_llbuf[i]);
}
free(_llbuf);
switch (at->at_attrib) {
case DW_AT_location:
case DW_AT_string_length:
case DW_AT_return_addr:
case DW_AT_data_member_location:
case DW_AT_frame_base:
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
case DW_AT_vtable_elem_location:
switch (at->at_form) {
case DW_FORM_data4:
case DW_FORM_data8:
/*
* DW_FORM_data[48] can not be used as section offset
* since DWARF4. For DWARF[23], the application needs
* to determine if DW_FORM_data[48] is representing
* a constant or a section offset.
*/
if (at->at_die->die_cu->cu_version >= 4) {
printf("called cu_version >= 4\n");
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
/* FALLTHROUGH */
case DW_FORM_sec_offset:
ret = _dwarf_loclist_find(at->at_die->die_dbg,
at->at_die->die_cu, at->u[0].u64, &ll, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
}
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
*llbuf = ll->ll_ldlist[0];
*listlen = 1;
return (DW_DLV_OK);
case DW_FORM_block:
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
if (at->at_ld == NULL) {
ret = _dwarf_loc_add(at->at_die, at, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
}
*llbuf = at->at_ld;
*listlen = 1;
return (DW_DLV_OK);
default:
DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
return (DW_DLV_ERROR);
}
default:
/* Wrong attr supplied. */
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
*listlen = 1;
return (DW_DLV_OK);
}
int
@ -184,19 +175,25 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry,
Dwarf_Error *error)
{
Dwarf_Loclist ll, next_ll;
Dwarf_Locdesc *ld;
Dwarf_Locdesc *ld, **llbuf;
Dwarf_Section *ds;
Dwarf_Signed listlen;
int i, ret;
/*
* Note that this API sometimes will not work correctly because
* it assumes that all units have the same pointer size and offset
* size.
*/
if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL ||
entry_len == NULL || next_entry == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll,
error);
ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset,
&llbuf, &listlen, entry_len, error);
if (ret == DW_DLE_NO_ENTRY) {
DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
return (DW_DLV_NO_ENTRY);
@ -204,8 +201,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
return (DW_DLV_ERROR);
*hipc = *lopc = 0;
for (i = 0; i < ll->ll_ldlen; i++) {
ld = ll->ll_ldlist[i];
for (i = 0; i < listlen; i++) {
ld = llbuf[i];
if (i == 0) {
*hipc = ld->ld_hipc;
*lopc = ld->ld_lopc;
@ -219,14 +216,8 @@ dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
ds = _dwarf_find_section(dbg, ".debug_loc");
assert(ds != NULL);
*data = (uint8_t *) ds->ds_data + ll->ll_offset;
*entry_len = ll->ll_length;
next_ll = TAILQ_NEXT(ll, ll_next);
if (next_ll != NULL)
*next_entry = next_ll->ll_offset;
else
*next_entry = ds->ds_size;
*data = (uint8_t *) ds->ds_data + offset;
*next_entry = offset + *entry_len;
return (DW_DLV_OK);
}
@ -236,30 +227,49 @@ dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen,
Dwarf_Error *error)
{
Dwarf_Locdesc *ld;
int ret;
if (dbg == NULL || bytes_in == NULL || bytes_len == 0 ||
llbuf == NULL || listlen == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len,
dbg->dbg_pointer_size, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);
*llbuf = ld;
*listlen = 1;
return (DW_DLV_OK);
return (dwarf_loclist_from_expr_a(dbg, bytes_in, bytes_len,
dbg->dbg_pointer_size, llbuf, listlen, error));
}
int
dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen, Dwarf_Error *error)
{
Dwarf_Half offset_size;
Dwarf_Small version;
/*
* Obtain offset size and DWARF version from the current
* Compilation Unit or Type Unit. These values are needed
* for correctly parsing DW_OP_GNU_implicit_pointer operator.
*
* Note that dwarf_loclist_from_expr_b() should be used instead
* if the application knows correct values for offset size
* and DWARF version.
*/
if (dbg->dbg_cu_current) {
offset_size = dbg->dbg_cu_current->cu_length_size == 4 ? 4 : 8;
version = dbg->dbg_cu_current->cu_version;
} else if (dbg->dbg_tu_current) {
offset_size = dbg->dbg_tu_current->cu_length_size == 4 ? 4 : 8;
version = dbg->dbg_tu_current->cu_version;
} else {
/* Default values if no CU/TU context. */
offset_size = 4;
version = 2; /* DWARF2 */
}
return (dwarf_loclist_from_expr_b(dbg, bytes_in, bytes_len, addr_size,
offset_size, version, llbuf, listlen, error));
}
int
dwarf_loclist_from_expr_b(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Half offset_size,
Dwarf_Small version, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen,
Dwarf_Error *error)
{
Dwarf_Locdesc *ld;
int ret;
@ -275,8 +285,13 @@ dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
return (DW_DLV_ERROR);
}
if (offset_size != 4 && offset_size != 8) {
DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
return (DW_DLV_ERROR);
}
ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size,
error);
offset_size, version, error);
if (ret != DW_DLE_NONE)
return (DW_DLV_ERROR);

View file

@ -1,4 +1,4 @@
.\" Copyright (c) 2011 Kai Wang
.\" Copyright (c) 2011,2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,14 +22,15 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_loclist_from_expr.3 2074 2011-10-27 03:34:33Z jkoshy $
.\" $Id: dwarf_loclist_from_expr.3 3129 2014-12-21 20:06:26Z jkoshy $
.\"
.Dd July 6, 2011
.Dd December 21, 2014
.Os
.Dt DWARF_LOCLIST_FROM_EXPR 3
.Sh NAME
.Nm dwarf_loclist_from_expr ,
.Nm dwarf_loclist_from_expr_a
.Nm dwarf_loclist_from_expr_a ,
.Nm dwarf_loclist_from_expr_b
.Nd translate DWARF location expression bytes
.Sh LIBRARY
.Lb libdwarf
@ -54,6 +55,18 @@
.Fa "Dwarf_Signed *listlen"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_loclist_from_expr_b
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Ptr bytes_in"
.Fa "Dwarf_Unsigned bytes_len"
.Fa "Dwarf_Half addr_size"
.Fa "Dwarf_Half offset_size"
.Fa "Dwarf_Small version"
.Fa "Dwarf_Locdesc **llbuf"
.Fa "Dwarf_Signed *listlen"
.Fa "Dwarf_Error *error"
.Fc
.Sh DESCRIPTION
Function
.Fn dwarf_loclist_from_expr
@ -104,6 +117,21 @@ except that it requires one additional argument
.Ar addr_size ,
which specifies the address size to use when translating the location
expression bytes.
.Pp
Function
.Fn dwarf_loclist_from_expr_b
is identical to function
.Fn dwarf_loclist_from_expr_a
except that it requires two additional arguments for translating the
location expression bytes.
Argument
.Ar offset_size
specifies the offset size, and argument
.Ar version
specifies the DWARF version.
These values are required to correctly translate the
.Dv DW_OP_GNU_implicit_pointer
opcode.
.Ss Memory Management
The memory area used for the descriptor returned in argument
.Ar llbuf

View file

@ -1,4 +1,4 @@
.\" Copyright (c) 2010 Kai Wang
.\" Copyright (c) 2010,2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,14 +22,15 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_next_cu_header.3 2074 2011-10-27 03:34:33Z jkoshy $
.\" $Id: dwarf_next_cu_header.3 3128 2014-12-21 20:06:22Z jkoshy $
.\"
.Dd July 24, 2010
.Dd December 21, 2014
.Os
.Dt DWARF_NEXT_CU_HEADER 3
.Sh NAME
.Nm dwarf_next_cu_header ,
.Nm dwarf_next_cu_header_b
.Nm dwarf_next_cu_header_b ,
.Nm dwarf_next_cu_header_c
.Nd step through compilation units in a DWARF debug context
.Sh LIBRARY
.Lb libdwarf
@ -57,33 +58,71 @@
.Fa "Dwarf_Unsigned *cu_next_offset"
.Fa "Dwarf_Error *err"
.Fc
.Ft int
.Fo dwarf_next_cu_header_c
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Bool is_info"
.Fa "Dwarf_Unsigned *cu_length"
.Fa "Dwarf_Half *cu_version"
.Fa "Dwarf_Off *cu_abbrev_offset"
.Fa "Dwarf_Half *cu_pointer_size"
.Fa "Dwarf_Half *cu_offset_size"
.Fa "Dwarf_Half *cu_extension_size"
.Fa "Dwarf_Sig8 *type_signature"
.Fa "Dwarf_Unsigned *type_offset"
.Fa "Dwarf_Unsigned *cu_next_offset"
.Fa "Dwarf_Error *err"
.Fc
.Sh DESCRIPTION
These functions are used to step through compilation unit contexts
These functions are used to step through compilation or type units
associated with a DWARF debug context, optionally returning information
about the unit.
.Pp
Function
.Fn dwarf_next_cu_header_b
.Fn dwarf_next_cu_header_c
is the API recommended for new application code.
Function
.Fn dwarf_next_cu_header
and
.Fn dwarf_next_cu_header_b
can only operate on compilation units associated with the
.Dq \&.debug_info
section.
They are less general than function
.Fn dwarf_next_cu_header_c ,
and are deprecated for use by new application code.
.Pp
Argument
.Ar dbg
should reference a DWARF debug context allocated using
.Xr dwarf_init 3 .
If argument
.Ar is_info
is set to 1,
the function returns information for compilation units found in the
.Dq \&.debug_info
section.
If argument
.Ar is_info
is set to 0,
the function returns information for type units found in the
.Dq \&.debug_types
sections.
Argument
.Ar cu_length
should point to a location that will be set to the
length of the compilation unit.
length of the compilation or type unit.
Argument
.Ar cu_version
should point to a location that will be set to the
version number for the compilation unit.
version number for the compilation or type unit.
Argument
.Ar cu_abbrev_offset
should point to a location that will be set to the
starting offset (in the
.Dq .debug_abbrev
section) of the set of debugging information entry abbreviations
associated with this compilation unit.
associated with this compilation or type unit.
Argument
.Ar cu_pointer_size
should point to a location that will be set to the
@ -92,7 +131,7 @@ underlying object being debugged.
Argument
.Ar cu_offset_size
should point to a location that will be set to the
size in bytes for a DWARF offset in the compilation unit.
size in bytes for a DWARF offset in the compilation or type unit.
Argument
.Ar cu_extension_size
is only needed for processing MIPS/IRIX objects that use
@ -100,10 +139,26 @@ a non-standard DWARF format.
It should point to a location that will be set to 4 for normal
objects and to 0 for non-standard ones.
Argument
.Ar type_signature
and
.Ar type_offset
is only needed for processing type units.
Argument
.Ar type_signature
should point to a location that will be set to the 64-bit unique signature
of the type described in the type unit.
Argument
.Ar type_offset
should point to a location that will be set to the offset of the debugging
information entry that describes the type.
Argument
.Ar cu_next_offset
should point to a location that will be set to the
offset of the next compilation unit header in the
.Dq \&.debug_info
section,
or the offset of the next type unit header in the
.Dq \&.debug_types
section.
Argument
.Ar err
@ -111,42 +166,23 @@ should point to a location that will hold an error descriptor in case
of an error.
.Pp
Function
.Fn dwarf_next_cu_header_b
is identical to function
.Fn dwarf_next_cu_header_c
except that it does not provide arguments
.Ar is_info ,
.Ar type_signature
and
.Ar type_offset .
.Pp
Function
.Fn dwarf_next_cu_header
is less general than
.Fn dwarf_next_cu_header_b ,
and is deprecated for use by new application code.
Argument
.Ar dbg
should reference a DWARF debug context allocated using
.Xr dwarf_init 3 .
Argument
.Ar cu_length
should point to a location that will be set to the
length of the compilation unit.
Argument
.Ar cu_version
should point to a location that will be set to the
version number for the compilation unit.
Argument
.Ar cu_abbrev_offset
should point to a location that will be set to the
starting offset in the
.Dq .debug_abbrev
section of the set of debugging information entry abbreviations
associated with this compilation unit.
Argument
.Ar cu_pointer_size
should point to a location that will be set to the
size of an address in bytes for the machine architecture of the
underlying debugging object.
Argument
.Ar cu_next_offset
should point to a location that will be set to the
offset of the next compilation unit.
Argument
.Ar err
should point to a location that will hold an error descriptor in case
of an error.
is identical to function
.Fn dwarf_next_cu_header_b
except that it does not provide arguments
.Ar cu_offset_size
and
.Ar cu_extension_size .
.Pp
A value of NULL may be used for any of the arguments
.Ar cu_length ,
@ -155,30 +191,79 @@ A value of NULL may be used for any of the arguments
.Ar cu_pointer_size ,
.Ar cu_offset_size ,
.Ar cu_extension_size ,
.Ar type_signature ,
.Ar type_offset ,
.Ar cu_next_offset
and
.Ar err
if the caller is not interested in the respective value.
.Ss Iterating Through Compilation Units in a Debug Context
.Pp
The first call to functions
.Fn dwarf_next_cu_header_b
and
.Fn dwarf_next_cu_header
for a given debug context will return information about the first
compilation unit in the debug context.
Subsequent calls to these functions will iterate through the remaining
compilation units in the debug context.
On stepping past the last compilation unit in the debug context,
functions
.Fn dwarf_next_cu_header
and
.Fn dwarf_next_cu_header_b
return
The first call to function
.Fn dwarf_next_cu_header_c
for a given debug context with argument
.Ar is_info
set to 1 will return information about the first
compilation unit in the
.Dq \&.debug_info
section.
Subsequent calls to the function will iterate through the remaining
compilation units in the section.
On stepping past the last compilation unit in the section,
function
.Fn dwarf_next_cu_header_c
returns
.Dv DW_DLV_NO_ENTRY
and reset their internal state.
The next call to these functions will restart from the first compilation
unit in the debug context.
and resets its internal state.
The next call to the function will restart from the first compilation
unit in the section.
.Ss Iterating Through Type Units in a Debug Context
When a DWARF debug context is allocated using
.Xr dwarf_init 3 ,
an internal pointer assoicated with the context will point to the
fisrt
.Dq \&.debug_types
section found in the debug object.
The first call to function
.Fn dwarf_next_cu_header_c
for the debug context with argument
.Ar is_info
set to 0 will return information about the first
type unit in that
.Dq \&.debug_types
section.
Subsequent calls to the function will iterate through the remaining
type units in the section.
On stepping past the last type unit in the debug context,
function
.Fn dwarf_next_cu_header_c
returns
.Dv DW_DLV_NO_ENTRY
and resets its internal state.
The next call to the function will restart from the first type
unit in the
.Dq \&.debug_types
section.
.Pp
If the debug object contains multiple
.Dq \&.debug_types
sections, the function
.Fn dwarf_next_types_section
can be called to move the internal pointer to the next
.Dq \&.debug_types
section.
As a result, subsequent calls of the function
.Fn dwarf_next_cu_header_c
will operate on the new
.Dq \&.debug_types
section.
Function
.Fn dwarf_next_types_section
returns
.Dv DW_DLV_NO_ENTRY
when there are no more
.Dq \&.debug_types
sections left in the debug object.
.Sh RETURN VALUES
On success, these functions return
.Dv DW_DLV_OK .
@ -200,4 +285,5 @@ was NULL.
.Xr dwarf 3 ,
.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 ,
.Xr dwarf_init 3 ,
.Xr dwarf_next_types_section 3 ,
.Xr dwarf_siblingof 3

View file

@ -0,0 +1,134 @@
.\" Copyright (c) 2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: dwarf_next_types_section.3 3116 2014-12-20 18:26:55Z jkoshy $
.\"
.Dd December 20, 2014
.Os
.Dt DWARF_NEXT_TYPES_SECTION 3
.Sh NAME
.Nm dwarf_next_types_section
.Nd step through .debug_types sections in a debug context
.Sh LIBRARY
.Lb libdwarf
.Sh SYNOPSIS
.In libdwarf.h
.Ft int
.Fo dwarf_next_types_section
.Fa "Dwarf_Debug dbg"
.Fa "Dwarf_Error *err"
.Fc
.Sh DESCRIPTION
Function
.Fn dwarf_next_types_section
steps through the
.Dq \&.debug_types
sections found in a debug context.
.Pp
Argument
.Ar dbg
should reference a DWARF debug context allocated using
.Xr dwarf_init 3 .
Argument
.Ar err
should point to a location that will hold an error descriptor in case
of an error.
.Pp
When a DWARF debug context is allocated using
.Xr dwarf_init 3 ,
an internal pointer associated with the context will point to the
first
.Dq \&.debug_types
section present in the debug object.
When the application calls function
.Fn dwarf_next_types_section ,
this internal pointer will move to the next
.Dq \&.debug_types
section present.
On stepping past the last
.Dq \&.debug_types
section left in the debug context, function
.Fn dwarf_next_types_section
returns
.Dv DW_DLV_NO_ENTRY .
The next call to the function will restart from the first
.Dq \&.debug_types
section in the debug context.
.Pp
Application code should call function
.Xr dwarf_next_cu_header_c 3
to iterate though the type units associated with the current
.Dq \&.debug_types
section.
.Sh RETURN VALUES
On success, function
.Fn dwarf_next_types_section
returns
.Dv DW_DLV_OK .
.Pp
In case of an error, it returns
.Dv DW_DLV_ERROR
and sets argument
.Ar err .
When there are no more
.Dq \&.debug_types
sections left to traverse, it returns
.Dv DW_DLV_NO_ENTRY .
.Sh COMPATIBILITY
This function is an extension to the
.Xr DWARF 3
API.
.Sh ERRORS
The
.Fn dwarf_next_types_section
function may fail with the following errors:
.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT"
.It Bq Er DW_DLE_ARGUMENT
Argument
.Va dbg
was NULL.
.El
.Sh EXAMPLES
To iterate though every type unit in all the
.Dq \&.debug_types
sections found in a debug context:
.Bd -literal -offset indent
Dwarf_Debug dbg;
Dwarf_Sig8 sig8;
Dwarf_Unsigned typeoff;
Dwarf_Error de;
\&... allocate dbg using dwarf_init() etc ...
do {
while ((ret = dwarf_next_cu_header_c(dbg, 0, NULL, NULL, NULL,
NULL, NULL, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) {
/* Access DIEs etc ... */
}
} while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK);
.Ed
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_init 3 ,
.Xr dwarf_next_cu_header_c 3

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_ranges.c 2075 2011-10-27 03:47:28Z jkoshy $");
ELFTC_VCSID("$Id: dwarf_ranges.c 3029 2014-04-21 23:26:02Z kaiwang27 $");
static int
_dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Off off,
@ -63,7 +63,7 @@ dwarf_get_ranges(Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Ranges **ranges,
}
if (!dbg->dbg_info_loaded) {
if (_dwarf_info_load(dbg, 1, error) != DW_DLE_NONE)
if (_dwarf_info_load(dbg, 1, 1, error) != DW_DLE_NONE)
return (DW_DLV_ERROR);
}

View file

@ -0,0 +1,111 @@
/*-
* Copyright (c) 2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "_libdwarf.h"
ELFTC_VCSID("$Id: dwarf_sections.c 3036 2014-05-05 19:19:31Z kaiwang27 $");
#define SET(N, V) \
do { \
if ((N) != NULL) \
*(N) = (V); \
} while (0)
int
dwarf_get_section_max_offsets_b(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info,
Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line,
Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges,
Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames,
Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame,
Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes,
Dwarf_Unsigned *debug_types)
{
const char *n;
Dwarf_Unsigned sz;
int i;
if (dbg == NULL)
return (DW_DLV_ERROR);
SET(debug_info, 0);
SET(debug_abbrev, 0);
SET(debug_line, 0);
SET(debug_loc, 0);
SET(debug_aranges, 0);
SET(debug_macinfo, 0);
SET(debug_pubnames, 0);
SET(debug_str, 0);
SET(debug_frame, 0);
SET(debug_ranges, 0);
SET(debug_pubtypes, 0);
SET(debug_types, 0);
for (i = 0; (Dwarf_Unsigned) i < dbg->dbg_seccnt; i++) {
n = dbg->dbg_section[i].ds_name;
sz = dbg->dbg_section[i].ds_size;
if (!strcmp(n, ".debug_info"))
SET(debug_info, sz);
else if (!strcmp(n, ".debug_abbrev"))
SET(debug_abbrev, sz);
else if (!strcmp(n, ".debug_line"))
SET(debug_line, sz);
else if (!strcmp(n, ".debug_loc"))
SET(debug_loc, sz);
else if (!strcmp(n, ".debug_aranges"))
SET(debug_aranges, sz);
else if (!strcmp(n, ".debug_macinfo"))
SET(debug_macinfo, sz);
else if (!strcmp(n, ".debug_pubnames"))
SET(debug_pubnames, sz);
else if (!strcmp(n, ".debug_str"))
SET(debug_str, sz);
else if (!strcmp(n, ".debug_frame"))
SET(debug_frame, sz);
else if (!strcmp(n, ".debug_ranges"))
SET(debug_ranges, sz);
else if (!strcmp(n, ".debug_pubtypes"))
SET(debug_pubtypes, sz);
else if (!strcmp(n, ".debug_types"))
SET(debug_types, sz);
}
return (DW_DLV_OK);
}
int
dwarf_get_section_max_offsets(Dwarf_Debug dbg, Dwarf_Unsigned *debug_info,
Dwarf_Unsigned *debug_abbrev, Dwarf_Unsigned *debug_line,
Dwarf_Unsigned *debug_loc, Dwarf_Unsigned *debug_aranges,
Dwarf_Unsigned *debug_macinfo, Dwarf_Unsigned *debug_pubnames,
Dwarf_Unsigned *debug_str, Dwarf_Unsigned *debug_frame,
Dwarf_Unsigned *debug_ranges, Dwarf_Unsigned *debug_pubtypes)
{
return (dwarf_get_section_max_offsets(dbg, debug_info, debug_abbrev,
debug_line, debug_loc, debug_aranges, debug_macinfo,
debug_pubnames, debug_str, debug_frame, debug_ranges,
debug_pubtypes));
}

View file

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2009-2011 Kai Wang
* Copyright (c) 2009-2011,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: libdwarf.h 2576 2012-09-13 09:16:11Z jkoshy $
* $Id: libdwarf.h 3064 2014-06-06 19:35:55Z kaiwang27 $
*/
#ifndef _LIBDWARF_H_
@ -47,7 +47,6 @@ typedef struct _Dwarf_ArangeSet *Dwarf_ArangeSet;
typedef struct _Dwarf_Attribute *Dwarf_Attribute;
typedef struct _Dwarf_Attribute *Dwarf_P_Attribute;
typedef struct _Dwarf_AttrDef *Dwarf_AttrDef;
typedef struct _Dwarf_CU *Dwarf_CU;
typedef struct _Dwarf_Cie *Dwarf_Cie;
typedef struct _Dwarf_Cie *Dwarf_P_Cie;
typedef struct _Dwarf_Debug *Dwarf_Debug;
@ -60,7 +59,6 @@ typedef struct _Dwarf_FrameSec *Dwarf_FrameSec;
typedef struct _Dwarf_Line *Dwarf_Line;
typedef struct _Dwarf_LineFile *Dwarf_LineFile;
typedef struct _Dwarf_LineInfo *Dwarf_LineInfo;
typedef struct _Dwarf_Loclist *Dwarf_Loclist;
typedef struct _Dwarf_MacroSet *Dwarf_MacroSet;
typedef struct _Dwarf_NamePair *Dwarf_NamePair;
typedef struct _Dwarf_NamePair *Dwarf_Func;
@ -519,6 +517,7 @@ int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *,
Dwarf_Error *);
int dwarf_attrlist(Dwarf_Die, Dwarf_Attribute **,
Dwarf_Signed *, Dwarf_Error *);
int dwarf_attroffset(Dwarf_Attribute, Dwarf_Off *, Dwarf_Error *);
int dwarf_attrval_flag(Dwarf_Die, Dwarf_Half, Dwarf_Bool *,
Dwarf_Error *);
int dwarf_attrval_signed(Dwarf_Die, Dwarf_Half, Dwarf_Signed *,
@ -626,6 +625,9 @@ int dwarf_get_cu_die_offset(Dwarf_Arange, Dwarf_Off *,
Dwarf_Error *);
int dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug,
Dwarf_Off, Dwarf_Off *, Dwarf_Error *);
int dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug,
Dwarf_Off, Dwarf_Bool, Dwarf_Off *, Dwarf_Error *);
Dwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die);
int dwarf_get_elf(Dwarf_Debug, Elf **, Dwarf_Error *);
int dwarf_get_fde_at_pc(Dwarf_Fde *, Dwarf_Addr, Dwarf_Fde *,
Dwarf_Addr *, Dwarf_Addr *, Dwarf_Error *);
@ -678,6 +680,16 @@ int dwarf_get_relocation_info_count(Dwarf_P_Debug, Dwarf_Unsigned *,
int *, Dwarf_Error *);
Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug, Dwarf_Signed,
Dwarf_Signed *, Dwarf_Unsigned *, Dwarf_Error *);
int dwarf_get_section_max_offsets(Dwarf_Debug, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *);
int dwarf_get_section_max_offsets_b(Dwarf_Debug, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Unsigned *);
int dwarf_get_str(Dwarf_Debug, Dwarf_Off, char **, Dwarf_Signed *,
Dwarf_Error *);
int dwarf_get_types(Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *,
@ -700,6 +712,8 @@ int dwarf_hasattr(Dwarf_Die, Dwarf_Half, Dwarf_Bool *,
int dwarf_hasform(Dwarf_Attribute, Dwarf_Half, Dwarf_Bool *,
Dwarf_Error *);
int dwarf_highpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *);
int dwarf_highpc_b(Dwarf_Die, Dwarf_Addr *, Dwarf_Half *,
enum Dwarf_Form_Class *, Dwarf_Error *);
int dwarf_init(int, int, Dwarf_Handler, Dwarf_Ptr, Dwarf_Debug *,
Dwarf_Error *);
int dwarf_line_srcfileno(Dwarf_Line, Dwarf_Unsigned *,
@ -722,6 +736,10 @@ int dwarf_loclist_from_expr(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned,
int dwarf_loclist_from_expr_a(Dwarf_Debug, Dwarf_Ptr,
Dwarf_Unsigned, Dwarf_Half, Dwarf_Locdesc **,
Dwarf_Signed *, Dwarf_Error *);
int dwarf_loclist_from_expr_b(Dwarf_Debug, Dwarf_Ptr,
Dwarf_Unsigned, Dwarf_Half, Dwarf_Half,
Dwarf_Small, Dwarf_Locdesc **, Dwarf_Signed *,
Dwarf_Error *);
int dwarf_loclist_n(Dwarf_Attribute, Dwarf_Locdesc ***,
Dwarf_Signed *, Dwarf_Error *);
int dwarf_lowpc(Dwarf_Die, Dwarf_Addr *, Dwarf_Error *);
@ -735,11 +753,18 @@ int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *,
int dwarf_next_cu_header_b(Dwarf_Debug, Dwarf_Unsigned *,
Dwarf_Half *, Dwarf_Off *, Dwarf_Half *, Dwarf_Half *,
Dwarf_Half *, Dwarf_Unsigned *, Dwarf_Error *);
int dwarf_next_cu_header_c(Dwarf_Debug, Dwarf_Bool,
Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Off *, Dwarf_Half *,
Dwarf_Half *, Dwarf_Half *, Dwarf_Sig8 *, Dwarf_Unsigned *,
Dwarf_Unsigned *, Dwarf_Error *);
int dwarf_next_types_section(Dwarf_Debug, Dwarf_Error *);
int dwarf_object_finish(Dwarf_Debug, Dwarf_Error *);
int dwarf_object_init(Dwarf_Obj_Access_Interface *, Dwarf_Handler,
Dwarf_Ptr, Dwarf_Debug *, Dwarf_Error *);
int dwarf_offdie(Dwarf_Debug, Dwarf_Off, Dwarf_Die *,
Dwarf_Error *);
int dwarf_offdie_b(Dwarf_Debug, Dwarf_Off, Dwarf_Bool, Dwarf_Die *,
Dwarf_Error *);
Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug, Dwarf_Error *);
Dwarf_P_Debug dwarf_producer_init(Dwarf_Unsigned, Dwarf_Callback_Func,
Dwarf_Handler, Dwarf_Ptr, Dwarf_Error *);
@ -765,6 +790,8 @@ int dwarf_set_reloc_application(int);
Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug, Dwarf_Ptr);
Dwarf_Handler dwarf_seterrhand(Dwarf_Debug, Dwarf_Handler);
int dwarf_siblingof(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Error *);
int dwarf_siblingof_b(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Bool,
Dwarf_Error *);
int dwarf_srcfiles(Dwarf_Die, char ***, Dwarf_Signed *, Dwarf_Error *);
int dwarf_srclang(Dwarf_Die, Dwarf_Unsigned *, Dwarf_Error *);
int dwarf_srclines(Dwarf_Die, Dwarf_Line **, Dwarf_Signed *,

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_arange.c 2070 2011-10-27 03:05:32Z jkoshy $");
ELFTC_VCSID("$Id: libdwarf_arange.c 3029 2014-04-21 23:26:02Z kaiwang27 $");
void
_dwarf_arange_cleanup(Dwarf_Debug dbg)
@ -67,7 +67,7 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error)
return (DW_DLE_NONE);
if (!dbg->dbg_info_loaded) {
ret = _dwarf_info_load(dbg, 1, error);
ret = _dwarf_info_load(dbg, 1, 1, error);
if (ret != DW_DLE_NONE)
return (ret);
}
@ -137,8 +137,8 @@ _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error)
/* Build arange array. */
if (dbg->dbg_arange_cnt > 0) {
if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt *
sizeof(struct _Dwarf_Arange))) == NULL) {
if ((dbg->dbg_arange_array = malloc(dbg->dbg_arange_cnt *
sizeof(Dwarf_Arange))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
ret = DW_DLE_MEMORY;
goto fail_cleanup;

View file

@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_attr.c 2966 2013-09-21 14:40:14Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $");
int
_dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error)
@ -106,6 +106,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp,
ret = DW_DLE_NONE;
memset(&atref, 0, sizeof(atref));
atref.at_die = die;
atref.at_offset = *offsetp;
atref.at_attrib = ad->ad_attrib;
atref.at_form = indirect ? form : ad->ad_form;
atref.at_indirect = indirect;
@ -162,7 +163,7 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp,
if (cu->cu_version == 2)
atref.u[0].u64 = dbg->read(ds->ds_data, offsetp,
cu->cu_pointer_size);
else if (cu->cu_version == 3)
else
atref.u[0].u64 = dbg->read(ds->ds_data, offsetp,
dwarf_size);
break;

View file

@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_die.c 2948 2013-05-30 21:25:52Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $");
int
_dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error)
@ -81,6 +81,7 @@ Dwarf_Die
_dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off)
{
Dwarf_Debug dbg;
Dwarf_Section *ds;
Dwarf_CU cu;
Dwarf_Die die1;
Dwarf_Error de;
@ -88,9 +89,10 @@ _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off)
cu = die->die_cu;
dbg = die->die_dbg;
ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec;
ret = _dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size,
off, cu->cu_next_offset, &die1, 0, &de);
ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off,
cu->cu_next_offset, &die1, 0, &de);
if (ret == DW_DLE_NONE)
return (die1);

View file

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2009-2011 Kai Wang
* Copyright (c) 2009-2011,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_frame.c 2529 2012-07-29 23:31:12Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_frame.c 3106 2014-12-19 16:00:58Z kaiwang27 $");
static int
_dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset,
@ -49,8 +49,9 @@ _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset,
}
static int
_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data,
uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, Dwarf_Error *error)
_dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val,
uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc,
Dwarf_Error *error)
{
uint8_t application;
@ -62,7 +63,7 @@ _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, uint64_t *val, uint8_t *data,
switch (encode) {
case DW_EH_PE_absptr:
*val = dbg->read(data, offsetp, dbg->dbg_pointer_size);
*val = dbg->read(data, offsetp, cie->cie_addrsize);
break;
case DW_EH_PE_uleb128:
*val = _dwarf_read_uleb128(data, offsetp);
@ -149,7 +150,7 @@ _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie,
/* Skip two augments in augment data. */
encode = *augdata_p++;
offset = 0;
ret = _dwarf_frame_read_lsb_encoded(dbg, &val,
ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val,
augdata_p, &offset, encode, 0, error);
if (ret != DW_DLE_NONE)
return (ret);
@ -233,6 +234,18 @@ _dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds,
cie->cie_ehdata = dbg->read(ds->ds_data, off,
dbg->dbg_pointer_size);
/* DWARF4 added "address_size" and "segment_size". */
if (cie->cie_version == 4) {
cie->cie_addrsize = dbg->read(ds->ds_data, off, 1);
cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1);
} else {
/*
* Otherwise (DWARF[23]) we just set CIE addrsize to the
* debug context pointer size.
*/
cie->cie_addrsize = dbg->dbg_pointer_size;
}
cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off);
cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off);
@ -345,8 +358,9 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds,
* The FDE PC start/range for .eh_frame is encoded according
* to the LSB spec's extension to DWARF2.
*/
ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data,
off, cie->cie_fde_encode, ds->ds_addr + *off, error);
ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val,
ds->ds_data, off, cie->cie_fde_encode, ds->ds_addr + *off,
error);
if (ret != DW_DLE_NONE)
return (ret);
fde->fde_initloc = val;
@ -354,16 +368,16 @@ _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds,
* FDE PC range should not be relative value to anything.
* So pass 0 for pc value.
*/
ret = _dwarf_frame_read_lsb_encoded(dbg, &val, ds->ds_data,
off, cie->cie_fde_encode, 0, error);
ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val,
ds->ds_data, off, cie->cie_fde_encode, 0, error);
if (ret != DW_DLE_NONE)
return (ret);
fde->fde_adrange = val;
} else {
fde->fde_initloc = dbg->read(ds->ds_data, off,
dbg->dbg_pointer_size);
cie->cie_addrsize);
fde->fde_adrange = dbg->read(ds->ds_data, off,
dbg->dbg_pointer_size);
cie->cie_addrsize);
}
/* Optional FDE augmentation data for .eh_frame section. (ignored) */
@ -530,9 +544,9 @@ _dwarf_frame_section_init(Dwarf_Debug dbg, Dwarf_FrameSec *frame_sec,
}
static int
_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts,
Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc,
Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error)
_dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size,
uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf,
Dwarf_Addr pc, Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error)
{
Dwarf_Regtable3 *init_rt, *saved_rt;
uint8_t *p, *pe;
@ -632,7 +646,7 @@ _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts,
switch (low6) {
case DW_CFA_set_loc:
pc = dbg->decode(&p, dbg->dbg_pointer_size);
pc = dbg->decode(&p, addr_size);
#ifdef FRAME_DEBUG
printf("DW_CFA_set_loc(pc=%#jx)\n", pc);
#endif
@ -898,14 +912,13 @@ _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t *insts,
}
static int
_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, Dwarf_Frame_Op3 *fop3,
Dwarf_Error *error)
_dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts,
Dwarf_Unsigned len, Dwarf_Unsigned *count, Dwarf_Frame_Op *fop,
Dwarf_Frame_Op3 *fop3, Dwarf_Error *error)
{
uint8_t *p, *pe;
uint8_t high2, low6;
uint64_t reg, reg2, uoff, soff, blen;
int ret;
#define SET_BASE_OP(x) \
do { \
@ -970,7 +983,6 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
} \
} while(0)
ret = DW_DLE_NONE;
*count = 0;
p = insts;
@ -1020,7 +1032,7 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
switch (low6) {
case DW_CFA_set_loc:
uoff = dbg->decode(&p, dbg->dbg_pointer_size);
uoff = dbg->decode(&p, addr_size);
SET_OFFSET(uoff);
break;
case DW_CFA_advance_loc1:
@ -1103,15 +1115,16 @@ _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
}
int
_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, Dwarf_Error *error)
_dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts,
Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt,
Dwarf_Error *error)
{
Dwarf_Frame_Op *oplist;
Dwarf_Unsigned count;
int ret;
ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, NULL, NULL,
error);
ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count,
NULL, NULL, error);
if (ret != DW_DLE_NONE)
return (ret);
@ -1120,8 +1133,8 @@ _dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t *insts, Dwarf_Unsigned len,
return (DW_DLE_MEMORY);
}
ret = _dwarf_frame_convert_inst(dbg, insts, len, &count, oplist, NULL,
error);
ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count,
oplist, NULL, error);
if (ret != DW_DLE_NONE) {
free(oplist);
return (ret);
@ -1201,17 +1214,17 @@ _dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req,
/* Run initial instructions in CIE. */
cie = fde->fde_cie;
assert(cie != NULL);
ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_initinst,
cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, ~0ULL,
&row_pc, error);
ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize,
cie->cie_initinst, cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0,
~0ULL, &row_pc, error);
if (ret != DW_DLE_NONE)
return (ret);
/* Run instructions in FDE. */
if (pc_req >= fde->fde_initloc) {
ret = _dwarf_frame_run_inst(dbg, rt, fde->fde_inst,
fde->fde_instlen, cie->cie_caf, cie->cie_daf,
fde->fde_initloc, pc_req, &row_pc, error);
ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize,
fde->fde_inst, fde->fde_instlen, cie->cie_caf,
cie->cie_daf, fde->fde_initloc, pc_req, &row_pc, error);
if (ret != DW_DLE_NONE)
return (ret);
}

View file

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2010,2011 Kai Wang
* Copyright (c) 2010,2011,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_info.c 2942 2013-05-04 23:03:54Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_info.c 3041 2014-05-18 15:11:03Z kaiwang27 $");
int
_dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error)
@ -46,7 +46,7 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error)
return (DW_DLE_NO_ENTRY);
dbg->dbg_info_off = 0;
ret = _dwarf_info_load(dbg, 0, error);
ret = _dwarf_info_load(dbg, 0, 1, error);
if (ret != DW_DLE_NONE)
return (ret);
@ -55,6 +55,32 @@ _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error)
return (DW_DLE_NONE);
}
int
_dwarf_info_first_tu(Dwarf_Debug dbg, Dwarf_Error *error)
{
Dwarf_CU tu;
int ret;
assert(dbg->dbg_tu_current == NULL);
tu = STAILQ_FIRST(&dbg->dbg_tu);
if (tu != NULL) {
dbg->dbg_tu_current = tu;
return (DW_DLE_NONE);
}
if (dbg->dbg_types_loaded)
return (DW_DLE_NO_ENTRY);
dbg->dbg_types_off = 0;
ret = _dwarf_info_load(dbg, 0, 0, error);
if (ret != DW_DLE_NONE)
return (ret);
dbg->dbg_tu_current = STAILQ_FIRST(&dbg->dbg_tu);
return (DW_DLE_NONE);
}
int
_dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error)
{
@ -73,7 +99,7 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error)
return (DW_DLE_NO_ENTRY);
}
ret = _dwarf_info_load(dbg, 0, error);
ret = _dwarf_info_load(dbg, 0, 1, error);
if (ret != DW_DLE_NONE)
return (ret);
@ -83,7 +109,35 @@ _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error)
}
int
_dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
_dwarf_info_next_tu(Dwarf_Debug dbg, Dwarf_Error *error)
{
Dwarf_CU cu;
int ret;
assert(dbg->dbg_tu_current != NULL);
cu = STAILQ_NEXT(dbg->dbg_tu_current, cu_next);
if (cu != NULL) {
dbg->dbg_tu_current = cu;
return (DW_DLE_NONE);
}
if (dbg->dbg_types_loaded) {
dbg->dbg_tu_current = NULL;
return (DW_DLE_NO_ENTRY);
}
ret = _dwarf_info_load(dbg, 0, 0, error);
if (ret != DW_DLE_NONE)
return (ret);
dbg->dbg_tu_current = STAILQ_NEXT(dbg->dbg_tu_current, cu_next);
return (DW_DLE_NONE);
}
int
_dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info,
Dwarf_Error *error)
{
Dwarf_CU cu;
Dwarf_Section *ds;
@ -93,12 +147,22 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
uint64_t offset;
ret = DW_DLE_NONE;
if (dbg->dbg_info_loaded)
return (DW_DLE_NONE);
offset = dbg->dbg_info_off;
ds = dbg->dbg_info_sec;
assert(ds != NULL);
if (is_info) {
if (dbg->dbg_info_loaded)
return (ret);
offset = dbg->dbg_info_off;
ds = dbg->dbg_info_sec;
assert(ds != NULL);
} else {
if (dbg->dbg_types_loaded)
return (ret);
offset = dbg->dbg_types_off;
ds = dbg->dbg_types_sec;
if (ds == NULL)
return (DW_DLE_NO_ENTRY);
}
while (offset < ds->ds_size) {
if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
@ -106,6 +170,7 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
}
cu->cu_dbg = dbg;
cu->cu_is_info = is_info;
cu->cu_offset = offset;
length = dbg->read(ds->ds_data, &offset, 4);
@ -129,7 +194,10 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
/* Compute the offset to the next compilation unit: */
next_offset = offset + length;
dbg->dbg_info_off = next_offset;
if (is_info)
dbg->dbg_info_off = next_offset;
else
dbg->dbg_types_off = next_offset;
/* Initialise the compilation unit. */
cu->cu_length = length;
@ -141,8 +209,20 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1);
cu->cu_next_offset = next_offset;
/* .debug_types extra fields. */
if (!is_info) {
memcpy(cu->cu_type_sig.signature,
(char *) ds->ds_data + offset, 8);
offset += 8;
cu->cu_type_offset = dbg->read(ds->ds_data, &offset,
dwarf_size);
}
/* Add the compilation unit to the list. */
STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
if (is_info)
STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
else
STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next);
if (cu->cu_version < 2 || cu->cu_version > 4) {
DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
@ -158,8 +238,13 @@ _dwarf_info_load(Dwarf_Debug dbg, int load_all, Dwarf_Error *error)
break;
}
if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size)
dbg->dbg_info_loaded = 1;
if (is_info) {
if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size)
dbg->dbg_info_loaded = 1;
} else {
if ((Dwarf_Unsigned) dbg->dbg_types_off >= ds->ds_size)
dbg->dbg_types_loaded = 1;
}
return (ret);
}
@ -180,6 +265,22 @@ _dwarf_info_cleanup(Dwarf_Debug dbg)
}
free(cu);
}
_dwarf_type_unit_cleanup(dbg);
}
void
_dwarf_type_unit_cleanup(Dwarf_Debug dbg)
{
Dwarf_CU cu, tcu;
assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
STAILQ_FOREACH_SAFE(cu, &dbg->dbg_tu, cu_next, tcu) {
STAILQ_REMOVE(&dbg->dbg_tu, cu, _Dwarf_CU, cu_next);
_dwarf_abbrev_cleanup(cu);
free(cu);
}
}
int

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_init.c 3061 2014-06-02 00:42:41Z kaiwang27 $");
static int
_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
@ -69,7 +69,8 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
dbg->dbg_seccnt = cnt;
if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) {
if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) ==
NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
@ -90,6 +91,7 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
return (ret);
}
}
dbg->dbg_section[cnt].ds_name = NULL;
if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL ||
((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) ==
@ -98,6 +100,9 @@ _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
return (DW_DLE_DEBUG_INFO_NULL);
}
/* Try to find the optional DWARF4 .debug_types section. */
dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL);
/* Initialise call frame API related parameters. */
_dwarf_frame_params_init(dbg);
@ -210,10 +215,10 @@ _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand,
dbg->dbg_errarg = errarg;
STAILQ_INIT(&dbg->dbg_cu);
STAILQ_INIT(&dbg->dbg_tu);
STAILQ_INIT(&dbg->dbg_rllist);
STAILQ_INIT(&dbg->dbg_aslist);
STAILQ_INIT(&dbg->dbg_mslist);
TAILQ_INIT(&dbg->dbg_loclist);
if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) {
ret = _dwarf_consumer_init(dbg, error);
@ -270,7 +275,6 @@ _dwarf_consumer_deinit(Dwarf_Debug dbg)
assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
_dwarf_info_cleanup(dbg);
_dwarf_loclist_cleanup(dbg);
_dwarf_ranges_cleanup(dbg);
_dwarf_frame_cleanup(dbg);
_dwarf_arange_cleanup(dbg);

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_lineno.c 2972 2013-12-23 06:46:04Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_lineno.c 3100 2014-10-25 20:34:29Z jkoshy $");
static int
_dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir,
@ -87,9 +87,8 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p,
{
Dwarf_Debug dbg;
Dwarf_Line ln, tln;
uint64_t address, file, line, column, isa, opsize;
uint64_t address, file, line, column, opsize;
int is_stmt, basic_block, end_sequence;
int prologue_end, epilogue_begin;
int ret;
#define RESET_REGISTERS \
@ -101,8 +100,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p,
is_stmt = li->li_defstmt; \
basic_block = 0; \
end_sequence = 0; \
prologue_end = 0; \
epilogue_begin = 0; \
} while(0)
#define APPEND_ROW \
@ -181,8 +178,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p,
case DW_LNS_copy:
APPEND_ROW;
basic_block = 0;
prologue_end = 0;
epilogue_begin = 0;
break;
case DW_LNS_advance_pc:
address += _dwarf_decode_uleb128(&p) *
@ -210,13 +205,11 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p,
address += dbg->decode(&p, 2);
break;
case DW_LNS_set_prologue_end:
prologue_end = 1;
break;
case DW_LNS_set_epilogue_begin:
epilogue_begin = 1;
break;
case DW_LNS_set_isa:
isa = _dwarf_decode_uleb128(&p);
(void) _dwarf_decode_uleb128(&p);
break;
default:
/* Unrecognized extened opcodes. What to do? */
@ -233,8 +226,6 @@ _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p,
address += ADDRESS(*p);
APPEND_ROW;
basic_block = 0;
prologue_end = 0;
epilogue_begin = 0;
p++;
}
}
@ -482,7 +473,7 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds,
Dwarf_Unsigned address, file, line, spc;
Dwarf_Unsigned addr0, maddr;
Dwarf_Signed line0, column;
int is_stmt, basic_block, end_sequence;
int is_stmt, basic_block;
int need_copy;
int ret;
@ -494,7 +485,6 @@ _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds,
column = 0; \
is_stmt = li->li_defstmt; \
basic_block = 0; \
end_sequence = 0; \
} while(0)
li = dbg->dbgp_lineinfo;

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2007 John Birrell (jb@freebsd.org)
* Copyright (c) 2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $");
ELFTC_VCSID("$Id: libdwarf_loc.c 3070 2014-06-23 03:08:33Z kaiwang27 $");
/*
* Given an array of bytes of length 'len' representing a
@ -38,12 +39,12 @@ ELFTC_VCSID("$Id: libdwarf_loc.c 2070 2011-10-27 03:05:32Z jkoshy $");
*/
static int
_dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
uint8_t *p, int len)
uint8_t offset_size, uint8_t version, uint8_t *p, int len)
{
int count;
uint64_t operand1;
uint64_t operand2;
uint8_t *ps, *pe;
uint8_t *ps, *pe, s;
count = 0;
ps = p;
@ -165,37 +166,49 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
case DW_OP_ne:
case DW_OP_nop:
case DW_OP_push_object_address:
case DW_OP_form_tls_address:
case DW_OP_call_frame_cfa:
case DW_OP_stack_value:
case DW_OP_GNU_push_tls_address:
case DW_OP_GNU_uninit:
break;
/* Operations with 1-byte operands. */
case DW_OP_const1u:
case DW_OP_const1s:
case DW_OP_pick:
case DW_OP_deref_size:
case DW_OP_xderef_size:
operand1 = *p++;
break;
case DW_OP_const1s:
operand1 = (int8_t) *p++;
break;
/* Operations with 2-byte operands. */
case DW_OP_call2:
case DW_OP_const2u:
case DW_OP_const2s:
case DW_OP_bra:
case DW_OP_skip:
operand1 = dbg->decode(&p, 2);
break;
case DW_OP_const2s:
operand1 = (int16_t) dbg->decode(&p, 2);
break;
/* Operations with 4-byte operands. */
case DW_OP_call4:
case DW_OP_const4u:
case DW_OP_const4s:
case DW_OP_GNU_parameter_ref:
operand1 = dbg->decode(&p, 4);
break;
case DW_OP_const4s:
operand1 = (int32_t) dbg->decode(&p, 4);
break;
/* Operations with 8-byte operands. */
case DW_OP_const8u:
case DW_OP_const8s:
@ -207,6 +220,9 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
case DW_OP_plus_uconst:
case DW_OP_regx:
case DW_OP_piece:
case DW_OP_GNU_deref_type:
case DW_OP_GNU_convert:
case DW_OP_GNU_reinterpret:
operand1 = _dwarf_decode_uleb128(&p);
break;
@ -252,6 +268,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
* Oeration with two unsigned LEB128 operands.
*/
case DW_OP_bit_piece:
case DW_OP_GNU_regval_type:
operand1 = _dwarf_decode_uleb128(&p);
operand2 = _dwarf_decode_uleb128(&p);
break;
@ -267,10 +284,14 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
/*
* Operation with an unsigned LEB128 operand
* followed by a block. Store a pointer to the
* block in the operand2.
* representing the size of a block, followed
* by the block content.
*
* Store the size of the block in the operand1
* and a pointer to the block in the operand2.
*/
case DW_OP_implicit_value:
case DW_OP_GNU_entry_value:
operand1 = _dwarf_decode_uleb128(&p);
operand2 = (Dwarf_Unsigned) (uintptr_t) p;
p += operand1;
@ -278,25 +299,59 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
/* Target address size operand. */
case DW_OP_addr:
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
operand1 = dbg->decode(&p, pointer_size);
break;
/*
* XXX Opcode DW_OP_call_ref has an operand with size
* "dwarf_size". Here we use dbg->dbg_offset_size
* as "dwarf_size" to be compatible with SGI libdwarf.
* However note that dbg->dbg_offset_size is just
* a "guess" value so the parsing result of
* DW_OP_call_ref might not be correct at all. XXX
*/
/* Offset size operand. */
case DW_OP_call_ref:
operand1 = dbg->decode(&p, dbg->dbg_offset_size);
operand1 = dbg->decode(&p, offset_size);
break;
/*
* The first byte is address byte length, followed by
* the address value. If the length is 0, the address
* size is the same as target pointer size.
*/
case DW_OP_GNU_encoded_addr:
s = *p++;
if (s == 0)
s = pointer_size;
operand1 = dbg->decode(&p, s);
break;
/*
* Operand1: DIE offset (size depending on DWARF version)
* DWARF2: pointer size
* DWARF{3,4}: offset size
*
* Operand2: SLEB128
*/
case DW_OP_GNU_implicit_pointer:
if (version == 2)
operand1 = dbg->decode(&p, pointer_size);
else
operand1 = dbg->decode(&p, offset_size);
operand2 = _dwarf_decode_sleb128(&p);
break;
/*
* Operand1: DIE offset (ULEB128)
* Operand2: pointer to a block. The block's first byte
* is its size.
*/
case DW_OP_GNU_const_type:
operand1 = _dwarf_decode_uleb128(&p);
operand2 = (Dwarf_Unsigned) (uintptr_t) p;
s = *p++;
p += s;
break;
/* All other operations cause an error. */
default:
count = -1;
break;
goto done;
}
if (lbuf != NULL) {
@ -307,6 +362,7 @@ _dwarf_loc_fill_loc(Dwarf_Debug dbg, Dwarf_Locdesc *lbuf, uint8_t pointer_size,
count++;
}
done:
return (count);
}
@ -561,7 +617,8 @@ _dwarf_loc_expr_add_atom(Dwarf_Debug dbg, uint8_t *out, uint8_t *end,
int
_dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in,
uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error)
uint64_t in_len, uint8_t pointer_size, uint8_t offset_size,
uint8_t version, Dwarf_Error *error)
{
int num;
@ -570,8 +627,8 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in,
assert(in_len > 0);
/* Compute the number of locations. */
if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, in, in_len)) <
0) {
if ((num = _dwarf_loc_fill_loc(dbg, NULL, pointer_size, offset_size,
version, in, in_len)) < 0) {
DWARF_SET_ERROR(dbg, error, DW_DLE_LOC_EXPR_BAD);
return (DW_DLE_LOC_EXPR_BAD);
}
@ -585,14 +642,16 @@ _dwarf_loc_fill_locdesc(Dwarf_Debug dbg, Dwarf_Locdesc *llbuf, uint8_t *in,
return (DW_DLE_MEMORY);
}
(void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, in, in_len);
(void) _dwarf_loc_fill_loc(dbg, llbuf, pointer_size, offset_size,
version, in, in_len);
return (DW_DLE_NONE);
}
int
_dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in,
uint64_t in_len, uint8_t pointer_size, Dwarf_Error *error)
uint64_t in_len, uint8_t pointer_size, uint8_t offset_size,
uint8_t version, Dwarf_Error *error)
{
Dwarf_Locdesc *llbuf;
int ret;
@ -606,7 +665,7 @@ _dwarf_loc_fill_locexpr(Dwarf_Debug dbg, Dwarf_Locdesc **ret_llbuf, uint8_t *in,
llbuf->ld_s = NULL;
ret = _dwarf_loc_fill_locdesc(dbg, llbuf, in, in_len, pointer_size,
error);
offset_size, version, error);
if (ret != DW_DLE_NONE) {
free(llbuf);
return (ret);
@ -635,7 +694,8 @@ _dwarf_loc_add(Dwarf_Die die, Dwarf_Attribute at, Dwarf_Error *error)
assert(dbg != NULL);
ret = _dwarf_loc_fill_locexpr(dbg, &at->at_ld, at->u[1].u8p,
at->u[0].u64, cu->cu_pointer_size, error);
at->u[0].u64, cu->cu_pointer_size, cu->cu_length_size == 4 ? 4 : 8,
cu->cu_version, error);
return (ret);
}

View file

@ -26,11 +26,11 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_loclist.c 2972 2013-12-23 06:46:04Z kaiwang27 $");
ELFTC_VCSID("$Id: libdwarf_loclist.c 3061 2014-06-02 00:42:41Z kaiwang27 $");
static int
_dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
uint64_t *off, Dwarf_Locdesc **ld, uint64_t *ldlen,
Dwarf_Unsigned *off, Dwarf_Locdesc **ld, Dwarf_Signed *ldlen,
Dwarf_Unsigned *total_len, Dwarf_Error *error)
{
uint64_t start, end;
@ -75,6 +75,7 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
if (ld != NULL) {
ret = _dwarf_loc_fill_locdesc(dbg, ld[i],
ds->ds_data + *off, len, cu->cu_pointer_size,
cu->cu_length_size == 4 ? 4 : 8, cu->cu_version,
error);
if (ret != DW_DLE_NONE)
return (ret);
@ -91,37 +92,15 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
int
_dwarf_loclist_find(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff,
Dwarf_Loclist *ret_ll, Dwarf_Error *error)
{
Dwarf_Loclist ll;
int ret;
assert(ret_ll != NULL);
ret = DW_DLE_NONE;
TAILQ_FOREACH(ll, &dbg->dbg_loclist, ll_next)
if (ll->ll_offset == lloff)
break;
if (ll == NULL)
ret = _dwarf_loclist_add(dbg, cu, lloff, ret_ll, error);
else
*ret_ll = ll;
return (ret);
}
int
_dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff,
Dwarf_Loclist *ret_ll, Dwarf_Error *error)
Dwarf_Locdesc ***ret_llbuf, Dwarf_Signed *listlen,
Dwarf_Unsigned *entry_len, Dwarf_Error *error)
{
Dwarf_Locdesc **llbuf;
Dwarf_Section *ds;
Dwarf_Loclist ll, tll;
uint64_t ldlen;
Dwarf_Signed ldlen;
Dwarf_Unsigned off;
int i, ret;
ret = DW_DLE_NONE;
if ((ds = _dwarf_find_section(dbg, ".debug_loc")) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLE_NO_ENTRY);
@ -132,98 +111,55 @@ _dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff,
return (DW_DLE_NO_ENTRY);
}
if ((ll = malloc(sizeof(struct _Dwarf_Loclist))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
ll->ll_offset = lloff;
/* Get the number of locdesc the first round. */
ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, NULL, &ldlen,
off = lloff;
ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, NULL, &ldlen,
NULL, error);
if (ret != DW_DLE_NONE)
goto fail_cleanup;
return (ret);
if (ldlen == 0)
return (DW_DLE_NO_ENTRY);
/*
* Dwarf_Locdesc list memory is allocated in this way (one more level
* of indirect) to make the loclist API be compatible with SGI libdwarf.
*/
ll->ll_ldlen = ldlen;
if (ldlen != 0) {
if ((ll->ll_ldlist = calloc(ldlen, sizeof(Dwarf_Locdesc *))) ==
NULL) {
if ((llbuf = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
return (DW_DLE_MEMORY);
}
for (i = 0; i < ldlen; i++) {
if ((llbuf[i] = calloc(1, sizeof(Dwarf_Locdesc))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
ret = DW_DLE_MEMORY;
goto fail_cleanup;
}
for (i = 0; (uint64_t) i < ldlen; i++) {
if ((ll->ll_ldlist[i] =
calloc(1, sizeof(Dwarf_Locdesc))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
ret = DW_DLE_MEMORY;
goto fail_cleanup;
}
}
} else
ll->ll_ldlist = NULL;
}
lloff = ll->ll_offset;
off = lloff;
/* Fill in locdesc. */
ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, ll->ll_ldlist,
NULL, &ll->ll_length, error);
ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, llbuf, NULL,
entry_len, error);
if (ret != DW_DLE_NONE)
goto fail_cleanup;
/* Insert to the queue. Sort by offset. */
TAILQ_FOREACH(tll, &dbg->dbg_loclist, ll_next)
if (tll->ll_offset > ll->ll_offset) {
TAILQ_INSERT_BEFORE(tll, ll, ll_next);
break;
}
*ret_llbuf = llbuf;
*listlen = ldlen;
if (tll == NULL)
TAILQ_INSERT_TAIL(&dbg->dbg_loclist, ll, ll_next);
*ret_ll = ll;
return (DW_DLE_NONE);
fail_cleanup:
_dwarf_loclist_free(ll);
if (llbuf != NULL) {
for (i = 0; i < ldlen; i++) {
if (llbuf[i]->ld_s)
free(llbuf[i]->ld_s);
free(llbuf[i]);
}
free(llbuf);
}
return (ret);
}
void
_dwarf_loclist_free(Dwarf_Loclist ll)
{
int i;
if (ll == NULL)
return;
if (ll->ll_ldlist != NULL) {
for (i = 0; i < ll->ll_ldlen; i++) {
if (ll->ll_ldlist[i]->ld_s)
free(ll->ll_ldlist[i]->ld_s);
free(ll->ll_ldlist[i]);
}
free(ll->ll_ldlist);
}
free(ll);
}
void
_dwarf_loclist_cleanup(Dwarf_Debug dbg)
{
Dwarf_Loclist ll, tll;
assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
TAILQ_FOREACH_SAFE(ll, &dbg->dbg_loclist, ll_next, tll) {
TAILQ_REMOVE(&dbg->dbg_loclist, ll, ll_next);
_dwarf_loclist_free(ll);
}
}

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_nametbl.c 2070 2011-10-27 03:05:32Z jkoshy $");
ELFTC_VCSID("$Id: libdwarf_nametbl.c 3029 2014-04-21 23:26:02Z kaiwang27 $");
void
_dwarf_nametbl_cleanup(Dwarf_NameSec *nsp)
@ -103,7 +103,7 @@ _dwarf_nametbl_init(Dwarf_Debug dbg, Dwarf_NameSec *namesec, Dwarf_Section *ds,
nt->nt_cu_length = dbg->read(ds->ds_data, &offset, dwarf_size);
if (!dbg->dbg_info_loaded) {
ret = _dwarf_info_load(dbg, 1, error);
ret = _dwarf_info_load(dbg, 1, 1, error);
if (ret != DW_DLE_NONE)
goto fail_cleanup;
}

View file

@ -26,7 +26,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_sections.c 2379 2012-01-05 02:08:20Z jkoshy $");
ELFTC_VCSID("$Id: libdwarf_sections.c 3041 2014-05-18 15:11:03Z kaiwang27 $");
#define _SECTION_INIT_SIZE 128
@ -212,7 +212,7 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name)
Dwarf_Section *ds;
Dwarf_Half i;
assert(name != NULL);
assert(dbg != NULL && name != NULL);
for (i = 0; i < dbg->dbg_seccnt; i++) {
ds = &dbg->dbg_section[i];
@ -223,6 +223,27 @@ _dwarf_find_section(Dwarf_Debug dbg, const char *name)
return (NULL);
}
Dwarf_Section *
_dwarf_find_next_types_section(Dwarf_Debug dbg, Dwarf_Section *ds)
{
assert(dbg != NULL);
if (ds == NULL)
return (_dwarf_find_section(dbg, ".debug_types"));
assert(ds->ds_name != NULL);
do {
ds++;
if (ds->ds_name != NULL &&
!strcmp(ds->ds_name, ".debug_types"))
return (ds);
} while (ds->ds_name != NULL);
return (NULL);
}
Dwarf_P_Section
_dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name)
{

View file

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libelf.h 2365 2011-12-29 04:36:44Z jkoshy $
* $Id: _libelf.h 3011 2014-03-23 03:32:42Z jkoshy $
*/
#ifndef __LIBELF_H_
@ -48,7 +48,7 @@ struct _libelf_globals {
int libelf_error;
int libelf_fillchar;
unsigned int libelf_version;
char libelf_msg[LIBELF_MSG_SIZE];
unsigned char libelf_msg[LIBELF_MSG_SIZE];
};
extern struct _libelf_globals _libelf;
@ -71,14 +71,14 @@ extern struct _libelf_globals _libelf;
* Flags for library internal use. These use the upper 16 bits of the
* `e_flags' field.
*/
#define LIBELF_F_API_MASK 0x00FFFF /* Flags defined by the API. */
#define LIBELF_F_AR_HEADER 0x010000 /* translated header available */
#define LIBELF_F_AR_VARIANT_SVR4 0x020000 /* BSD style ar(1) archive */
#define LIBELF_F_DATA_MALLOCED 0x040000 /* whether data was malloc'ed */
#define LIBELF_F_RAWFILE_MALLOC 0x080000 /* whether e_rawfile was malloc'ed */
#define LIBELF_F_RAWFILE_MMAP 0x100000 /* whether e_rawfile was mmap'ed */
#define LIBELF_F_SHDRS_LOADED 0x200000 /* whether all shdrs were read in */
#define LIBELF_F_SPECIAL_FILE 0x400000 /* non-regular file */
#define LIBELF_F_API_MASK 0x00FFFFU /* Flags defined by the API. */
#define LIBELF_F_AR_HEADER 0x010000U /* translated header available */
#define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */
#define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */
#define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */
#define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */
#define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */
#define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */
struct _Elf {
int e_activations; /* activation count */
@ -89,7 +89,7 @@ struct _Elf {
unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */
Elf_Kind e_kind; /* ELF_K_* */
Elf *e_parent; /* non-NULL for archive members */
char *e_rawfile; /* uninterpreted bytes */
unsigned char *e_rawfile; /* uninterpreted bytes */
size_t e_rawsize; /* size of uninterpreted bytes */
unsigned int e_version; /* file version */
@ -99,16 +99,16 @@ struct _Elf {
*/
union {
Elf_Arhdr *e_arhdr; /* translated header */
char *e_rawhdr; /* untranslated header */
unsigned char *e_rawhdr; /* untranslated header */
} e_hdr;
union {
struct { /* ar(1) archives */
off_t e_next; /* set by elf_rand()/elf_next() */
int e_nchildren;
char *e_rawstrtab; /* file name strings */
unsigned char *e_rawstrtab; /* file name strings */
size_t e_rawstrtabsz;
char *e_rawsymtab; /* symbol table */
unsigned char *e_rawsymtab; /* symbol table */
size_t e_rawsymtabsz;
Elf_Arsym *e_symtab;
size_t e_symtabsz;
@ -162,21 +162,31 @@ enum {
ELF_TOMEMORY
};
#define LIBELF_COPY_U32(DST,SRC,NAME) do { \
if ((SRC)->NAME > UINT_MAX) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (SRC)->NAME; \
/*
* The LIBELF_COPY macros are used to copy fields from a GElf_*
* structure to their 32-bit counterparts, while checking for out of
* range values.
*
* - LIBELF_COPY_U32 :: copy an unsigned 32 bit field.
* - LIBELF_COPY_S32 :: copy a signed 32 bit field.
*/
#define LIBELF_COPY_U32(DST, SRC, NAME) do { \
if ((SRC)->NAME > UINT32_MAX) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \
} while (0)
#define LIBELF_COPY_S32(DST,SRC,NAME) do { \
if ((SRC)->NAME > INT_MAX || \
(SRC)->NAME < INT_MIN) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (SRC)->NAME; \
#define LIBELF_COPY_S32(DST, SRC, NAME) do { \
if ((SRC)->NAME > INT32_MAX || \
(SRC)->NAME < INT32_MIN) { \
LIBELF_SET_ERROR(RANGE, 0); \
return (0); \
} \
(DST)->NAME = (int32_t) (SRC)->NAME; \
} while (0)
@ -191,22 +201,22 @@ Elf_Scn *_libelf_allocate_scn(Elf *_e, size_t _ndx);
Elf_Arhdr *_libelf_ar_gethdr(Elf *_e);
Elf *_libelf_ar_open(Elf *_e, int _reporterror);
Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar);
int _libelf_ar_get_member(char *_s, size_t _sz, int _base, size_t *_ret);
Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst);
Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst);
unsigned long _libelf_checksum(Elf *_e, int _elfclass);
long _libelf_checksum(Elf *_e, int _elfclass);
void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate);
int _libelf_falign(Elf_Type _t, int _elfclass);
unsigned int _libelf_falign(Elf_Type _t, int _elfclass);
size_t _libelf_fsize(Elf_Type _t, int _elfclass, unsigned int _version,
size_t count);
int (*_libelf_get_translator(Elf_Type _t, int _direction, int _elfclass))
(char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap);
(unsigned char *_dst, size_t dsz, unsigned char *_src,
size_t _cnt, int _byteswap);
void *_libelf_getphdr(Elf *_e, int _elfclass);
void *_libelf_getshdr(Elf_Scn *_scn, int _elfclass);
void _libelf_init_elf(Elf *_e, Elf_Kind _kind);
int _libelf_load_section_headers(Elf *e, void *ehdr);
int _libelf_malign(Elf_Type _t, int _elfclass);
Elf *_libelf_memory(char *_image, size_t _sz, int _reporterror);
unsigned int _libelf_malign(Elf_Type _t, int _elfclass);
Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror);
size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version);
void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count);
Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror);

View file

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: _libelf_ar.h 2032 2011-10-23 09:07:00Z jkoshy $
* $Id: _libelf_ar.h 3013 2014-03-23 06:16:59Z jkoshy $
*/
#ifndef __LIBELF_AR_H_
@ -42,15 +42,16 @@
(sizeof(LIBELF_AR_BSD_EXTENDED_NAME_PREFIX) - 1)
#define IS_EXTENDED_BSD_NAME(NAME) \
(strncmp((NAME), LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \
(strncmp((const char *) (NAME), \
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX, \
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE) == 0)
char *_libelf_ar_get_string(const char *_buf, size_t _sz, int _rawname,
int _svr4names);
unsigned char *_libelf_ar_get_string(const char *_buf, size_t _sz,
unsigned int _rawname, int _svr4names);
char *_libelf_ar_get_raw_name(const struct ar_hdr *_arh);
char *_libelf_ar_get_translated_name(const struct ar_hdr *_arh, Elf *_ar);
int _libelf_ar_get_number(const char *_buf, size_t _sz, int _base,
size_t *_ret);
int _libelf_ar_get_number(const char *_buf, size_t _sz,
unsigned int _base, size_t *_ret);
#endif /* __LIBELF_AR_H_ */

View file

@ -21,9 +21,9 @@
.\" out of the use of this software, even if advised of the possibility of
.\" such damage.
.\"
.\" $Id: elf.3 2885 2013-01-11 02:11:28Z jkoshy $
.\" $Id: elf.3 3082 2014-07-28 09:13:33Z jkoshy $
.\"
.Dd August 14, 2011
.Dd July 28, 2014
.Os
.Dt ELF 3
.Sh NAME
@ -367,6 +367,11 @@ section entries.
.Xc
.It Dv SHT_DYNSYM Ta Dv ELF_T_SYM Ta Symbols for dynamic linking.
.It Dv SHT_FINI_ARRAY Ta Dv ELF_T_ADDR Ta Termination function pointers.
.It Dv SHT_GNU_HASH Ta Dv ELF_T_GNUHASH Ta GNU hash sections.
.It Dv SHT_GNU_LIBLIST Ta Dv ELF_T_WORD Ta List of libraries to be pre-linked.
.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions.
.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements.
.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols.
.It Dv SHT_GROUP Ta Dv ELF_T_WORD Ta Section group marker.
.It Dv SHT_HASH Ta Dv ELF_T_HASH Ta Symbol hashes.
.It Dv SHT_INIT_ARRAY Ta Dv ELF_T_ADDR Ta Initialization function pointers.
@ -383,12 +388,32 @@ See
.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables.
.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables.
.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering.
.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions.
.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements.
.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols.
.It Dv SHT_SUNW_dof Ta Dv ELF_T_BYTE Ta Xo
Used by
.Xr dtrace 1 .
.Xc
.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records.
.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags.
.It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo
Same as
.Dv SHT_GNU_verdef .
.Xc
.It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo
Same as
.Dv SHT_GNU_verneed .
.Xc
.It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo
Same as
.Dv SHT_GNU_versym .
.Xc
.El
.Pp
Section types in the range
.Ns [ Dv SHT_LOOS ,
.Dv SHT_HIUSER ]
are otherwise considered to be of type
.Dv ELF_T_BYTE .
.TE
.Ss Functional Grouping
This section contains a brief overview of the available functionality
in the ELF library.

View file

@ -27,11 +27,12 @@
#include <assert.h>
#include <errno.h>
#include <libelf.h>
#include <stdint.h>
#include <stdlib.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_data.c 2921 2013-03-04 16:19:22Z jkoshy $");
ELFTC_VCSID("$Id: elf_data.c 3009 2014-03-23 01:49:59Z jkoshy $");
Elf_Data *
elf_getdata(Elf_Scn *s, Elf_Data *ed)
@ -39,10 +40,11 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
Elf *e;
unsigned int sh_type;
int elfclass, elftype;
size_t fsz, msz, count;
size_t count, fsz, msz;
struct _Libelf_Data *d;
uint64_t sh_align, sh_offset, sh_size;
int (*xlate)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s,
size_t _c, int _swap);
d = (struct _Libelf_Data *) ed;
@ -108,11 +110,23 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
return (NULL);
}
count = sh_size / fsz;
if (sh_size / fsz > SIZE_MAX) {
LIBELF_SET_ERROR(RANGE, 0);
return (NULL);
}
count = (size_t) (sh_size / fsz);
msz = _libelf_msize(elftype, elfclass, e->e_version);
if (count > 0 && msz > SIZE_MAX / count) {
LIBELF_SET_ERROR(RANGE, 0);
return (NULL);
}
assert(msz > 0);
assert(count <= SIZE_MAX);
assert(msz * count <= SIZE_MAX);
if ((d = _libelf_allocate_data(s)) == NULL)
return (NULL);
@ -129,7 +143,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
return (&d->d_data);
}
if ((d->d_data.d_buf = malloc(msz*count)) == NULL) {
if ((d->d_data.d_buf = malloc(msz * count)) == NULL) {
(void) _libelf_release_data(d);
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
@ -138,7 +152,7 @@ elf_getdata(Elf_Scn *s, Elf_Data *ed)
d->d_flags |= LIBELF_F_DATA_MALLOCED;
xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass);
if (!(*xlate)(d->d_data.d_buf, d->d_data.d_size,
if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size,
e->e_rawfile + sh_offset, count,
e->e_byteorder != LIBELF_PRIVATE(byteorder))) {
_libelf_release_data(d);

View file

@ -32,7 +32,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_errmsg.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: elf_errmsg.c 3012 2014-03-23 03:41:38Z jkoshy $");
/*
* Retrieve a human readable translation for an error message.
@ -76,7 +76,7 @@ elf_errmsg(int error)
if (error < ELF_E_NONE || error >= ELF_E_NUM)
return _libelf_errors[ELF_E_NUM];
if (oserr) {
(void) snprintf(LIBELF_PRIVATE(msg),
(void) snprintf((char *) LIBELF_PRIVATE(msg),
sizeof(LIBELF_PRIVATE(msg)), "%s: %s",
_libelf_errors[error], strerror(oserr));
return (const char *)&LIBELF_PRIVATE(msg);

View file

@ -30,7 +30,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: elf_flag.c 2988 2014-03-17 08:51:49Z jkoshy $");
unsigned int
elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags)
@ -111,7 +111,7 @@ elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags)
unsigned int
elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags)
{
int r;
unsigned int r;
if (e == NULL)
return (0);
@ -173,7 +173,7 @@ elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags)
unsigned int
elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
{
int r;
unsigned int r;
if (s == NULL)
return (0);

View file

@ -28,7 +28,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $");
ELFTC_VCSID("$Id: elf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $");
Elf *
elf_memory(char *image, size_t sz)
@ -43,5 +43,5 @@ elf_memory(char *image, size_t sz)
return (NULL);
}
return (_libelf_memory(image, sz, 1));
return (_libelf_memory((unsigned char *) image, sz, 1));
}

View file

@ -32,7 +32,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_next.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: elf_next.c 2989 2014-03-17 09:56:46Z jkoshy $");
Elf_Cmd
elf_next(Elf *e)
@ -48,13 +48,17 @@ elf_next(Elf *e)
return (ELF_C_NULL);
}
assert (parent->e_kind == ELF_K_AR);
assert (parent->e_cmd == ELF_C_READ);
assert(parent->e_kind == ELF_K_AR);
assert(parent->e_cmd == ELF_C_READ);
assert(e->e_rawfile > parent->e_rawfile);
next = e->e_rawfile - parent->e_rawfile + e->e_rawsize;
next = e->e_rawfile - parent->e_rawfile + (off_t) e->e_rawsize;
next = (next + 1) & ~1; /* round up to an even boundary */
/*
* Setup the 'e_next' field of the archive descriptor for the
* next call to 'elf_begin()'.
*/
parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ?
(off_t) 0 : next;

View file

@ -63,5 +63,5 @@ elf_openmemory(char *image, size_t sz)
return (NULL);
}
return (_libelf_memory(image, sz, 0));
return (_libelf_memory((unsigned char *) image, sz, 0));
}

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_rand.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: elf_rand.c 2991 2014-03-17 09:57:04Z jkoshy $");
off_t
elf_rand(Elf *ar, off_t offset)
@ -40,7 +40,7 @@ elf_rand(Elf *ar, off_t offset)
if (ar == NULL || ar->e_kind != ELF_K_AR ||
(offset & 1) || offset < SARMAG ||
offset + sizeof(struct ar_hdr) >= ar->e_rawsize) {
(size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return 0;
}

View file

@ -30,13 +30,13 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_rawfile.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: elf_rawfile.c 3013 2014-03-23 06:16:59Z jkoshy $");
char *
elf_rawfile(Elf *e, size_t *sz)
{
char *ptr;
size_t size;
unsigned char *ptr;
size = e ? e->e_rawsize : 0;
ptr = NULL;
@ -49,5 +49,5 @@ elf_rawfile(Elf *e, size_t *sz)
if (sz)
*sz = size;
return (ptr);
return ((char *) ptr);
}

View file

@ -36,7 +36,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: elf_scn.c 3013 2014-03-23 06:16:59Z jkoshy $");
/*
* Load an ELF section table and create a list of Elf_Scn structures.
@ -44,14 +44,15 @@ ELFTC_VCSID("$Id: elf_scn.c 2225 2011-11-26 18:55:54Z jkoshy $");
int
_libelf_load_section_headers(Elf *e, void *ehdr)
{
int ec, swapbytes;
size_t fsz, i, shnum;
Elf_Scn *scn;
uint64_t shoff;
char *src;
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
Elf_Scn *scn;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
int ec, swapbytes;
unsigned char *src;
size_t fsz, i, shnum;
int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
size_t _c, int _swap);
assert(e != NULL);
assert(ehdr != NULL);
@ -104,8 +105,8 @@ _libelf_load_section_headers(Elf *e, void *ehdr)
if ((scn = _libelf_allocate_scn(e, i)) == NULL)
return (0);
(*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr), src,
(size_t) 1, swapbytes);
(*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr),
src, (size_t) 1, swapbytes);
if (ec == ELFCLASS32) {
scn->s_offset = scn->s_rawoff =

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: elf_strptr.c 2271 2011-12-03 17:06:35Z jkoshy $");
ELFTC_VCSID("$Id: elf_strptr.c 2990 2014-03-17 09:56:58Z jkoshy $");
/*
* Convert an ELF section#,offset pair to a string pointer.
@ -42,8 +42,8 @@ elf_strptr(Elf *e, size_t scndx, size_t offset)
{
Elf_Scn *s;
Elf_Data *d;
size_t alignment, count;
GElf_Shdr shdr;
uint64_t alignment, count;
if (e == NULL || e->e_kind != ELF_K_ELF) {
LIBELF_SET_ERROR(ARGUMENT, 0);
@ -90,7 +90,7 @@ elf_strptr(Elf *e, size_t scndx, size_t offset)
* account 'holes' in coverage of the section introduced
* by alignment requirements.
*/
count = (size_t) 0; /* cumulative count of bytes seen */
count = (uint64_t) 0; /* cumulative count of bytes seen */
while ((d = elf_getdata(s, d)) != NULL && count <= offset) {
if (d->d_buf == NULL || d->d_size == 0)

View file

@ -41,7 +41,7 @@
#include <sys/mman.h>
#endif
ELFTC_VCSID("$Id: elf_update.c 2931 2013-03-23 11:41:07Z jkoshy $");
ELFTC_VCSID("$Id: elf_update.c 3013 2014-03-23 06:16:59Z jkoshy $");
/*
* Layout strategy:
@ -110,14 +110,13 @@ SLIST_HEAD(_Elf_Extent_List, _Elf_Extent);
static int
_libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
{
int ec;
Elf_Data *d;
size_t fsz, msz;
int ec, elftype;
uint32_t sh_type;
uint64_t d_align;
Elf32_Shdr *shdr32;
Elf64_Shdr *shdr64;
unsigned int elftype;
struct _Libelf_Data *ld;
uint64_t scn_size, scn_alignment;
uint64_t sh_align, sh_entsize, sh_offset, sh_size;
@ -253,7 +252,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
scn_size = roundup2(scn_size, d->d_align);
d->d_off = scn_size;
fsz = _libelf_fsize(d->d_type, ec, d->d_version,
d->d_size / msz);
(size_t) d->d_size / msz);
scn_size += fsz;
}
@ -307,7 +306,7 @@ _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
* Compute the new offset for the section based on
* the section's alignment needs.
*/
sh_offset = roundup(rc, sh_align);
sh_offset = roundup((uint64_t) rc, sh_align);
/*
* Update the section header.
@ -471,7 +470,7 @@ _libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents)
return ((off_t) -1);
if ((size_t) rc < s->s_offset + s->s_size)
rc = s->s_offset + s->s_size;
rc = (off_t) (s->s_offset + s->s_size);
}
return (rc);
@ -529,17 +528,22 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
if (ec == ELFCLASS32) {
eh_byteorder = eh32->e_ident[EI_DATA];
eh_class = eh32->e_ident[EI_CLASS];
phoff = (uint64_t) eh32->e_phoff;
shoff = (uint64_t) eh32->e_shoff;
phoff = (off_t) eh32->e_phoff;
shoff = (off_t) eh32->e_shoff;
eh_version = eh32->e_version;
} else {
eh_byteorder = eh64->e_ident[EI_DATA];
eh_class = eh64->e_ident[EI_CLASS];
phoff = eh64->e_phoff;
shoff = eh64->e_shoff;
phoff = (off_t) eh64->e_phoff;
shoff = (off_t) eh64->e_shoff;
eh_version = eh64->e_version;
}
if (phoff < 0 || shoff < 0) {
LIBELF_SET_ERROR(HEADER, 0);
return ((off_t) -1);
}
if (eh_version == EV_NONE)
eh_version = EV_CURRENT;
@ -564,18 +568,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
e->e_byteorder = eh_byteorder;
#define INITIALIZE_EHDR(E,EC,V) do { \
unsigned int _version = (unsigned int) (V); \
(E)->e_ident[EI_MAG0] = ELFMAG0; \
(E)->e_ident[EI_MAG1] = ELFMAG1; \
(E)->e_ident[EI_MAG2] = ELFMAG2; \
(E)->e_ident[EI_MAG3] = ELFMAG3; \
(E)->e_ident[EI_CLASS] = (EC); \
(E)->e_ident[EI_VERSION] = (V); \
(E)->e_ehsize = _libelf_fsize(ELF_T_EHDR, (EC), (V), \
(size_t) 1); \
(E)->e_phentsize = (phnum == 0) ? 0 : _libelf_fsize( \
ELF_T_PHDR, (EC), (V), (size_t) 1); \
(E)->e_shentsize = _libelf_fsize(ELF_T_SHDR, (EC), (V), \
(size_t) 1); \
(E)->e_ident[EI_CLASS] = (unsigned char) (EC); \
(E)->e_ident[EI_VERSION] = (_version & 0xFFU); \
(E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \
(EC), _version, (size_t) 1); \
(E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \
_libelf_fsize(ELF_T_PHDR, (EC), _version, \
(size_t) 1)); \
(E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \
(EC), _version, (size_t) 1); \
} while (0)
if (ec == ELFCLASS32)
@ -585,9 +591,10 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
(void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);
rc += _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1);
rc += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1);
if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, rc, ehdr))
if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) rc,
ehdr))
return ((off_t) -1);
/*
@ -608,20 +615,20 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
return ((off_t) -1);
}
if (phoff % align) {
if (phoff % (off_t) align) {
LIBELF_SET_ERROR(LAYOUT, 0);
return ((off_t) -1);
}
} else
phoff = roundup(rc, align);
phoff = roundup(rc, (off_t) align);
rc = phoff + fsz;
rc = phoff + (off_t) fsz;
phdr = _libelf_getphdr(e, ec);
if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, phoff,
fsz, phdr))
if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR,
(uint64_t) phoff, fsz, phdr))
return ((off_t) -1);
} else
phoff = 0;
@ -656,18 +663,18 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
align = _libelf_falign(ELF_T_SHDR, ec);
if (e->e_flags & ELF_F_LAYOUT) {
if (shoff % align) {
if (shoff % (off_t) align) {
LIBELF_SET_ERROR(LAYOUT, 0);
return ((off_t) -1);
}
} else
shoff = roundup(rc, align);
shoff = roundup(rc, (off_t) align);
if (shoff + fsz > (size_t) rc)
rc = shoff + fsz;
if (shoff + (off_t) fsz > rc)
rc = shoff + (off_t) fsz;
if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, shoff,
fsz, NULL))
if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR,
(uint64_t) shoff, fsz, NULL))
return ((off_t) -1);
} else
shoff = 0;
@ -700,22 +707,23 @@ _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
* Write out the contents of an ELF section.
*/
static size_t
_libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex)
static off_t
_libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
{
int ec;
off_t rc;
Elf_Scn *s;
int elftype;
Elf_Data *d, dst;
uint32_t sh_type;
struct _Libelf_Data *ld;
uint64_t sh_off, sh_size;
size_t fsz, msz, nobjects, rc;
size_t fsz, msz, nobjects;
assert(ex->ex_type == ELF_EXTENT_SECTION);
s = ex->ex_desc;
rc = ex->ex_start;
rc = (off_t) ex->ex_start;
if ((ec = e->e_class) == ELFCLASS32) {
sh_type = s->s_shdr.s_shdr32.sh_type;
@ -756,18 +764,20 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex)
if ((uint64_t) rc < sh_off + d->d_off)
(void) memset(nf + rc,
LIBELF_PRIVATE(fillchar), sh_off +
d->d_off - rc);
rc = sh_off + d->d_off;
LIBELF_PRIVATE(fillchar),
(size_t) (sh_off + d->d_off -
(uint64_t) rc));
rc = (off_t) (sh_off + d->d_off);
assert(d->d_buf != NULL);
assert(d->d_type == ELF_T_BYTE);
assert(d->d_version == e->e_version);
(void) memcpy(nf + rc,
e->e_rawfile + s->s_rawoff + d->d_off, d->d_size);
e->e_rawfile + s->s_rawoff + d->d_off,
(size_t) d->d_size);
rc += d->d_size;
rc += (off_t) d->d_size;
}
return (rc);
@ -789,15 +799,16 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex)
if ((uint64_t) rc < sh_off + d->d_off)
(void) memset(nf + rc,
LIBELF_PRIVATE(fillchar), sh_off + d->d_off - rc);
LIBELF_PRIVATE(fillchar),
(size_t) (sh_off + d->d_off - (uint64_t) rc));
rc = sh_off + d->d_off;
rc = (off_t) (sh_off + d->d_off);
assert(d->d_buf != NULL);
assert(d->d_version == e->e_version);
assert(d->d_size % msz == 0);
nobjects = d->d_size / msz;
nobjects = (size_t) (d->d_size / msz);
fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects);
@ -808,10 +819,10 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex)
NULL)
return ((off_t) -1);
rc += fsz;
rc += (off_t) fsz;
}
return ((off_t) rc);
return (rc);
}
/*
@ -819,7 +830,7 @@ _libelf_write_scn(Elf *e, char *nf, struct _Elf_Extent *ex)
*/
static off_t
_libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex)
_libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
{
int ec;
void *ehdr;
@ -860,7 +871,7 @@ _libelf_write_ehdr(Elf *e, char *nf, struct _Elf_Extent *ex)
*/
static off_t
_libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex)
_libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
{
int ec;
void *ehdr;
@ -909,7 +920,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex)
NULL)
return ((off_t) -1);
return (phoff + fsz);
return ((off_t) (phoff + fsz));
}
/*
@ -917,7 +928,7 @@ _libelf_write_phdr(Elf *e, char *nf, struct _Elf_Extent *ex)
*/
static off_t
_libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex)
_libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
{
int ec;
void *ehdr;
@ -969,7 +980,7 @@ _libelf_write_shdr(Elf *e, char *nf, struct _Elf_Extent *ex)
return ((off_t) -1);
}
return (ex->ex_start + nscn * fsz);
return ((off_t) (ex->ex_start + nscn * fsz));
}
/*
@ -993,9 +1004,9 @@ static off_t
_libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
{
off_t nrc, rc;
char *newfile;
Elf_Scn *scn, *tscn;
struct _Elf_Extent *ex;
unsigned char *newfile;
assert(e->e_kind == ELF_K_ELF);
assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE);
@ -1012,7 +1023,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
/* Fill inter-extent gaps. */
if (ex->ex_start > (size_t) rc)
(void) memset(newfile + rc, LIBELF_PRIVATE(fillchar),
ex->ex_start - rc);
(size_t) (ex->ex_start - (uint64_t) rc));
switch (ex->ex_type) {
case ELF_EXTENT_EHDR:
@ -1103,7 +1114,7 @@ _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
#endif /* ELFTC_HAVE_MMAP */
/* Record the new size of the file. */
e->e_rawsize = newsize;
e->e_rawsize = (size_t) newsize;
} else {
/* File opened in ELF_C_WRITE mode. */
assert(e->e_rawfile == NULL);

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_cap.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_cap.c 2995 2014-03-18 02:16:31Z jkoshy $");
GElf_Cap *
gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
@ -72,7 +73,7 @@ gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst)
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -131,7 +132,7 @@ gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc)
msz = _libelf_msize(ELF_T_CAP, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_dyn.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_dyn.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Dyn *
gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
@ -71,8 +72,9 @@ gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst)
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -128,9 +130,11 @@ gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds)
}
msz = _libelf_msize(ELF_T_DYN, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -30,6 +30,7 @@
#include <gelf.h>
#include <libelf.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
#include "_libelf.h"

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_move.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_move.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Move *
gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
@ -71,8 +72,9 @@ gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst)
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -131,9 +133,11 @@ gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm)
}
msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -29,6 +29,7 @@
#include <gelf.h>
#include <libelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_rel.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_rel.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Rel *
gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
@ -71,8 +72,9 @@ gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst)
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -130,9 +132,11 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
}
msz = _libelf_msize(ELF_T_REL, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
@ -147,8 +151,9 @@ gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr)
LIBELF_SET_ERROR(RANGE, 0);
return (0);
}
rel32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info),
ELF64_R_TYPE(dr->r_info));
rel32->r_info = ELF32_R_INFO(
(Elf32_Word) ELF64_R_SYM(dr->r_info),
(Elf32_Word) ELF64_R_TYPE(dr->r_info));
} else {
rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx;

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_rela.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_rela.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Rela *
gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
@ -71,8 +72,9 @@ gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst)
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -131,9 +133,11 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
}
msz = _libelf_msize(ELF_T_RELA, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}
@ -148,8 +152,9 @@ gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr)
LIBELF_SET_ERROR(RANGE, 0);
return (0);
}
rela32->r_info = ELF32_R_INFO(ELF64_R_SYM(dr->r_info),
ELF64_R_TYPE(dr->r_info));
rela32->r_info = ELF32_R_INFO(
(Elf32_Word) ELF64_R_SYM(dr->r_info),
(Elf32_Word) ELF64_R_TYPE(dr->r_info));
LIBELF_COPY_S32(rela32, dr, r_addend);
} else {

View file

@ -30,6 +30,7 @@
#include <gelf.h>
#include <libelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"

View file

@ -29,10 +29,11 @@
#include <assert.h>
#include <gelf.h>
#include <limits.h>
#include <stdint.h>
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_sym.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_sym.c 2999 2014-03-18 17:19:06Z jkoshy $");
GElf_Sym *
gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
@ -71,25 +72,23 @@ gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst)
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
if (ec == ELFCLASS32) {
sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx;
dst->st_name = sym32->st_name;
dst->st_value = (Elf64_Addr) sym32->st_value;
dst->st_size = (Elf64_Xword) sym32->st_size;
dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(sym32->st_info),
ELF32_ST_TYPE(sym32->st_info));
dst->st_info = sym32->st_info;
dst->st_other = sym32->st_other;
dst->st_shndx = sym32->st_shndx;
} else {
sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx;
*dst = *sym64;
@ -133,9 +132,11 @@ gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs)
}
msz = _libelf_msize(ELF_T_SYM, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_syminfo.c 2272 2011-12-03 17:07:31Z jkoshy $");
ELFTC_VCSID("$Id: gelf_syminfo.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Syminfo *
gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
@ -70,8 +70,9 @@ gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst)
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= d->d_data.d_size) {
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -128,9 +129,11 @@ gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs)
}
msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= d->d_data.d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= d->d_data.d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: gelf_symshndx.c 2283 2011-12-04 04:07:24Z jkoshy $");
ELFTC_VCSID("$Id: gelf_symshndx.c 2998 2014-03-18 17:19:00Z jkoshy $");
GElf_Sym *
gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
@ -74,8 +74,9 @@ gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst,
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
assert(msz > 0);
assert(ndx >= 0);
if (msz * ndx >= id->d_size) {
if (msz * (size_t) ndx >= id->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (NULL);
}
@ -123,9 +124,11 @@ gelf_update_symshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *gs,
}
msz = _libelf_msize(ELF_T_WORD, ec, e->e_version);
assert(msz > 0);
if (msz * ndx >= id->d_size) {
assert(msz > 0);
assert(ndx >= 0);
if (msz * (size_t) ndx >= id->d_size) {
LIBELF_SET_ERROR(ARGUMENT, 0);
return (0);
}

View file

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: libelf.h 2366 2011-12-29 06:12:14Z jkoshy $
* $Id: libelf.h 2988 2014-03-17 08:51:49Z jkoshy $
*/
#ifndef _LIBELF_H_
@ -129,7 +129,7 @@ typedef struct {
/*
* Members that are not part of the public API.
*/
int ar_flags;
unsigned int ar_flags;
} Elf_Arhdr;
/*

View file

@ -32,11 +32,11 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_align.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_align.c 3006 2014-03-22 08:10:07Z jkoshy $");
struct align {
int a32;
int a64;
unsigned int a32;
unsigned int a64;
};
#ifdef __GNUC__
@ -87,7 +87,7 @@ static struct align malign[ELF_T_NUM] = {
[ELF_T_GNUHASH] = MALIGN_WORD()
};
int
unsigned int
_libelf_malign(Elf_Type t, int elfclass)
{
if (t >= ELF_T_NUM || (int) t < 0)
@ -126,7 +126,7 @@ static struct align falign[ELF_T_NUM] = {
[ELF_T_GNUHASH] = FALIGN(4,8)
};
int
unsigned int
_libelf_falign(Elf_Type t, int elfclass)
{
if (t >= ELF_T_NUM || (int) t < 0)

View file

@ -35,7 +35,7 @@
#include "_libelf.h"
#include "_libelf_ar.h"
ELFTC_VCSID("$Id: libelf_ar.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_ar.c 3013 2014-03-23 06:16:59Z jkoshy $");
#define LIBELF_NALLOC_SIZE 16
@ -110,8 +110,8 @@ Elf_Arhdr *
_libelf_ar_gethdr(Elf *e)
{
Elf *parent;
char *namelen;
Elf_Arhdr *eh;
char *namelen;
size_t n, nlen;
struct ar_hdr *arh;
@ -192,7 +192,7 @@ _libelf_ar_gethdr(Elf *e)
}
e->e_flags &= ~LIBELF_F_AR_HEADER;
e->e_hdr.e_rawhdr = (char *) arh;
e->e_hdr.e_rawhdr = (unsigned char *) arh;
return (NULL);
}
@ -201,10 +201,10 @@ Elf *
_libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
{
Elf *e;
char *member, *namelen;
size_t nsz, sz;
off_t next;
size_t nsz, sz;
struct ar_hdr *arh;
char *member, *namelen;
assert(elf->e_kind == ELF_K_AR);
@ -249,12 +249,12 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
member = (char *) (arh + 1);
if ((e = elf_memory((char *) member, sz)) == NULL)
if ((e = elf_memory(member, sz)) == NULL)
return (NULL);
e->e_fd = fd;
e->e_cmd = c;
e->e_hdr.e_rawhdr = (char *) arh;
e->e_hdr.e_rawhdr = (unsigned char *) arh;
elf->e_u.e_ar.e_nchildren++;
e->e_parent = elf;
@ -274,9 +274,10 @@ _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf)
*/
/*
* A helper macro to read in a 'long' value from the archive. We use
* memcpy() since the source pointer may be misaligned with respect to
* the natural alignment for a C 'long'.
* A helper macro to read in a 'long' value from the archive.
*
* We use memcpy() since the source pointer may be misaligned with
* respect to the natural alignment for a C 'long'.
*/
#define GET_LONG(P, V)do { \
memcpy(&(V), (P), sizeof(long)); \
@ -287,9 +288,10 @@ Elf_Arsym *
_libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
{
Elf_Arsym *symtab, *sym;
unsigned int n, nentries;
unsigned char *end, *p, *p0, *s, *s0;
const unsigned int entrysize = 2 * sizeof(long);
long arraysize, fileoffset, n, nentries, stroffset, strtabsize;
const size_t entrysize = 2 * sizeof(long);
long arraysize, fileoffset, stroffset, strtabsize;
assert(e != NULL);
assert(count != NULL);
@ -313,7 +315,8 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
*/
GET_LONG(p, arraysize);
if (p0 + arraysize >= end || (arraysize % entrysize != 0))
if (arraysize < 0 || p0 + arraysize >= end ||
((size_t) arraysize % entrysize != 0))
goto symtaberror;
/*
@ -323,10 +326,10 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
GET_LONG(s, strtabsize);
s0 = s; /* Start of string table. */
if (s0 + strtabsize > end)
if (strtabsize < 0 || s0 + strtabsize > end)
goto symtaberror;
nentries = arraysize / entrysize;
nentries = (size_t) arraysize / entrysize;
/*
* Allocate space for the returned Elf_Arsym array.
@ -341,12 +344,16 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
GET_LONG(p, stroffset);
GET_LONG(p, fileoffset);
if (stroffset < 0 || fileoffset < 0 ||
(size_t) fileoffset >= e->e_rawsize)
goto symtaberror;
s = s0 + stroffset;
if (s >= end)
goto symtaberror;
sym->as_off = fileoffset;
sym->as_off = (off_t) fileoffset;
sym->as_hash = elf_hash((char *) s);
sym->as_name = (char *) s;
}
@ -393,7 +400,8 @@ _libelf_ar_process_bsd_symtab(Elf *e, size_t *count)
Elf_Arsym *
_libelf_ar_process_svr4_symtab(Elf *e, size_t *count)
{
size_t n, nentries, off;
uint32_t off;
size_t n, nentries;
Elf_Arsym *symtab, *sym;
unsigned char *p, *s, *end;
@ -424,15 +432,14 @@ _libelf_ar_process_svr4_symtab(Elf *e, size_t *count)
s = p + (nentries * INTSZ); /* start of the string table. */
for (n = nentries, sym = symtab; n > 0; n--) {
if (s >= end)
goto symtaberror;
off = 0;
GET_WORD(p, off);
if (off >= e->e_rawsize)
goto symtaberror;
sym->as_off = off;
sym->as_off = (off_t) off;
sym->as_hash = elf_hash((char *) s);
sym->as_name = (char *) s;

View file

@ -34,21 +34,23 @@
#include "_libelf.h"
#include "_libelf_ar.h"
ELFTC_VCSID("$Id: libelf_ar_util.c 2365 2011-12-29 04:36:44Z jkoshy $");
ELFTC_VCSID("$Id: libelf_ar_util.c 3013 2014-03-23 06:16:59Z jkoshy $");
/*
* Convert a string bounded by `start' and `start+sz' (exclusive) to a
* number in the specified base.
*/
int
_libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret)
_libelf_ar_get_number(const char *src, size_t sz, unsigned int base,
size_t *ret)
{
int c, v;
size_t r;
const char *e;
unsigned int c, v;
const unsigned char *e, *s;
assert(base <= 10);
s = (const unsigned char *) src;
e = s + sz;
/* skip leading blanks */
@ -79,17 +81,18 @@ _libelf_ar_get_number(const char *s, size_t sz, int base, size_t *ret)
char *
_libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
{
char c, *s;
char *s;
unsigned char c;
size_t len, offset;
const char *buf, *p, *q, *r;
const unsigned char *buf, *p, *q, *r;
const size_t bufsize = sizeof(arh->ar_name);
assert(arh != NULL);
assert(ar->e_kind == ELF_K_AR);
assert((const char *) arh >= ar->e_rawfile &&
(const char *) arh < ar->e_rawfile + ar->e_rawsize);
assert((const unsigned char *) arh >= ar->e_rawfile &&
(const unsigned char *) arh < ar->e_rawfile + ar->e_rawsize);
buf = arh->ar_name;
buf = (const unsigned char *) arh->ar_name;
/*
* Check for extended naming.
@ -104,8 +107,8 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
* the archive string table where the actual name
* resides.
*/
if (_libelf_ar_get_number(buf + 1, bufsize - 1, 10,
&offset) == 0) {
if (_libelf_ar_get_number((const char *) (buf + 1),
bufsize - 1, 10, &offset) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
return (NULL);
}
@ -120,21 +123,21 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
for (; p < r && *p != '/'; p++)
;
len = p - q + 1; /* space for the trailing NUL */
len = (size_t) (p - q + 1); /* space for the trailing NUL */
if ((s = malloc(len)) == NULL) {
LIBELF_SET_ERROR(RESOURCE, 0);
return (NULL);
}
(void) strncpy(s, q, len - 1);
(void) strncpy(s, (const char *) q, len - 1);
s[len - 1] = '\0';
return (s);
} else if (IS_EXTENDED_BSD_NAME(buf)) {
r = buf + LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE;
if (_libelf_ar_get_number(r, bufsize -
if (_libelf_ar_get_number((const char *) r, bufsize -
LIBELF_AR_BSD_EXTENDED_NAME_PREFIX_SIZE, 10,
&len) == 0) {
LIBELF_SET_ERROR(ARCHIVE, 0);
@ -153,9 +156,9 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
/*
* The file name follows the archive header.
*/
q = (const char *) (arh + 1);
q = (const unsigned char *) (arh + 1);
(void) strncpy(s, q, len);
(void) strncpy(s, (const char *) q, len);
s[len] = '\0';
return (s);
@ -183,10 +186,10 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
q--;
}
len = q - buf + 2; /* Add space for a trailing NUL. */
len = (size_t) (q - buf + 2); /* Space for a trailing NUL. */
} else {
/* The buffer only had blanks. */
buf = "";
buf = (const unsigned char *) "";
len = 1;
}
@ -195,7 +198,7 @@ _libelf_ar_get_translated_name(const struct ar_hdr *arh, Elf *ar)
return (NULL);
}
(void) strncpy(s, buf, len - 1);
(void) strncpy(s, (const char *) buf, len - 1);
s[len - 1] = '\0';
return (s);
@ -229,8 +232,8 @@ _libelf_ar_open(Elf *e, int reporterror)
{
size_t sz;
int scanahead;
char *s, *end;
struct ar_hdr arh;
unsigned char *s, *end;
_libelf_init_elf(e, ELF_K_AR);
@ -264,7 +267,7 @@ _libelf_ar_open(Elf *e, int reporterror)
(void) memcpy(&(ARH), (S), sizeof((ARH))); \
if ((ARH).ar_fmag[0] != '`' || (ARH).ar_fmag[1] != '\n') \
goto error; \
if (_libelf_ar_get_number((ARH).ar_size, \
if (_libelf_ar_get_number((char *) (ARH).ar_size, \
sizeof((ARH).ar_size), 10, &(SZ)) == 0) \
goto error; \
} while (0)

View file

@ -30,7 +30,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_checksum.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_checksum.c 3003 2014-03-22 07:43:10Z jkoshy $");
static unsigned long
_libelf_sum(unsigned long c, const unsigned char *s, size_t size)
@ -44,7 +44,7 @@ _libelf_sum(unsigned long c, const unsigned char *s, size_t size)
return (c);
}
unsigned long
long
_libelf_checksum(Elf *e, int elfclass)
{
size_t shn;
@ -90,11 +90,11 @@ _libelf_checksum(Elf *e, int elfclass)
d = NULL;
while ((d = elf_rawdata(scn, d)) != NULL)
checksum = _libelf_sum(checksum,
(unsigned char *) d->d_buf, d->d_size);
(unsigned char *) d->d_buf, (size_t) d->d_size);
}
/*
* Return a 16-bit checksum compatible with Solaris.
*/
return (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL));
return (long) (((checksum >> 16) & 0xFFFFUL) + (checksum & 0xFFFFUL));
}

View file

@ -32,7 +32,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_convert.m4 2361 2011-12-28 12:03:05Z jkoshy $");
ELFTC_VCSID("$Id: libelf_convert.m4 3009 2014-03-23 01:49:59Z jkoshy $");
/* WARNING: GENERATED FROM __file__. */
@ -143,8 +143,8 @@ define(`SIZEDEP_OFF', 1)
# Generates a pair of conversion functions.
define(`MAKEPRIMFUNCS',`
static int
_libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$4_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$3_$2 t, *s = (Elf$3_$2 *) (uintptr_t) src;
size_t c;
@ -166,8 +166,8 @@ _libelf_cvt_$1$4_tof(char *dst, size_t dsz, char *src, size_t count,
}
static int
_libelf_cvt_$1$4_tom(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$4_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$3_$2 t, *d = (Elf$3_$2 *) (uintptr_t) dst;
size_t c;
@ -267,8 +267,8 @@ define(`READ_STRUCT',
# `$3': ELF class specifier, one of [`', `32', `64']
define(`MAKECOMPFUNCS', `ifdef(`NOFUNC_'$1$3,`',`
static int
_libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$3_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$3_$2 t, *s;
size_t c;
@ -288,16 +288,16 @@ _libelf_cvt_$1$3_tof(char *dst, size_t dsz, char *src, size_t count,
}
static int
_libelf_cvt_$1$3_tom(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$3_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$3_$2 t, *d;
char *s,*s0;
Elf$3_$2 t, *d;
unsigned char *s,*s0;
size_t fsz;
fsz = elf$3_fsize(ELF_T_$1, (size_t) 1, EV_CURRENT);
d = ((Elf$3_$2 *) (uintptr_t) dst) + (count - 1);
s0 = (char *) src + (count - 1) * fsz;
s0 = src + (count - 1) * fsz;
if (dsz < count * sizeof(Elf$3_$2))
return (0);
@ -398,8 +398,8 @@ define(`MAKE_VERSION_CONVERTERS',
# conversion function.
define(`MAKE_VERSION_CONVERTER',`
static int
_libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$5_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$5_$2 t;
Elf$5_$3 a;
@ -407,12 +407,12 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count,
const size_t auxfsz = FSZ(Elf$5_$3_DEF);
const size_t vermsz = sizeof(Elf$5_$2);
const size_t auxmsz = sizeof(Elf$5_$3);
char * const dstend = dst + dsz;
char * const srcend = src + count;
char *dtmp, *dstaux, *srcaux;
unsigned char * const dstend = dst + dsz;
unsigned char * const srcend = src + count;
unsigned char *dtmp, *dstaux, *srcaux;
Elf$5_Word aux, anext, cnt, vnext;
for (dtmp = dst, vnext = ~0;
for (dtmp = dst, vnext = ~0U;
vnext != 0 && dtmp + verfsz <= dstend && src + vermsz <= srcend;
dtmp += vnext, src += vnext) {
@ -434,7 +434,7 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count,
return (0);
/* Process AUX entries. */
for (anext = ~0, dstaux = dtmp + aux, srcaux = src + aux;
for (anext = ~0U, dstaux = dtmp + aux, srcaux = src + aux;
cnt != 0 && anext != 0 && dstaux + auxfsz <= dstend &&
srcaux + auxmsz <= srcend;
dstaux += anext, srcaux += anext, cnt--) {
@ -462,8 +462,8 @@ _libelf_cvt_$1$5_tof(char *dst, size_t dsz, char *src, size_t count,
}
static int
_libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_$1$5_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
Elf$5_$2 t, *dp;
Elf$5_$3 a, *ap;
@ -471,12 +471,12 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count,
const size_t auxfsz = FSZ(Elf$5_$3_DEF);
const size_t vermsz = sizeof(Elf$5_$2);
const size_t auxmsz = sizeof(Elf$5_$3);
char * const dstend = dst + dsz;
char * const srcend = src + count;
char *dstaux, *s, *srcaux, *stmp;
unsigned char * const dstend = dst + dsz;
unsigned char * const srcend = src + count;
unsigned char *dstaux, *s, *srcaux, *stmp;
Elf$5_Word aux, anext, cnt, vnext;
for (stmp = src, vnext = ~0;
for (stmp = src, vnext = ~0U;
vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend;
stmp += vnext, dst += vnext) {
@ -498,7 +498,7 @@ _libelf_cvt_$1$5_tom(char *dst, size_t dsz, char *src, size_t count,
return (0);
/* Process AUX entries. */
for (anext = ~0, dstaux = dst + aux, srcaux = stmp + aux;
for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux;
cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend &&
srcaux + auxfsz <= srcend;
dstaux += anext, srcaux += anext, cnt--) {
@ -536,22 +536,23 @@ divert(0)
#define SWAP_IDENT(X) do { (void) (X); } while (0)
#define SWAP_HALF(X) do { \
uint16_t _x = (uint16_t) (X); \
uint16_t _t = _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
(X) = _t; \
uint32_t _t = _x & 0xFFU; \
_t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \
(X) = (uint16_t) _t; \
} while (0)
#define SWAP_WORD(X) do { \
#define _SWAP_WORD(X, T) do { \
uint32_t _x = (uint32_t) (X); \
uint32_t _t = _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
(X) = _t; \
(X) = (T) _t; \
} while (0)
#define SWAP_ADDR32(X) SWAP_WORD(X)
#define SWAP_OFF32(X) SWAP_WORD(X)
#define SWAP_SWORD(X) SWAP_WORD(X)
#define SWAP_WORD64(X) do { \
#define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr)
#define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off)
#define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword)
#define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word)
#define _SWAP_WORD64(X, T) do { \
uint64_t _x = (uint64_t) (X); \
uint64_t _t = _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
@ -561,13 +562,13 @@ divert(0)
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
_t <<= 8; _x >>= 8; _t |= _x & 0xFF; \
(X) = _t; \
(X) = (T) _t; \
} while (0)
#define SWAP_ADDR64(X) SWAP_WORD64(X)
#define SWAP_LWORD(X) SWAP_WORD64(X)
#define SWAP_OFF64(X) SWAP_WORD64(X)
#define SWAP_SXWORD(X) SWAP_WORD64(X)
#define SWAP_XWORD(X) SWAP_WORD64(X)
#define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr)
#define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword)
#define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off)
#define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword)
#define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword)
/*
* C macros to write out various integral values.
@ -578,22 +579,22 @@ divert(0)
* - The destination pointer is incremented after the write.
*/
#define WRITE_BYTE(P,X) do { \
char *const _p = (char *) (P); \
_p[0] = (char) (X); \
unsigned char *const _p = (unsigned char *) (P); \
_p[0] = (unsigned char) (X); \
(P) = _p + 1; \
} while (0)
#define WRITE_HALF(P,X) do { \
uint16_t _t = (X); \
char *const _p = (char *) (P); \
const char *const _q = (char *) &_t; \
unsigned char *const _p = (unsigned char *) (P); \
const unsigned char *const _q = (unsigned char *) &_t; \
_p[0] = _q[0]; \
_p[1] = _q[1]; \
(P) = _p + 2; \
} while (0)
#define WRITE_WORD(P,X) do { \
uint32_t _t = (X); \
char *const _p = (char *) (P); \
const char *const _q = (char *) &_t; \
#define WRITE_WORD(P,X) do { \
uint32_t _t = (uint32_t) (X); \
unsigned char *const _p = (unsigned char *) (P); \
const unsigned char *const _q = (unsigned char *) &_t; \
_p[0] = _q[0]; \
_p[1] = _q[1]; \
_p[2] = _q[2]; \
@ -604,9 +605,9 @@ divert(0)
#define WRITE_OFF32(P,X) WRITE_WORD(P,X)
#define WRITE_SWORD(P,X) WRITE_WORD(P,X)
#define WRITE_WORD64(P,X) do { \
uint64_t _t = (X); \
char *const _p = (char *) (P); \
const char *const _q = (char *) &_t; \
uint64_t _t = (uint64_t) (X); \
unsigned char *const _p = (unsigned char *) (P); \
const unsigned char *const _q = (unsigned char *) &_t; \
_p[0] = _q[0]; \
_p[1] = _q[1]; \
_p[2] = _q[2]; \
@ -637,41 +638,42 @@ divert(0)
*/
#define READ_BYTE(P,X) do { \
const char *const _p = \
(const char *) (P); \
const unsigned char *const _p = \
(const unsigned char *) (P); \
(X) = _p[0]; \
(P) = (P) + 1; \
} while (0)
#define READ_HALF(P,X) do { \
uint16_t _t; \
char *const _q = (char *) &_t; \
const char *const _p = \
(const char *) (P); \
unsigned char *const _q = (unsigned char *) &_t; \
const unsigned char *const _p = \
(const unsigned char *) (P); \
_q[0] = _p[0]; \
_q[1] = _p[1]; \
(P) = (P) + 2; \
(X) = _t; \
} while (0)
#define READ_WORD(P,X) do { \
#define _READ_WORD(P,X,T) do { \
uint32_t _t; \
char *const _q = (char *) &_t; \
const char *const _p = \
(const char *) (P); \
unsigned char *const _q = (unsigned char *) &_t; \
const unsigned char *const _p = \
(const unsigned char *) (P); \
_q[0] = _p[0]; \
_q[1] = _p[1]; \
_q[2] = _p[2]; \
_q[3] = _p[3]; \
(P) = (P) + 4; \
(X) = _t; \
(X) = (T) _t; \
} while (0)
#define READ_ADDR32(P,X) READ_WORD(P,X)
#define READ_OFF32(P,X) READ_WORD(P,X)
#define READ_SWORD(P,X) READ_WORD(P,X)
#define READ_WORD64(P,X) do { \
#define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr)
#define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off)
#define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword)
#define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word)
#define _READ_WORD64(P,X,T) do { \
uint64_t _t; \
char *const _q = (char *) &_t; \
const char *const _p = \
(const char *) (P); \
unsigned char *const _q = (unsigned char *) &_t; \
const unsigned char *const _p = \
(const unsigned char *) (P); \
_q[0] = _p[0]; \
_q[1] = _p[1]; \
_q[2] = _p[2]; \
@ -681,13 +683,13 @@ divert(0)
_q[6] = _p[6]; \
_q[7] = _p[7]; \
(P) = (P) + 8; \
(X) = _t; \
(X) = (T) _t; \
} while (0)
#define READ_ADDR64(P,X) READ_WORD64(P,X)
#define READ_LWORD(P,X) READ_WORD64(P,X)
#define READ_OFF64(P,X) READ_WORD64(P,X)
#define READ_SXWORD(P,X) READ_WORD64(P,X)
#define READ_XWORD(P,X) READ_WORD64(P,X)
#define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr)
#define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword)
#define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off)
#define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword)
#define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword)
#define READ_IDENT(P,X) do { \
(void) memcpy((X), (P), sizeof((X))); \
(P) = (P) + EI_NIDENT; \
@ -707,8 +709,8 @@ MAKE_VERSION_CONVERTERS(VNEED,Verneed,Vernaux,vn)
*/
static int
_libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
(void) byteswap;
if (dsz < count)
@ -732,24 +734,24 @@ _libelf_cvt_BYTE_tox(char *dst, size_t dsz, char *src, size_t count,
*/
static int
_libelf_cvt_GNUHASH32_tom(char *dst, size_t dsz, char *src, size_t srcsz,
int byteswap)
_libelf_cvt_GNUHASH32_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t srcsz, int byteswap)
{
return (_libelf_cvt_WORD_tom(dst, dsz, src, srcsz / sizeof(uint32_t),
byteswap));
}
static int
_libelf_cvt_GNUHASH32_tof(char *dst, size_t dsz, char *src, size_t srcsz,
int byteswap)
_libelf_cvt_GNUHASH32_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t srcsz, int byteswap)
{
return (_libelf_cvt_WORD_tof(dst, dsz, src, srcsz / sizeof(uint32_t),
byteswap));
}
static int
_libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz,
int byteswap)
_libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t srcsz, int byteswap)
{
size_t sz;
uint64_t t64, *bloom64;
@ -834,8 +836,8 @@ _libelf_cvt_GNUHASH64_tom(char *dst, size_t dsz, char *src, size_t srcsz,
}
static int
_libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz,
int byteswap)
_libelf_cvt_GNUHASH64_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t srcsz, int byteswap)
{
uint32_t *s32;
size_t sz, hdrsz;
@ -921,8 +923,8 @@ _libelf_cvt_GNUHASH64_tof(char *dst, size_t dsz, char *src, size_t srcsz,
* The destination buffer needs to be at least `count' bytes in size.
*/
static int
_libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
uint32_t namesz, descsz, type;
Elf_Note *en;
@ -962,8 +964,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count,
dst += sizeof(Elf_Note);
count -= hdrsz;
ROUNDUP2(namesz, 4);
ROUNDUP2(descsz, 4);
ROUNDUP2(namesz, 4U);
ROUNDUP2(descsz, 4U);
sz = namesz + descsz;
@ -983,8 +985,8 @@ _libelf_cvt_NOTE_tom(char *dst, size_t dsz, char *src, size_t count,
}
static int
_libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count,
int byteswap)
_libelf_cvt_NOTE_tof(unsigned char *dst, size_t dsz, unsigned char *src,
size_t count, int byteswap)
{
uint32_t namesz, descsz, type;
Elf_Note *en;
@ -1006,9 +1008,9 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count,
type = en->n_type;
sz = namesz;
ROUNDUP2(sz, 4);
ROUNDUP2(sz, 4U);
sz += descsz;
ROUNDUP2(sz, 4);
ROUNDUP2(sz, 4U);
SWAP_WORD(namesz);
SWAP_WORD(descsz);
@ -1034,14 +1036,14 @@ _libelf_cvt_NOTE_tof(char *dst, size_t dsz, char *src, size_t count,
}
struct converters {
int (*tof32)(char *dst, size_t dsz, char *src, size_t cnt,
int byteswap);
int (*tom32)(char *dst, size_t dsz, char *src, size_t cnt,
int byteswap);
int (*tof64)(char *dst, size_t dsz, char *src, size_t cnt,
int byteswap);
int (*tom64)(char *dst, size_t dsz, char *src, size_t cnt,
int byteswap);
int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src,
size_t cnt, int byteswap);
int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src,
size_t cnt, int byteswap);
int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src,
size_t cnt, int byteswap);
int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src,
size_t cnt, int byteswap);
};
@ -1070,7 +1072,8 @@ CONVERTER_NAMES(ELF_TYPE_LIST)
};
int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass))
(char *_dst, size_t dsz, char *_src, size_t _cnt, int _byteswap)
(unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt,
int _byteswap)
{
assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64);
assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY);

View file

@ -30,11 +30,14 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_data.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_data.c 3080 2014-07-28 08:46:17Z jkoshy $");
int
_libelf_xlate_shtype(uint32_t sht)
{
/*
* Look for known section types.
*/
switch (sht) {
case SHT_DYNAMIC:
return (ELF_T_DYN);
@ -82,18 +85,19 @@ _libelf_xlate_shtype(uint32_t sht)
return (ELF_T_VNEED);
case SHT_SUNW_versym: /* == SHT_GNU_versym */
return (ELF_T_HALF);
case SHT_ARM_PREEMPTMAP:
case SHT_ARM_ATTRIBUTES:
case SHT_ARM_DEBUGOVERLAY:
case SHT_ARM_OVERLAYSECTION:
case SHT_MIPS_DWARF:
case SHT_MIPS_REGINFO:
case SHT_MIPS_OPTIONS:
case SHT_AMD64_UNWIND: /* == SHT_IA_64_UNWIND == SHT_ARM_EXIDX */
return (ELF_T_BYTE);
default:
/*
* Values in the range [SHT_LOOS..SHT_HIUSER] (i.e.,
* OS, processor and user-defined section types) are
* legal, but since we do not know anything more about
* their semantics, we return a type of ELF_T_BYTE.
*/
if (sht >= SHT_LOOS && sht <= SHT_HIUSER)
return (ELF_T_BYTE);
/*
* Other values are unsupported.
*/
return (-1);
}
}

View file

@ -33,7 +33,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_ehdr.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_ehdr.c 3009 2014-03-23 01:49:59Z jkoshy $");
/*
* Retrieve counts for sections, phdrs and the section string table index
@ -45,7 +45,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
{
Elf_Scn *scn;
size_t fsz;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
size_t _c, int _swap);
uint32_t shtype;
assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn));
@ -62,8 +63,8 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
return (0);
xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec);
(*xlator)((char *) &scn->s_shdr, sizeof(scn->s_shdr),
e->e_rawfile + shoff, (size_t) 1,
(*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr),
(unsigned char *) e->e_rawfile + shoff, (size_t) 1,
e->e_byteorder != LIBELF_PRIVATE(byteorder));
#define GET_SHDR_MEMBER(M) ((ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M : \
@ -74,7 +75,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
return (0);
}
e->e_u.e_elf.e_nscn = GET_SHDR_MEMBER(sh_size);
e->e_u.e_elf.e_nscn = (size_t) GET_SHDR_MEMBER(sh_size);
e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum :
GET_SHDR_MEMBER(sh_info);
e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx :
@ -92,7 +93,7 @@ _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum,
eh->e_ident[EI_MAG3] = ELFMAG3; \
eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \
eh->e_ident[EI_DATA] = ELFDATANONE; \
eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version); \
eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \
eh->e_machine = EM_NONE; \
eh->e_type = ELF_K_NONE; \
eh->e_version = LIBELF_PRIVATE(version); \
@ -105,7 +106,8 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
size_t fsz, msz;
uint16_t phnum, shnum, strndx;
uint64_t shoff;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
size_t _c, int _swap);
assert(ec == ELFCLASS32 || ec == ELFCLASS64);
@ -167,7 +169,7 @@ _libelf_ehdr(Elf *e, int ec, int allocate)
return (ehdr);
xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec);
(*xlator)(ehdr, msz, e->e_rawfile, (size_t) 1,
(*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1,
e->e_byteorder != LIBELF_PRIVATE(byteorder));
/*

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_extended.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_extended.c 3005 2014-03-22 07:43:25Z jkoshy $");
/*
* Retrieve section #0, allocating a new section if needed.
@ -69,9 +69,9 @@ _libelf_setshnum(Elf *e, void *eh, int ec, size_t shnum)
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_shnum = shnum;
((Elf32_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU;
else
((Elf64_Ehdr *) eh)->e_shnum = shnum;
((Elf64_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU;
return (1);
@ -99,9 +99,9 @@ _libelf_setshstrndx(Elf *e, void *eh, int ec, size_t shstrndx)
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx;
((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU;
else
((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx;
((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU;
return (1);
}
@ -128,9 +128,9 @@ _libelf_setphnum(Elf *e, void *eh, int ec, size_t phnum)
}
if (ec == ELFCLASS32)
((Elf32_Ehdr *) eh)->e_phnum = phnum;
((Elf32_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU;
else
((Elf64_Ehdr *) eh)->e_phnum = phnum;
((Elf64_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU;
return (1);
}

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $");
ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $");
/*
* Create an ELF descriptor for a memory image, optionally reporting
@ -39,7 +39,7 @@ ELFTC_VCSID("$Id: libelf_memory.c 2368 2011-12-29 06:34:28Z jkoshy $");
*/
Elf *
_libelf_memory(char *image, size_t sz, int reporterror)
_libelf_memory(unsigned char *image, size_t sz, int reporterror)
{
Elf *e;
int e_class;
@ -89,7 +89,7 @@ _libelf_memory(char *image, size_t sz, int reporterror)
e->e_version = e_version;
}
} else if (sz >= SARMAG &&
strncmp(image, ARMAG, (size_t) SARMAG) == 0)
strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0)
return (_libelf_ar_open(e, reporterror));
return (e);

View file

@ -39,7 +39,7 @@
#include <sys/mman.h>
#endif
ELFTC_VCSID("$Id: libelf_open.c 2932 2013-03-30 01:26:04Z jkoshy $");
ELFTC_VCSID("$Id: libelf_open.c 3007 2014-03-22 08:10:14Z jkoshy $");
#define _LIBELF_INITSIZE (64*1024)
@ -73,11 +73,11 @@ _libelf_read_special_file(int fd, size_t *fsz)
}
do {
readsz = bufsz - datasz;
assert(bufsz - datasz > 0);
t = buf + datasz;
if ((readsz = read(fd, t, readsz)) <= 0)
if ((readsz = read(fd, t, bufsz - datasz)) <= 0)
break;
datasz += readsz;
datasz += (size_t) readsz;
} while (datasz < bufsz);
} while (readsz > 0);

View file

@ -33,7 +33,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_phdr.c 2931 2013-03-23 11:41:07Z jkoshy $");
ELFTC_VCSID("$Id: libelf_phdr.c 3009 2014-03-23 01:49:59Z jkoshy $");
void *
_libelf_getphdr(Elf *e, int ec)
@ -44,7 +44,8 @@ _libelf_getphdr(Elf *e, int ec)
Elf32_Ehdr *eh32;
Elf64_Ehdr *eh64;
void *ehdr, *phdr;
int (*xlator)(char *_d, size_t _dsz, char *_s, size_t _c, int _swap);
int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s,
size_t _c, int _swap);
assert(ec == ELFCLASS32 || ec == ELFCLASS64);

View file

@ -31,7 +31,7 @@
#include "_libelf.h"
ELFTC_VCSID("$Id: libelf_xlate.c 2225 2011-11-26 18:55:54Z jkoshy $");
ELFTC_VCSID("$Id: libelf_xlate.c 3007 2014-03-22 08:10:14Z jkoshy $");
/*
* Translate to/from the file representation of ELF objects.
@ -99,10 +99,10 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
* buffer.
*/
if (direction == ELF_TOMEMORY) {
cnt = src->d_size / fsz;
cnt = (size_t) src->d_size / fsz;
dsz = cnt * msz;
} else {
cnt = src->d_size / msz;
cnt = (size_t) src->d_size / msz;
dsz = cnt * fsz;
}
@ -112,9 +112,9 @@ _libelf_xlate(Elf_Data *dst, const Elf_Data *src, unsigned int encoding,
}
sb = (uintptr_t) src->d_buf;
se = sb + src->d_size;
se = sb + (size_t) src->d_size;
db = (uintptr_t) dst->d_buf;
de = db + dst->d_size;
de = db + (size_t) dst->d_size;
/*
* Check for overlapping buffers. Note that db == sb is

View file

@ -37,7 +37,7 @@
#include <sys/mman.h>
#endif
ELFTC_VCSID("$Id: elftc_copyfile.c 2318 2011-12-11 10:54:27Z jkoshy $");
ELFTC_VCSID("$Id: elftc_copyfile.c 2981 2014-02-01 02:41:13Z jkoshy $");
/*
* Copy the contents referenced by 'ifd' to 'ofd'. Returns 0 on
@ -79,11 +79,13 @@ elftc_copyfile(int ifd, int ofd)
* If mmap() is not available, or if the mmap() operation
* failed, allocate a buffer, and read in input data.
*/
if (buf == NULL) {
if (buf_mmapped == false) {
if ((buf = malloc(sb.st_size)) == NULL)
return (-1);
if (read(ifd, buf, sb.st_size) != sb.st_size)
if (read(ifd, buf, sb.st_size) != sb.st_size) {
free(buf);
return (-1);
}
}
/*

View file

@ -29,14 +29,13 @@
#include <sys/param.h>
#include <assert.h>
#include <errno.h>
#include <libelf.h>
#include <libelftc.h>
#include <stdlib.h>
#include <string.h>
#include "_libelftc.h"
ELFTC_VCSID("$Id: elftc_demangle.c 2065 2011-10-26 15:24:47Z jkoshy $");
ELFTC_VCSID("$Id: elftc_demangle.c 3030 2014-05-01 06:30:48Z kaiwang27 $");
static int
is_mangled(const char *s, int style)

View file

@ -24,7 +24,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $
* $Id: libelftc.h 2863 2013-01-06 03:18:32Z jkoshy $
* $Id: libelftc.h 3031 2014-05-01 17:45:41Z jkoshy $
*/
#ifndef _LIBELFTC_H_
@ -34,6 +34,9 @@
#include <libelf.h>
/*
* Types meant to be opaque to the consumers of these APIs.
*/
typedef struct _Elftc_Bfd_Target Elftc_Bfd_Target;
typedef struct _Elftc_String_Table Elftc_String_Table;

View file

@ -36,7 +36,7 @@
#include "_libelftc.h"
ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 2179 2011-11-18 03:05:47Z jkoshy $");
ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3123 2014-12-21 05:46:19Z kaiwang27 $");
/**
* @file cpp_demangle.c

View file

@ -48,7 +48,7 @@
#include "_elftc.h"
ELFTC_VCSID("$Id: nm.c 2484 2012-04-07 15:52:05Z kaiwang27 $");
ELFTC_VCSID("$Id: nm.c 3124 2014-12-21 05:46:28Z kaiwang27 $");
/* symbol information list */
STAILQ_HEAD(sym_head, sym_entry);

View file

@ -22,7 +22,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $Id: readelf.1 2577 2012-09-13 16:07:04Z jkoshy $
.\" $Id: readelf.1 3059 2014-06-02 00:42:32Z kaiwang27 $
.\"
.Dd September 13, 2012
.Os
@ -139,7 +139,7 @@ option names:
.It p Ta pubnames Ta Show global names.
.It r Ta aranges|ranges Ta Show address range information.
.It s Ta str Ta Show the debug string table.
.It F Ta Ta Show frame information, displaying register rules.
.It F Ta frames-interp Ta Show frame information, displaying register rules.
.It L Ta decodedline Ta Show line information in decoded form.
.It R Ta Ranges Ta Show range lists.
.El

File diff suppressed because it is too large Load diff

View file

@ -46,7 +46,7 @@
#include "_elftc.h"
ELFTC_VCSID("$Id: strings.c 2351 2011-12-19 11:20:37Z jkoshy $");
ELFTC_VCSID("$Id: strings.c 3124 2014-12-21 05:46:28Z kaiwang27 $");
enum return_code {
RETURN_OK,

View file

@ -46,6 +46,7 @@ SRCS= \
dwarf_pubtypes.c \
dwarf_ranges.c \
dwarf_reloc.c \
dwarf_sections.c \
dwarf_seterror.c \
dwarf_str.c \
dwarf_types.c \
@ -130,6 +131,7 @@ MAN= dwarf.3 \
dwarf_add_weakname.3 \
dwarf_attr.3 \
dwarf_attrlist.3 \
dwarf_attroffset.3 \
dwarf_attrval_signed.3 \
dwarf_child.3 \
dwarf_dealloc.3 \
@ -169,6 +171,7 @@ MAN= dwarf.3 \
dwarf_get_cie_info.3 \
dwarf_get_cie_of_fde.3 \
dwarf_get_cu_die_offset.3 \
dwarf_get_die_infotypes_flag.3 \
dwarf_get_elf.3 \
dwarf_get_fde_at_pc.3 \
dwarf_get_fde_info_for_all_regs.3 \
@ -190,6 +193,7 @@ MAN= dwarf.3 \
dwarf_get_relocation_info.3 \
dwarf_get_relocation_info_count.3 \
dwarf_get_section_bytes.3 \
dwarf_get_section_max_offsets.3 \
dwarf_get_str.3 \
dwarf_get_types.3 \
dwarf_get_vars.3 \
@ -207,6 +211,7 @@ MAN= dwarf.3 \
dwarf_new_expr.3 \
dwarf_new_fde.3 \
dwarf_next_cu_header.3 \
dwarf_next_types_section.3 \
dwarf_object_init.3 \
dwarf_producer_init.3 \
dwarf_producer_set_isa.3 \
@ -235,7 +240,9 @@ MLINKS+= \
dwarf_attrval_signed.3 dwarf_attrval_string.3 \
dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \
dwarf_child.3 dwarf_offdie.3 \
dwarf_child.3 dwarf_offdie_b.3 \
dwarf_child.3 dwarf_siblingof.3 \
dwarf_child.3 dwarf_siblingof_b.3 \
dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \
dwarf_dealloc.3 dwarf_funcs_dealloc.3 \
dwarf_dealloc.3 dwarf_globals_dealloc.3 \
@ -249,6 +256,7 @@ MLINKS+= \
dwarf_dieoffset.3 dwarf_die_CU_offset.3 \
dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \
dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \
dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset_b.3 \
dwarf_finish.3 dwarf_object_finish.3 \
dwarf_formref.3 dwarf_global_formref.3 \
dwarf_formudata.3 dwarf_formsdata.3 \
@ -288,6 +296,7 @@ MLINKS+= \
dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \
dwarf_get_pubtypes.3 dwarf_pubtypename.3 \
dwarf_get_ranges.3 dwarf_get_ranges_a.3 \
dwarf_get_section_max_offsets.3 dwarf_get_section_max_offsets_b.3 \
dwarf_get_types.3 dwarf_type_die_offset.3 \
dwarf_get_types.3 dwarf_type_cu_offset.3 \
dwarf_get_types.3 dwarf_type_name_offsets.3 \
@ -306,6 +315,7 @@ MLINKS+= \
dwarf_highpc.3 dwarf_bitoffset.3 \
dwarf_highpc.3 dwarf_bitsize.3 \
dwarf_highpc.3 dwarf_bytesize.3 \
dwarf_highpc.3 dwarf_highpc_b.3 \
dwarf_highpc.3 dwarf_lowpc.3 \
dwarf_highpc.3 dwarf_srclang.3 \
dwarf_lineno.3 dwarf_lineaddr.3 \
@ -317,6 +327,9 @@ MLINKS+= \
dwarf_lineno.3 dwarf_line_srcfileno.3 \
dwarf_loclist.3 dwarf_loclist_n.3 \
dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \
dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_b.3 \
dwarf_next_cu_header.3 dwarf_next_cu_header_b.3 \
dwarf_next_cu_header.3 dwarf_next_cu_header_c.3 \
dwarf_producer_init.3 dwarf_producer_init_b.3 \
dwarf_seterrarg.3 dwarf_seterrhand.3 \
dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \

View file

@ -6,5 +6,5 @@
const char *
elftc_version(void)
{
return "libelftc r2974";
return "libelftc r3130";
}