MFhead @ r276594

This commit is contained in:
Enji Cooper 2015-01-02 23:27:16 +00:00
commit a4ed727666
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/building-blocks/; revision=276595
5084 changed files with 474635 additions and 391838 deletions

View File

@ -4,7 +4,7 @@
The compilation of software known as FreeBSD is distributed under the
following terms:
Copyright (c) 1992-2014 The FreeBSD Project. All rights reserved.
Copyright (c) 1992-2015 The FreeBSD Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View File

@ -260,7 +260,7 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
MK_HTML=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
@ -298,7 +298,7 @@ KTMAKE= TOOLS_PREFIX=${WORLDTMP} MAKEOBJDIRPREFIX=${WORLDTMP} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
MK_HTML=no -DNO_LINT MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no
@ -443,7 +443,7 @@ LIB32WMAKEFLAGS+= CC="${XCC} ${LIB32FLAGS}" \
MK_TESTS=no
LIB32WMAKE= ${LIB32WMAKEENV} ${MAKE} ${LIB32WMAKEFLAGS} \
MK_MAN=no MK_INFO=no MK_HTML=no MK_HYPERV=no MK_BHYVE=no
MK_MAN=no MK_HTML=no MK_HYPERV=no MK_BHYVE=no
LIB32IMAKE= ${LIB32WMAKE:NINSTALL=*:NDESTDIR=*:N_LDSCRIPTROOT=*} \
MK_TOOLCHAIN=no ${IMAKE_INSTALL}
.endif
@ -595,7 +595,7 @@ _libraries:
@echo ">>> stage 4.2: building libraries"
@echo "--------------------------------------------------------------"
${_+_}cd ${.CURDIR}; \
${WMAKE} -DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT MK_MAN=no \
${WMAKE} -DNO_FSCHG MK_HTML=no -DNO_LINT MK_MAN=no \
MK_PROFILE=no MK_TESTS=no MK_TESTS_SUPPORT=${MK_TESTS} libraries
_depend:
@echo
@ -789,9 +789,6 @@ __installcheck_UGID:
#
# Required install tools to be saved in a scratch dir for safety.
#
.if ${MK_INFO} != "no"
_install-info= install-info
.endif
.if ${MK_ZONEINFO} != "no"
_zoneinfo= zic tzsetup
.endif
@ -1448,8 +1445,10 @@ _kgzip= usr.sbin/kgzip
.endif
# If we're given an XAS, don't build binutils.
.if ${XAS:M/*} == "" && ${MK_BINUTILS_BOOTSTRAP} != "no"
.if ${XAS:M/*} == ""
.if ${MK_BINUTILS_BOOTSTRAP} != "no"
_binutils= gnu/usr.bin/binutils
.endif
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
_elftctools= lib/libelftc \
usr.bin/addr2line \
@ -1501,7 +1500,7 @@ NXBMAKE= ${NXBENV} ${MAKE} \
MACHINE=${TARGET} MACHINE_ARCH=${TARGET_ARCH} \
MK_DEBUG_FILES=no MK_GDB=no MK_TESTS=no \
SSP_CFLAGS= \
MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \
MK_HTML=no NO_LINT=yes MK_MAN=no \
-DNO_PIC MK_PROFILE=no -DNO_SHARED \
-DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \
MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \
@ -2034,7 +2033,7 @@ XDEV_CPUTYPE?=${CPUTYPE}
XDEV_CPUTYPE?=${TARGET_CPUTYPE}
.endif
NOFUN=-DNO_FSCHG MK_HTML=no MK_INFO=no -DNO_LINT \
NOFUN=-DNO_FSCHG MK_HTML=no -DNO_LINT \
MK_MAN=no MK_NLS=no MK_PROFILE=no \
MK_KERBEROS=no MK_RESCUE=no MK_TESTS=no MK_WARNS=no \
MK_DEBUG_FILES=no \

View File

@ -38,6 +38,103 @@
# xargs -n1 | sort | uniq -d;
# done
# 20150102: removal of texinfo
OLD_FILES+=usr/bin/info
OLD_FILES+=usr/bin/infokey
OLD_FILES+=usr/bin/install-info
OLD_FILES+=usr/bin/makeinfo
OLD_FILES+=usr/bin/texindex
OLD_FILES+=usr/share/info/am-utils.info.gz
OLD_FILES+=usr/share/info/as-utils.info.gz
OLD_FILES+=usr/share/info/binutils.info.gz
OLD_FILES+=usr/share/info/com_err.info.gz
OLD_FILES+=usr/share/info/diff.info.gz
OLD_FILES+=usr/share/info/gdb.info.gz
OLD_FILES+=usr/share/info/gdbint.info.gz
OLD_FILES+=usr/share/info/gperf.info.gz
OLD_FILES+=usr/share/info/grep.info.gz
OLD_FILES+=usr/share/info/groff.info.gz
OLD_FILES+=usr/share/info/heimdal.info.gz
OLD_FILES+=usr/share/info/history.info.gz
OLD_FILES+=usr/share/info/info-stnd.info.gz
OLD_FILES+=usr/share/info/info.info.gz
OLD_FILES+=usr/share/info/ld.info.gz
OLD_FILES+=usr/share/info/regex.info.gz
OLD_FILES+=usr/share/info/rluserman.info.gz
OLD_FILES+=usr/share/info/stabs.info.gz
OLD_FILES+=usr/share/info/texinfo.info.gz
OLD_FILES+=usr/share/man/man1/info.1.gz
OLD_FILES+=usr/share/man/man1/infokey.1.gz
OLD_FILES+=usr/share/man/man1/install-info.1.gz
OLD_FILES+=usr/share/man/man1/makeinfo.1.gz
OLD_FILES+=usr/share/man/man1/texindex.1.gz
OLD_FILES+=usr/share/man/man5/info.5.gz
OLD_FILES+=usr/share/man/man5/texinfo.5.gz
# 20141231: new clang import which bumps version from 3.4.1 to 3.5.0.
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_aes.h
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_pclmul.h
OLD_FILES+=usr/include/clang/3.4.1/altivec.h
OLD_FILES+=usr/include/clang/3.4.1/ammintrin.h
OLD_FILES+=usr/include/clang/3.4.1/arm_neon.h
OLD_FILES+=usr/include/clang/3.4.1/avx2intrin.h
OLD_FILES+=usr/include/clang/3.4.1/avxintrin.h
OLD_FILES+=usr/include/clang/3.4.1/bmi2intrin.h
OLD_FILES+=usr/include/clang/3.4.1/bmiintrin.h
OLD_FILES+=usr/include/clang/3.4.1/cpuid.h
OLD_FILES+=usr/include/clang/3.4.1/emmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/f16cintrin.h
OLD_FILES+=usr/include/clang/3.4.1/fma4intrin.h
OLD_FILES+=usr/include/clang/3.4.1/fmaintrin.h
OLD_FILES+=usr/include/clang/3.4.1/immintrin.h
OLD_FILES+=usr/include/clang/3.4.1/lzcntintrin.h
OLD_FILES+=usr/include/clang/3.4.1/mm3dnow.h
OLD_FILES+=usr/include/clang/3.4.1/mm_malloc.h
OLD_FILES+=usr/include/clang/3.4.1/mmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/module.map
OLD_FILES+=usr/include/clang/3.4.1/nmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/pmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/popcntintrin.h
OLD_FILES+=usr/include/clang/3.4.1/prfchwintrin.h
OLD_FILES+=usr/include/clang/3.4.1/rdseedintrin.h
OLD_FILES+=usr/include/clang/3.4.1/rtmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/shaintrin.h
OLD_FILES+=usr/include/clang/3.4.1/smmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/tbmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/tmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/wmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/x86intrin.h
OLD_FILES+=usr/include/clang/3.4.1/xmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/xopintrin.h
OLD_DIRS+=usr/include/clang/3.4.1
# 20141226: Remove gpib/ieee488
OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h
OLD_FILES+=usr/include/dev/ieee488/tnt4882.h
OLD_FILES+=usr/include/dev/ieee488/ugpib.h
OLD_FILES+=usr/include/dev/ieee488/upd7210.h
OLD_DIRS+=usr/include/dev/ieee488
OLD_FILES+=usr/include/gpib/gpib.h
OLD_DIRS+=usr/include/gpib
OLD_FILES+=usr/lib/libgpib.a
OLD_FILES+=usr/lib/libgpib_p.a
OLD_FILES+=usr/lib/libgpib.so
OLD_LIBS+=usr/lib/libgpib.so.3
OLD_FILES+=usr/lib/libgpib_p.a
OLD_FILES+=share/man/man4/pcii.4.gz
OLD_FILES+=share/man/man4/gpib.4.gz
OLD_FILES+=share/man/man4/tnt4882.4.gz
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
OLD_FILES+=usr/lib32/libgpib.a
OLD_FILES+=usr/lib32/libgpib_p.a
OLD_FILES+=usr/lib32/libgpib.so
OLD_LIBS+=usr/lib32/libgpib.so.3
.endif
# 20141224: libxo moved to /lib
OLD_LIBS+=usr/lib/libxo.so.0
# 20141223: remove in6_gif.h, in_gif.h and if_stf.h
OLD_FILES+=usr/include/net/if_stf.h
OLD_FILES+=usr/include/netinet/in_gif.h
OLD_FILES+=usr/include/netinet6/in6_gif.h
# 20141202: update to mandoc CVS 20141201
OLD_FILES+=usr.bin/preconv
OLD_FILES+=share/man/man1/preconv.1.gz

View File

@ -31,6 +31,80 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20150102:
The GNU texinfo and GNU info pages have been removed.
To be able to view GNU info pages please install texinfo from ports.
20141231:
Clang, llvm and lldb have been upgraded to 3.5.0 release.
As of this release, a prerequisite for building clang, llvm and lldb is
a C++11 capable compiler and C++11 standard library. This means that to
be able to successfully build the cross-tools stage of buildworld, with
clang as the bootstrap compiler, your system compiler or cross compiler
should either be clang 3.3 or later, or gcc 4.8 or later, and your
system C++ library should be libc++, or libdstdc++ from gcc 4.8 or
later.
On any standard FreeBSD 10.x or 11.x installation, where clang and
libc++ are on by default (that is, on x86 or arm), this should work out
of the box.
On 9.x installations where clang is enabled by default, e.g. on x86 and
powerpc, libc++ will not be enabled by default, so libc++ should be
built (with clang) and installed first. If both clang and libc++ are
missing, build clang first, then use it to build libc++.
On 8.x and earlier installations, upgrade to 9.x first, and then follow
the instructions for 9.x above.
Sparc64 and mips users are unaffected, as they still use gcc 4.2.1 by
default, and do not build clang.
Many embedded systems are resource constrained, and will not be able to
build clang in a reasonable time, or in some cases at all. In those
cases, cross building bootable systems on amd64 is a workaround.
This new version of clang introduces a number of new warnings, of which
the following are most likely to appear:
-Wabsolute-value
This warns in two cases, for both C and C++:
* When the code is trying to take the absolute value of an unsigned
quantity, which is effectively a no-op, and almost never what was
intended. The code should be fixed, if at all possible. If you are
sure that the unsigned quantity can be safely cast to signed, without
loss of information or undefined behavior, you can add an explicit
cast, or disable the warning.
* When the code is trying to take an absolute value, but the called
abs() variant is for the wrong type, which can lead to truncation.
If you want to disable the warning instead of fixing the code, please
make sure that truncation will not occur, or it might lead to unwanted
side-effects.
-Wtautological-undefined-compare and
-Wundefined-bool-conversion
These warn when C++ code is trying to compare 'this' against NULL, while
'this' should never be NULL in well-defined C++ code. However, there is
some legacy (pre C++11) code out there, which actively abuses this
feature, which was less strictly defined in previous C++ versions.
Squid and openjdk do this, for example. The warning can be turned off
for C++98 and earlier, but compiling the code in C++11 mode might result
in unexpected behavior; for example, the parts of the program that are
unreachable could be optimized away.
20141222:
The old NFS client and server (kernel options NFSCLIENT, NFSSERVER)
kernel sources have been removed. The .h files remain, since some
utilities include them. This will need to be fixed later.
If "mount -t oldnfs ..." is attempted, it will fail.
If the "-o" option on mountd(8), nfsd(8) or nfsstat(1) is used,
the utilities will report errors.
20141121:
The handling of LOCAL_LIB_DIRS has been altered to skip addition of
directories to top level SUBDIR variable when their parent
@ -106,6 +180,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
The GNU texinfo and GNU info pages are not built and installed
anymore, WITH_INFO knob has been added to allow to built and install
them again.
UPDATE: see 20150102 entry on texinfo's removal
20140708:
The GNU readline library is now an INTERNALLIB - that is, it is

View File

@ -29,7 +29,7 @@
.\" @(#)symlink.7 8.3 (Berkeley) 3/31/94
.\" $FreeBSD$
.\"
.Dd April 25, 2010
.Dd December 29, 2014
.Dt SYMLINK 7
.Os
.Sh NAME
@ -219,7 +219,7 @@ would change the ownership of
.Dq Li slink
itself.
.Pp
There are four exceptions to this rule.
There are five exceptions to this rule.
The
.Xr mv 1
and
@ -262,13 +262,12 @@ a file tree.)
.Pp
The
.Xr file 1
command is also an exception to this rule.
The
.Xr file 1
command does not follow symbolic links named as argument by default.
The
.Xr file 1
command does follow symbolic links named as argument if
and
.Xr stat 1
commands are also exceptions to this rule.
These
commands do not follow symbolic links named as argument by default,
but do follow symbolic links named as argument if the
.Fl L
option is specified.
.Pp

View File

@ -90,13 +90,14 @@ exraise(int e)
/*
* Called from trap.c when a SIGINT is received. (If the user specifies
* that SIGINT is to be trapped or ignored using the trap builtin, then
* this routine is not called.) Suppressint is nonzero when interrupts
* are held using the INTOFF macro. If SIGINTs are not suppressed and
* the shell is not a root shell, then we want to be terminated if we
* get here, as if we were terminated directly by a SIGINT. Arrange for
* this here.
* Called from trap.c when a SIGINT is received and not suppressed, or when
* an interrupt is pending and interrupts are re-enabled using INTON.
* (If the user specifies that SIGINT is to be trapped or ignored using the
* trap builtin, then this routine is not called.) Suppressint is nonzero
* when interrupts are held using the INTOFF macro. If SIGINTs are not
* suppressed and the shell is not a root shell, then we want to be
* terminated if we get here, as if we were terminated directly by a SIGINT.
* Arrange for this here.
*/
void
@ -104,16 +105,6 @@ onint(void)
{
sigset_t sigs;
/*
* The !in_dotrap here is safe. The only way we can arrive here
* with in_dotrap set is that a trap handler set SIGINT to SIG_DFL
* and killed itself.
*/
if (suppressint && !in_dotrap) {
intpending++;
return;
}
intpending = 0;
sigemptyset(&sigs);
sigprocmask(SIG_SETMASK, &sigs, NULL);
@ -130,6 +121,7 @@ onint(void)
else {
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
_exit(128 + SIGINT);
}
}

View File

@ -75,11 +75,12 @@ extern volatile sig_atomic_t intpending;
#define is_int_on() suppressint
#define SETINTON(s) suppressint = (s)
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
#define SET_PENDING_INT intpending = 1
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
void exraise(int) __dead2;
void onint(void);
void onint(void) __dead2;
void warning(const char *, ...) __printflike(1, 2);
void error(const char *, ...) __printf0like(1, 2) __dead2;
void exerror(int, const char *, ...) __printf0like(2, 3) __dead2;

View File

@ -539,13 +539,13 @@ expredir(union node *n)
case NFROMTO:
case NAPPEND:
case NCLOBBER:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
expandarg(redir->nfile.fname, &fn, EXP_TILDE);
redir->nfile.expfname = fn.list->text;
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
expandarg(redir->ndup.vname, &fn, EXP_TILDE);
fixredir(redir, fn.list->text, 1);
}
break;

View File

@ -171,17 +171,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
STPUTC('\0', expdest);
p = grabstackstr(expdest);
exparg.lastp = &exparg.list;
/*
* TODO - EXP_REDIR
*/
if (flag & EXP_FULL) {
ifsbreakup(p, &exparg);
*exparg.lastp = NULL;
exparg.lastp = &exparg.list;
expandmeta(exparg.list, flag);
} else {
if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
rmescapes(p);
sp = (struct strlist *)stalloc(sizeof (struct strlist));
sp->text = p;
*exparg.lastp = sp;
@ -209,7 +204,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
* expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
* Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
* This is used to expand word in ${var+word} etc.
* If EXP_FULL, EXP_CASE or EXP_REDIR are set, keep and/or generate CTLESC
* If EXP_FULL or EXP_CASE are set, keep and/or generate CTLESC
* characters to allow for further processing.
* If EXP_FULL is set, also preserve CTLQUOTEMARK characters.
*/
@ -217,7 +212,7 @@ static char *
argstr(char *p, int flag)
{
char c;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
int firsteq = 1;
int split_lit;
int lit_quoted;
@ -303,7 +298,7 @@ exptilde(char *p, int flag)
char c, *startp = p;
struct passwd *pw;
char *home;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
while ((c = *p) != '\0') {
switch(c) {
@ -437,7 +432,7 @@ expbackq(union node *cmd, int quoted, int flag)
char lastc;
int startloc = dest - stackblock();
char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
size_t nnl;
INTOFF;
@ -637,7 +632,7 @@ evalvar(char *p, int flag)
int varlen;
int varlenb;
int easy;
int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
int quotes = flag & (EXP_FULL | EXP_CASE);
varflags = (unsigned char)*p++;
subtype = varflags & VSTYPE;
@ -862,7 +857,7 @@ varisset(const char *name, int nulok)
static void
strtodest(const char *p, int flag, int subtype, int quoted)
{
if (flag & (EXP_FULL | EXP_CASE | EXP_REDIR) && subtype != VSLENGTH)
if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH)
STPUTS_QUOTES(p, quoted ? DQSYNTAX : BASESYNTAX, expdest);
else
STPUTS(p, expdest);
@ -1104,7 +1099,6 @@ expandmeta(struct strlist *str, int flag __unused)
struct strlist **savelastp;
struct strlist *sp;
char c;
/* TODO - EXP_REDIR */
while (str) {
savelastp = exparg.lastp;

View File

@ -50,7 +50,6 @@ struct arglist {
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
#define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */

View File

@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$");
static char sigmode[NSIG]; /* current value of signal */
volatile sig_atomic_t pendingsig; /* indicates some signal received */
volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */
int in_dotrap; /* do we execute in a trap handler? */
static int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
/* indicates specified signal received */
@ -380,7 +380,15 @@ onsig(int signo)
{
if (signo == SIGINT && trap[SIGINT] == NULL) {
onint();
/*
* The !in_dotrap here is safe. The only way we can arrive
* here with in_dotrap set is that a trap handler set SIGINT to
* SIG_DFL and killed itself.
*/
if (suppressint && !in_dotrap)
SET_PENDING_INT;
else
onint();
return;
}

View File

@ -35,7 +35,6 @@
extern volatile sig_atomic_t pendingsig;
extern volatile sig_atomic_t pendingsig_waitcmd;
extern int in_dotrap;
void clear_traps(void);
int have_traps(void);

View File

@ -443,7 +443,7 @@ This feature becomes
.Sy active
once a
.Sy recordsize
property has been set larger than 128KB, and will return to being
property has been set larger than 128KB, and will return to being
.Sy enabled
once all filesystems that have ever had their recordsize larger than 128KB
are destroyed.

View File

@ -4509,11 +4509,12 @@ zpool_do_status(int argc, char **argv)
}
typedef struct upgrade_cbdata {
int cb_first;
char cb_poolname[ZPOOL_MAXNAMELEN];
int cb_argc;
uint64_t cb_version;
char **cb_argv;
boolean_t cb_first;
boolean_t cb_unavail;
char cb_poolname[ZPOOL_MAXNAMELEN];
int cb_argc;
uint64_t cb_version;
char **cb_argv;
} upgrade_cbdata_t;
#ifdef __FreeBSD__
@ -4629,6 +4630,14 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
boolean_t printnl = B_FALSE;
int ret;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
/* Allow iteration to continue. */
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4689,6 +4698,26 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
return (0);
}
static int
upgrade_list_unavail(zpool_handle_t *zhp, void *arg)
{
upgrade_cbdata_t *cbp = arg;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
if (cbp->cb_first) {
(void) fprintf(stderr, gettext("The following pools "
"are unavailable and cannot be upgraded as this "
"time.\n\n"));
(void) fprintf(stderr, gettext("POOL\n"));
(void) fprintf(stderr, gettext("------------\n"));
cbp->cb_first = B_FALSE;
}
(void) printf(gettext("%s\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
}
return (0);
}
static int
upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
{
@ -4696,6 +4725,15 @@ upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config;
uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
/*
* This will have been reported by upgrade_list_unavail so
* just allow iteration to continue.
*/
cbp->cb_unavail = B_TRUE;
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4729,6 +4767,15 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config;
uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
/*
* This will have been reported by upgrade_list_unavail so
* just allow iteration to continue.
*/
cbp->cb_unavail = B_TRUE;
return (0);
}
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@ -4782,10 +4829,17 @@ upgrade_one(zpool_handle_t *zhp, void *data)
uint64_t cur_version;
int ret;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"is currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
return (1);
}
if (strcmp("log", zpool_get_name(zhp)) == 0) {
(void) printf(gettext("'log' is now a reserved word\n"
"Pool 'log' must be renamed using export and import"
" to upgrade.\n"));
" to upgrade.\n\n"));
return (1);
}
@ -4829,7 +4883,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
#endif /* __FreeBSD __*/
} else if (cur_version == SPA_VERSION) {
(void) printf(gettext("Pool '%s' already has all "
"supported features enabled.\n"),
"supported features enabled.\n\n"),
zpool_get_name(zhp));
}
}
@ -4986,11 +5040,13 @@ zpool_do_upgrade(int argc, char **argv)
ret = zpool_iter(g_zfs, upgrade_cb, &cb);
if (ret == 0 && cb.cb_first) {
if (cb.cb_version == SPA_VERSION) {
(void) printf(gettext("All pools are already "
"formatted using feature flags.\n\n"));
(void) printf(gettext("Every feature flags "
(void) printf(gettext("All %spools are already "
"formatted using feature flags.\n\n"),
cb.cb_unavail ? gettext("available ") : "");
(void) printf(gettext("Every %sfeature flags "
"pool already has all supported features "
"enabled.\n"));
"enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("All pools are already "
"formatted with version %llu or higher.\n"),
@ -4998,13 +5054,22 @@ zpool_do_upgrade(int argc, char **argv)
}
}
} else if (argc == 0) {
cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb);
assert(ret == 0);
if (!cb.cb_first) {
(void) fprintf(stderr, "\n");
}
cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
assert(ret == 0);
if (cb.cb_first) {
(void) printf(gettext("All pools are formatted "
"using feature flags.\n\n"));
(void) printf(gettext("All %spools are formatted using "
"feature flags.\n\n"), cb.cb_unavail ?
gettext("available ") : "");
} else {
(void) printf(gettext("\nUse 'zpool upgrade -v' "
"for a list of available legacy versions.\n"));
@ -5015,13 +5080,14 @@ zpool_do_upgrade(int argc, char **argv)
assert(ret == 0);
if (cb.cb_first) {
(void) printf(gettext("Every feature flags pool has "
"all supported features enabled.\n"));
(void) printf(gettext("Every %sfeature flags pool has "
"all supported features enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("\n"));
}
} else {
ret = for_each_pool(argc, argv, B_FALSE, NULL,
ret = for_each_pool(argc, argv, B_TRUE, NULL,
upgrade_one, &cb);
}

View File

@ -127,6 +127,7 @@ dtrace_dof_init(void)
int efd;
char *s;
size_t shstridx;
uint64_t aligned_filesz;
#endif
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
@ -171,6 +172,7 @@ dtrace_dof_init(void)
if (s != NULL && strcmp(s, ".SUNW_dof") == 0) {
dofdata = elf_getdata(scn, NULL);
dof = dofdata->d_buf;
break;
}
}
}
@ -182,7 +184,9 @@ dtrace_dof_init(void)
}
while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
dof_next = (void *) ((char *) dof + dof->dofh_filesz);
aligned_filesz = (shdr.sh_addralign == 0 ? dof->dofh_filesz :
roundup2(dof->dofh_filesz, shdr.sh_addralign));
dof_next = (void *) ((char *) dof + aligned_filesz);
#endif
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||

View File

@ -685,8 +685,8 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
elf_file.ehdr.e_machine = EM_ARM;
#elif defined(__mips__)
elf_file.ehdr.e_machine = EM_MIPS;
#elif defined(__powerpc__)
elf_file.ehdr.e_machine = EM_PPC;
#elif defined(__powerpc64__)
elf_file.ehdr.e_machine = EM_PPC64;
#elif defined(__sparc)
elf_file.ehdr.e_machine = EM_SPARCV9;
#elif defined(__i386) || defined(__amd64)
@ -784,21 +784,32 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
static int
dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
GElf_Sym *sym)
GElf_Sym *sym, int uses_funcdesc, Elf *elf)
{
int i, ret = -1;
Elf64_Addr symval;
Elf_Scn *opd_scn;
Elf_Data *opd_desc;
GElf_Sym s;
for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC &&
shn == sym->st_shndx &&
sym->st_value <= addr &&
addr < sym->st_value + sym->st_size) {
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
return (0);
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
symval = sym->st_value;
if (uses_funcdesc) {
opd_scn = elf_getscn(elf, sym->st_shndx);
opd_desc = elf_rawdata(opd_scn, NULL);
symval =
*(uint64_t*)((char *)opd_desc->d_buf + symval);
}
if ((uses_funcdesc || shn == sym->st_shndx) &&
symval <= addr &&
addr < symval + sym->st_size) {
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
return (0);
ret = 0;
s = *sym;
ret = 0;
s = *sym;
}
}
}
@ -1375,7 +1386,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
continue;
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym) != 0) {
shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0) {
dt_strtab_destroy(strtab);
goto err;
}
@ -1536,7 +1548,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
p = strhyphenate(p + 3); /* strlen("___") */
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym) != 0)
shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0)
goto err;
if (fsym.st_name > data_str->d_size)

View File

@ -256,7 +256,8 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len,
break;
case ZPOOL_PROP_HEALTH:
(void) strlcpy(buf, "FAULTED", len);
(void) strlcpy(buf,
zpool_pool_state_to_name(POOL_STATE_UNAVAIL), len);
break;
case ZPOOL_PROP_GUID:

View File

@ -74,8 +74,8 @@ Write the output to file in
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr ctfmerge 1 ,
.Xr ctfdump 1
.Xr ctfdump 1 ,
.Xr ctfmerge 1
.Sh HISTORY
The
.Nm

View File

@ -6185,7 +6185,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
howto = NULL;
if (r_type < R_PPC_max)
howto = ppc_elf_howto_table[r_type];
switch (r_type)
switch ((int) r_type)
{
default:
(*_bfd_error_handler)

View File

@ -1548,7 +1548,7 @@ ppc_insert_operand (unsigned long insn,
errmsg = NULL;
insn = (*operand->insert) (insn, (long) val, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad_where (file, line, errmsg);
as_bad_where (file, line, "%s", errmsg);
}
else
insn |= ((long) val & operand->bitm) << operand->shift;
@ -2279,7 +2279,7 @@ md_assemble (char *str)
{
insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad (errmsg);
as_bad ("%s", errmsg);
continue;
}
@ -2292,7 +2292,7 @@ md_assemble (char *str)
{
insn = (*operand->insert) (insn, 0L, ppc_cpu, &errmsg);
if (errmsg != (const char *) NULL)
as_bad (errmsg);
as_bad ("%s", errmsg);
}
if ((operand->flags & PPC_OPERAND_NEXT) != 0)
next_opindex = *opindex_ptr + 1;

View File

@ -1040,6 +1040,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
{
for (i = 0; i < expressionP->X_add_number; ++i)
generic_bignum[i] = ~generic_bignum[i];
/* Extend the bignum to at least the size of .octa. */
if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER)
{
expressionP->X_add_number = SIZE_OF_LARGE_NUMBER;
for (; i < expressionP->X_add_number; ++i)
generic_bignum[i] = ~(LITTLENUM_TYPE) 0;
}
if (c == '-')
for (i = 0; i < expressionP->X_add_number; ++i)
{
@ -1050,14 +1059,12 @@ operand (expressionS *expressionP, enum expr_mode mode)
}
else if (c == '!')
{
int nonzero = 0;
for (i = 0; i < expressionP->X_add_number; ++i)
{
if (generic_bignum[i])
nonzero = 1;
generic_bignum[i] = 0;
}
generic_bignum[0] = nonzero;
if (generic_bignum[i] != 0)
break;
expressionP->X_add_number = i >= expressionP->X_add_number;
expressionP->X_op = O_constant;
expressionP->X_unsigned = 1;
}
}
else if (expressionP->X_op != O_illegal

View File

@ -335,7 +335,7 @@ input_scrub_next_buffer (char **bufp)
if (partial_size)
{
memcpy (buffer_start + BEFORE_SIZE, partial_where,
memmove (buffer_start + BEFORE_SIZE, partial_where,
(unsigned int) partial_size);
memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
}

View File

@ -4117,15 +4117,32 @@ emit_expr (expressionS *exp, unsigned int nbytes)
unsigned int size;
LITTLENUM_TYPE *nums;
know (nbytes % CHARS_PER_LITTLENUM == 0);
size = exp->X_add_number * CHARS_PER_LITTLENUM;
if (nbytes < size)
{
as_warn (_("bignum truncated to %d bytes"), nbytes);
int i = nbytes / CHARS_PER_LITTLENUM;
if (i != 0)
{
LITTLENUM_TYPE sign = 0;
if ((generic_bignum[--i]
& (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0)
sign = ~(LITTLENUM_TYPE) 0;
while (++i < exp->X_add_number)
if (generic_bignum[i] != sign)
break;
}
if (i < exp->X_add_number)
as_warn (_("bignum truncated to %d bytes"), nbytes);
size = nbytes;
}
if (nbytes == 1)
{
md_number_to_chars (p, (valueT) generic_bignum[0], 1);
return;
}
know (nbytes % CHARS_PER_LITTLENUM == 0);
if (target_big_endian)
{
while (nbytes > size)

View File

@ -366,7 +366,7 @@ snmp_pdu_decrypt(const struct snmp_pdu *pdu)
return (SNMP_CODE_OK);
}
int
enum snmp_code
snmp_passwd_to_keys(struct snmp_user *user, char *passwd __unused)
{
if (user->auth_proto == SNMP_AUTH_NOAUTH &&
@ -378,7 +378,7 @@ snmp_passwd_to_keys(struct snmp_user *user, char *passwd __unused)
return (SNMP_CODE_FAILED);
}
int
enum snmp_code
snmp_get_local_keys(struct snmp_user *user, uint8_t *eid __unused,
uint32_t elen __unused)
{

View File

@ -1,4 +1,3 @@
.PU
.TH bzip2 1
.SH NAME
bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6

View File

@ -7,7 +7,7 @@
.\" $Header: /home/hugh/sources/old_ae/RCS/ee.1,v 1.22 2001/12/16 04:49:27 hugh Exp $
.\"
.\"
.TH ee 1 "" "" "" ""
.TH ee 1 "" "" ""
.SH NAME
ee \- easy editor
.SH SYNOPSIS

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 $
*/
/*
@ -770,6 +770,8 @@ _ELF_DEFINE_EM(EM_ETPU, 178, \
"Freescale Extended Time Processing Unit") \
_ELF_DEFINE_EM(EM_SLE9X, 179, \
"Infineon Technologies SLE9X core") \
_ELF_DEFINE_EM(EM_AARCH64, 183, \
"AArch64 (64-bit ARM)") \
_ELF_DEFINE_EM(EM_AVR32, 185, \
"Atmel Corporation 32-bit microprocessor family") \
_ELF_DEFINE_EM(EM_STM8, 186, \
@ -819,7 +821,8 @@ enum {
EM__LAST__
};
/* Older synonyms. */
/* Other synonyms. */
#define EM_AMD64 EM_X86_64
#define EM_ARC_A5 EM_ARC_COMPACT
/*
@ -2112,11 +2115,11 @@ typedef struct {
/* 64-bit entry. */
typedef struct {
Elf64_Word l_name;
Elf64_Word l_time_stamp;
Elf64_Word l_checksum;
Elf64_Word l_version;
Elf64_Word l_flags;
Elf64_Word l_name; /* The name of a shared object. */
Elf64_Word l_time_stamp; /* 32-bit timestamp. */
Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */
Elf64_Word l_version; /* Interface version string index. */
Elf64_Word l_flags; /* Flags (LL_*). */
} Elf64_Lib;
#define _ELF_DEFINE_LL_FLAGS() \
@ -2364,12 +2367,12 @@ typedef struct {
/* 64 bit PHDR entry. */
typedef struct {
Elf64_Word p_type; /* Type of segment. */
Elf64_Word p_flags; /* File offset to segment. */
Elf64_Off p_offset; /* Virtual address in memory. */
Elf64_Addr p_vaddr; /* Physical address (if relevant). */
Elf64_Addr p_paddr; /* Size of segment in file. */
Elf64_Xword p_filesz; /* Size of segment in memory. */
Elf64_Xword p_memsz; /* Segment flags. */
Elf64_Word p_flags; /* Segment flags. */
Elf64_Off p_offset; /* File offset to segment. */
Elf64_Addr p_vaddr; /* Virtual address in memory. */
Elf64_Addr p_paddr; /* Physical address (if relevant). */
Elf64_Xword p_filesz; /* Size of segment in file. */
Elf64_Xword p_memsz; /* Size of segment in memory. */
Elf64_Xword p_align; /* Alignment constraints. */
} Elf64_Phdr;
@ -2453,11 +2456,11 @@ typedef struct {
typedef struct {
Elf64_Word st_name; /* index of symbol's name */
unsigned char st_info; /* value for the symbol */
unsigned char st_other; /* size of associated data */
Elf64_Half st_shndx; /* type and binding attributes */
Elf64_Addr st_value; /* visibility */
Elf64_Xword st_size; /* index of related section */
unsigned char st_info; /* type and binding attributes */
unsigned char st_other; /* visibility */
Elf64_Half st_shndx; /* index of related section */
Elf64_Addr st_value; /* value for the symbol */
Elf64_Xword st_size; /* size of associated data */
} Elf64_Sym;
#define ELF32_ST_BIND(I) ((I) >> 4)

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

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: elfcopy.h 2970 2013-12-01 15:22:12Z kaiwang27 $
* $Id: elfcopy.h 3134 2014-12-23 10:43:59Z kaiwang27 $
*/
#include <sys/queue.h>
@ -115,6 +115,7 @@ struct segment;
/* Internal data structure for sections. */
struct section {
struct segment *seg; /* containing segment */
struct segment *seg_tls; /* tls segment */
const char *name; /* section name */
char *newname; /* new section name */
Elf_Scn *is; /* input scn */

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

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2007-2011 Kai Wang
* Copyright (c) 2007-2011,2014 Kai Wang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -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 3134 2014-12-23 10:43:59Z 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);
@ -477,7 +485,10 @@ insert_shtab(struct elfcopy *ecp, int tail)
if ((shtab = calloc(1, sizeof(*shtab))) == NULL)
errx(EXIT_FAILURE, "calloc failed");
if (!tail) {
/* shoff of input object is used as a hint. */
/*
* "shoff" of input object is used as a hint for section
* resync later.
*/
if (gelf_getehdr(ecp->ein, &ieh) == NULL)
errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
elf_errmsg(-1));
@ -756,14 +767,23 @@ resync_sections(struct elfcopy *ecp)
first = 0;
}
/*
* Ignore TLS sections with load address 0 and without
* content. We don't need to adjust their file offset or
* VMA, only the size matters.
*/
if (s->seg_tls != NULL && s->type == SHT_NOBITS &&
s->off == 0)
continue;
/* Align section offset. */
if (off <= s->off) {
if (!s->loadable)
s->off = roundup(off, s->align);
} else {
if (s->loadable)
warnx("moving loadable section,"
"is this intentional?");
warnx("moving loadable section %s, "
"is this intentional?", s->name);
s->off = roundup(off, s->align);
}
@ -1042,6 +1062,17 @@ copy_data(struct section *s)
od->d_size = id->d_size;
od->d_version = id->d_version;
}
/*
* Alignment Fixup. libelf does not allow the alignment for
* Elf_Data descriptor to be set to 0. In this case we workaround
* it by setting the alignment to 1.
*
* According to the ELF ABI, alignment 0 and 1 has the same
* meaning: the section has no alignment constraints.
*/
if (od->d_align == 0)
od->d_align = 1;
}
struct section *
@ -1139,12 +1170,6 @@ add_to_shstrtab(struct elfcopy *ecp, const char *name)
struct section *s;
s = ecp->shstrtab;
if (s->buf == NULL) {
insert_to_strtab(s, "");
insert_to_strtab(s, ".symtab");
insert_to_strtab(s, ".strtab");
insert_to_strtab(s, ".shstrtab");
}
insert_to_strtab(s, name);
}
@ -1206,6 +1231,11 @@ init_shstrtab(struct elfcopy *ecp)
s->loadable = 0;
s->type = SHT_STRTAB;
s->vma = 0;
insert_to_strtab(s, "");
insert_to_strtab(s, ".symtab");
insert_to_strtab(s, ".strtab");
insert_to_strtab(s, ".shstrtab");
}
void

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 3134 2014-12-23 10:43:59Z kaiwang27 $");
static void insert_to_inseg_list(struct segment *seg, struct section *sec);
@ -73,17 +73,21 @@ 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)
s->seg = seg;
else if (seg->type == PT_TLS)
s->seg_tls = seg;
s->lma = seg->addr + (s->off - seg->off);
loadable = 1;
}
@ -97,7 +101,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 +118,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 3135 2014-12-24 08:22:43Z kaiwang27 $");
/* Symbol table buffer structure. */
struct symbuf {
@ -46,12 +46,25 @@ struct symbuf {
size_t gcap, lcap; /* buffer capacities. */
};
struct sthash {
LIST_ENTRY(sthash) sh_next;
size_t sh_off;
};
typedef LIST_HEAD(,sthash) hash_head;
#define STHASHSIZE 65536
struct strimpl {
char *buf; /* string table */
size_t sz; /* entries */
size_t cap; /* buffer capacity */
hash_head hash[STHASHSIZE];
};
/* String table buffer structure. */
struct strbuf {
char *l; /* local symbol string table */
char *g; /* global symbol string table */
size_t lsz, gsz; /* size of each kind */
size_t gcap, lcap; /* buffer capacities. */
struct strimpl l; /* local symbols */
struct strimpl g; /* global symbols */
};
static int is_debug_symbol(unsigned char st_info);
@ -62,10 +75,12 @@ static int is_needed_symbol(struct elfcopy *ecp, int i, GElf_Sym *s);
static int is_remove_symbol(struct elfcopy *ecp, size_t sc, int i,
GElf_Sym *s, const char *name);
static int is_weak_symbol(unsigned char st_info);
static int lookup_exact_string(const char *buf, size_t sz, const char *s);
static int lookup_exact_string(hash_head *hash, const char *buf,
const char *s);
static int generate_symbols(struct elfcopy *ecp);
static void mark_symbols(struct elfcopy *ecp, size_t sc);
static int match_wildcard(const char *name, const char *pattern);
uint32_t str_hash(const char *s);
/* Convenient bit vector operation macros. */
#define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7))
@ -300,7 +315,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)
@ -316,11 +331,10 @@ generate_symbols(struct elfcopy *ecp)
if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
err(EXIT_FAILURE, "calloc failed");
sy_buf->gcap = sy_buf->lcap = 64;
st_buf->gcap = 256;
st_buf->lcap = 64;
st_buf->lsz = 1; /* '\0' at start. */
st_buf->gsz = 0;
nsyms = 0;
st_buf->g.cap = 256;
st_buf->l.cap = 64;
st_buf->l.sz = 1; /* '\0' at start. */
st_buf->g.sz = 0;
ecp->symtab->sz = 0;
ecp->strtab->sz = 0;
@ -542,10 +556,10 @@ generate_symbols(struct elfcopy *ecp)
/* Update st_name. */
if (ec == ELFCLASS32)
sy_buf->g32[ecp->symndx[i]].st_name +=
st_buf->lsz;
st_buf->l.sz;
else
sy_buf->g64[ecp->symndx[i]].st_name +=
st_buf->lsz;
st_buf->l.sz;
/* Update index map. */
ecp->symndx[i] += sy_buf->nls;
@ -634,6 +648,8 @@ free_symtab(struct elfcopy *ecp)
{
struct symbuf *sy_buf;
struct strbuf *st_buf;
struct sthash *sh, *shtmp;
int i;
if (ecp->symtab != NULL && ecp->symtab->buf != NULL) {
sy_buf = ecp->symtab->buf;
@ -649,10 +665,22 @@ free_symtab(struct elfcopy *ecp)
if (ecp->strtab != NULL && ecp->strtab->buf != NULL) {
st_buf = ecp->strtab->buf;
if (st_buf->l != NULL)
free(st_buf->l);
if (st_buf->g != NULL)
free(st_buf->g);
if (st_buf->l.buf != NULL)
free(st_buf->l.buf);
if (st_buf->g.buf != NULL)
free(st_buf->g.buf);
for (i = 0; i < STHASHSIZE; i++) {
LIST_FOREACH_SAFE(sh, &st_buf->l.hash[i], sh_next,
shtmp) {
LIST_REMOVE(sh, sh_next);
free(sh);
}
LIST_FOREACH_SAFE(sh, &st_buf->g.hash[i], sh_next,
shtmp) {
LIST_REMOVE(sh, sh_next);
free(sh);
}
}
}
}
@ -690,10 +718,10 @@ create_external_symtab(struct elfcopy *ecp)
if ((st_buf = calloc(1, sizeof(*st_buf))) == NULL)
err(EXIT_FAILURE, "calloc failed");
sy_buf->gcap = sy_buf->lcap = 64;
st_buf->gcap = 256;
st_buf->lcap = 64;
st_buf->lsz = 1; /* '\0' at start. */
st_buf->gsz = 0;
st_buf->g.cap = 256;
st_buf->l.cap = 64;
st_buf->l.sz = 1; /* '\0' at start. */
st_buf->g.sz = 0;
ecp->symtab->sz = 0;
ecp->strtab->sz = 0;
@ -730,6 +758,8 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
{
struct symbuf *sy_buf;
struct strbuf *st_buf;
struct sthash *sh;
uint32_t hash;
int pos;
/*
@ -762,32 +792,39 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
else \
sy_buf->B##SZ[sy_buf->n##B##s].st_shndx = \
ecp->secndx[st_shndx]; \
if (st_buf->B == NULL) { \
st_buf->B = calloc(st_buf->B##cap, sizeof(*st_buf->B)); \
if (st_buf->B == NULL) \
if (st_buf->B.buf == NULL) { \
st_buf->B.buf = calloc(st_buf->B.cap, \
sizeof(*st_buf->B.buf)); \
if (st_buf->B.buf == NULL) \
err(EXIT_FAILURE, "malloc failed"); \
} \
if (name != NULL && *name != '\0') { \
pos = lookup_exact_string(st_buf->B, \
st_buf->B##sz, name); \
pos = lookup_exact_string(st_buf->B.hash, st_buf->B.buf,\
name); \
if (pos != -1) \
sy_buf->B##SZ[sy_buf->n##B##s].st_name = pos; \
else { \
sy_buf->B##SZ[sy_buf->n##B##s].st_name = \
st_buf->B##sz; \
while (st_buf->B##sz + strlen(name) >= \
st_buf->B##cap - 1) { \
st_buf->B##cap *= 2; \
st_buf->B = realloc(st_buf->B, \
st_buf->B##cap); \
if (st_buf->B == NULL) \
st_buf->B.sz; \
while (st_buf->B.sz + strlen(name) >= \
st_buf->B.cap - 1) { \
st_buf->B.cap *= 2; \
st_buf->B.buf = realloc(st_buf->B.buf, \
st_buf->B.cap); \
if (st_buf->B.buf == NULL) \
err(EXIT_FAILURE, \
"realloc failed"); \
} \
strncpy(&st_buf->B[st_buf->B##sz], name, \
if ((sh = malloc(sizeof(*sh))) == NULL) \
err(EXIT_FAILURE, "malloc failed"); \
sh->sh_off = st_buf->B.sz; \
hash = str_hash(name); \
LIST_INSERT_HEAD(&st_buf->B.hash[hash], sh, \
sh_next); \
strncpy(&st_buf->B.buf[st_buf->B.sz], name, \
strlen(name)); \
st_buf->B[st_buf->B##sz + strlen(name)] = '\0'; \
st_buf->B##sz += strlen(name) + 1; \
st_buf->B.buf[st_buf->B.sz + strlen(name)] = '\0'; \
st_buf->B.sz += strlen(name) + 1; \
} \
} else \
sy_buf->B##SZ[sy_buf->n##B##s].st_name = 0; \
@ -812,7 +849,7 @@ add_to_symtab(struct elfcopy *ecp, const char *name, uint64_t st_value,
/* Update section size. */
ecp->symtab->sz = (sy_buf->nls + sy_buf->ngs) *
(ecp->oec == ELFCLASS32 ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym));
ecp->strtab->sz = st_buf->lsz + st_buf->gsz;
ecp->strtab->sz = st_buf->l.sz + st_buf->g.sz;
#undef _ADDSYM
}
@ -832,9 +869,9 @@ finalize_external_symtab(struct elfcopy *ecp)
st_buf = ecp->strtab->buf;
for (i = 0; (size_t) i < sy_buf->ngs; i++) {
if (ecp->oec == ELFCLASS32)
sy_buf->g32[i].st_name += st_buf->lsz;
sy_buf->g32[i].st_name += st_buf->l.sz;
else
sy_buf->g64[i].st_name += st_buf->lsz;
sy_buf->g64[i].st_name += st_buf->l.sz;
}
}
@ -921,19 +958,19 @@ create_symtab_data(struct elfcopy *ecp)
elf_errmsg(-1));
lstdata->d_align = 1;
lstdata->d_off = 0;
lstdata->d_buf = st_buf->l;
lstdata->d_size = st_buf->lsz;
lstdata->d_buf = st_buf->l.buf;
lstdata->d_size = st_buf->l.sz;
lstdata->d_type = ELF_T_BYTE;
lstdata->d_version = EV_CURRENT;
if (st_buf->gsz > 0) {
if (st_buf->g.sz > 0) {
if ((gstdata = elf_newdata(st->os)) == NULL)
errx(EXIT_FAILURE, "elf_newdata() failed: %s.",
elf_errmsg(-1));
gstdata->d_align = 1;
gstdata->d_off = lstdata->d_size;
gstdata->d_buf = st_buf->g;
gstdata->d_size = st_buf->gsz;
gstdata->d_buf = st_buf->g.buf;
gstdata->d_size = st_buf->g.sz;
gstdata->d_type = ELF_T_BYTE;
gstdata->d_version = EV_CURRENT;
}
@ -1023,18 +1060,25 @@ lookup_symop_list(struct elfcopy *ecp, const char *name, unsigned int op)
}
static int
lookup_exact_string(const char *buf, size_t sz, const char *s)
lookup_exact_string(hash_head *buckets, const char *buf, const char *s)
{
const char *b;
size_t slen;
slen = strlen(s);
for (b = buf; b < buf + sz; b += strlen(b) + 1) {
if (strlen(b) != slen)
continue;
if (!strcmp(b, s))
return (b - buf);
}
struct sthash *sh;
uint32_t hash;
hash = str_hash(s);
LIST_FOREACH(sh, &buckets[hash], sh_next)
if (strcmp(buf + sh->sh_off, s) == 0)
return sh->sh_off;
return (-1);
}
uint32_t
str_hash(const char *s)
{
uint32_t hash;
for (hash = 2166136261; *s; s++)
hash = (hash ^ *s) * 16777619;
return (hash & (STHASHSIZE - 1));
}

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

@ -247,6 +247,7 @@ constants.
.It Fn dwarf_get_VIS_name
.Dv DW_VIS_*
constants.
.El
.Sh RETURN VALUES
These functions return
.Dv DW_DLV_OK on success.

View File

@ -102,6 +102,7 @@ One of the arguments
or
.Ar cu_die_offset
was NULL.
.El
.Sh EXAMPLE
To loop through all the address lookup table entries, use:
.Bd -literal -offset indent

View File

@ -1,4 +1,4 @@
.\" Copyright (c) 2010, Joerg Wunsch
.\" Copyright (c) 2014 Kai Wang
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -22,34 +22,52 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\" $Id: dwarf_get_die_infotypes_flag.3 3118 2014-12-20 20:30:06Z jkoshy $
.\"
.Dd January 24, 2010
.Dt TNT4882 4
.Dd December 20, 2014
.Os
.Dt DWARF_GET_DIE_INFOTYPES_FLAG 3
.Sh NAME
.Nm tnt4882
.Nd National Instruments TNT4882A GPIB controller driver
.Nm dwarf_get_die_infotypes_flag
.Nd indicate the originating DWARF section for a DIE
.Sh LIBRARY
.Lb libdwarf
.Sh SYNOPSIS
.Cd "device tnt4882"
.In libdwarf.h
.Ft Dwarf_Bool
.Fo dwarf_get_die_infotypes_flag
.Fa "Dwarf_Die die"
.Fc
.Sh DESCRIPTION
The
.Nm
driver provides support for driving an IEEE-488 bus, also called
IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
Bus), or GPIB (General Purpose Instrument Bus).
The driver supports National Instruments PCI GPIB cards using
the TNT4882 bus interface chip.
This chip emulates a NEC \(mcPD7210 controller IC as the main
interface between the host computer and the instrument bus.
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 gpib 3 ,
.Xr gpib 4
.Sh HISTORY
The
.Nm
driver was written by Poul-Henning Kamp, and first appeared in
.Fx 5.4 .
.Sh AUTHORS
This manual page was written by
.An J\(:org Wunsch .
.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

@ -85,6 +85,7 @@ Either of argument
or
.Va ret_bool
was NULL.
.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,

View File

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

@ -72,6 +72,7 @@ Either of argument
or
.Va retcode
was NULL.
.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,

View File

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

@ -27,7 +27,7 @@
#include "_libdwarf.h"
ELFTC_VCSID("$Id: libdwarf_abbrev.c 2070 2011-10-27 03:05:32Z jkoshy $");
ELFTC_VCSID("$Id: libdwarf_abbrev.c 3136 2014-12-24 16:04:38Z kaiwang27 $");
int
_dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children,
@ -180,7 +180,9 @@ _dwarf_abbrev_find(Dwarf_CU cu, uint64_t entry, Dwarf_Abbrev *abp,
/* Load and search the abbrev table. */
ds = _dwarf_find_section(cu->cu_dbg, ".debug_abbrev");
assert(ds != NULL);
if (ds == NULL)
return (DW_DLE_NO_ENTRY);
offset = cu->cu_abbrev_offset_cur;
while (offset < ds->ds_size) {
ret = _dwarf_abbrev_parse(cu->cu_dbg, cu, &offset, &ab, error);

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 3136 2014-12-24 16:04:38Z 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,23 @@ _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;
if (ds == NULL)
return (DW_DLE_NO_ENTRY);
} 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 +171,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 +195,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 +210,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 +239,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 +266,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 3136 2014-12-24 16:04:38Z 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,13 +91,12 @@ _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")) ==
NULL)) {
DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
return (DW_DLE_DEBUG_INFO_NULL);
}
dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info");
/* 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 +210,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 +270,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,13 +388,31 @@ See
.It Dv SHT_STRTAB Ta Dv ELF_T_BYTE Ta String tables.
.It Dv SHT_SYMTAB Ta Dv ELF_T_SYM Ta Symbol tables.
.It Dv SHT_SYMTAB_SHNDX Ta Dv ELF_T_WORD Ta Used with extended section numbering.
.It Dv SHT_GNU_verdef Ta Dv ELF_T_VDEF Ta Symbol version definitions.
.It Dv SHT_GNU_verneed Ta Dv ELF_T_VNEED Ta Symbol versioning requirements.
.It Dv SHT_GNU_versym Ta Dv ELF_T_HALF Ta Version symbols.
.It Dv SHT_SUNW_dof Ta Dv ELF_T_BYTE Ta Xo
Used by
.Xr dtrace 1 .
.Xc
.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records.
.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags.
.It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo
Same as
.Dv SHT_GNU_verdef .
.Xc
.It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo
Same as
.Dv SHT_GNU_verneed .
.Xc
.It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo
Same as
.Dv SHT_GNU_versym .
.Xc
.El
.TE
.Pp
Section types in the range
.Ns [ Dv SHT_LOOS ,
.Dv SHT_HIUSER ]
are otherwise considered to be of type
.Dv ELF_T_BYTE .
.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

@ -32,11 +32,12 @@
#include <gelf.h>
#include <libelf.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#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 +45,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);
@ -59,7 +61,8 @@ _libelf_load_section_headers(Elf *e, void *ehdr)
#define CHECK_EHDR(E,EH) do { \
if (fsz != (EH)->e_shentsize || \
shoff + fsz * shnum > e->e_rawsize) { \
shnum > SIZE_MAX / fsz || \
fsz * shnum > e->e_rawsize - shoff) { \
LIBELF_SET_ERROR(HEADER, 0); \
return (0); \
} \
@ -104,8 +107,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"

Some files were not shown because too many files have changed in this diff Show More