libcwd-1.0.4/0000755000175000017500000000000011405442006011736 5ustar carlocarlolibcwd-1.0.4/config.guess0000755000175000017500000012763711344453613014306 0ustar carlocarlo#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2009-12-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libcwd-1.0.4/elfxx.cc0000644000175000017500000037222111401261041013374 0ustar carlocarlo// $Header$ // // Copyright (C) 2001 - 2007, by // // Carlo Wood, Run on IRC // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 // // This file may be distributed under the terms of the Q Public License // version 1.0 as appearing in the file LICENSE.QPL included in the // packaging of this file. // // // This file contains code that reads the symbol table and debug information from // ELF32/ELF64 object files. // #include "sys.h" #include #if CWDEBUG_LOCATION #include // ISO C99 header, needed for int32_t etc. #include #include #include #include #include #include #include #include "cwd_debug.h" #include "elfxx.h" #include #include "cwd_bfd.h" #include "compilation_unit.h" #define DEBUGELFXX 0 #define DEBUGSTABS 0 #define DEBUGDWARF 0 #if DEBUGELFXX || DEBUGSTABS || DEBUGDWARF static bool const default_dout_c = true; #endif #if DEBUGDWARF || DEBUGSTABS static bool doutdwarfon = default_dout_c; static bool doutstabson = default_dout_c; void debug_load_object_file(char const* filename, bool shared); #endif #if DEBUGDWARF #define DoutDwarf(cntrl, x) do { if (doutdwarfon) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(cntrl, x); _private_::set_alloc_checking_off(LIBCWD_TSD); } } while(0) #define DEBUGDWARF_OPT_COMMA(x) ,x #define DEBUGDWARF_OPT(x) x #else #define DoutDwarf(cntrl, x) do { } while(0) #define DEBUGDWARF_OPT_COMMA(x) #define DEBUGDWARF_OPT(x) #endif #if DEBUGSTABS #define DoutStabs(cntrl, x) do { if (doutstabson) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(cntrl, x); _private_::set_alloc_checking_off(LIBCWD_TSD); } } while(0) #else #define DoutStabs(cntrl, x) do { } while(0) #endif #if DEBUGELFXX static bool doutelfxxon = default_dout_c; #define DoutElfxx(cntrl, x) do { if (doutelfxxon) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(cntrl, x); _private_::set_alloc_checking_off(LIBCWD_TSD); } } while(0) #else #define DoutElfxx(cntrl, x) do { } while(0) #endif namespace libcwd { namespace elfxx { #if !defined(__x86_64__) && !defined(__sparc64) && !defined(__ia64__) typedef Elf32_Ehdr Elfxx_Ehdr; typedef Elf32_Word Elfxx_Word; typedef Elf32_Half Elfxx_Half; typedef Elf32_Addr Elfxx_Addr; typedef Elf32_Shdr Elfxx_Shdr; typedef Elf32_Sym Elfxx_Sym; #define ELFXX_ST_TYPE(var) ELF32_ST_TYPE(var) #define ELFXX_ST_BIND(var) ELF32_ST_BIND(var) #else typedef Elf64_Ehdr Elfxx_Ehdr; typedef Elf64_Word Elfxx_Word; typedef Elf64_Half Elfxx_Half; typedef Elf64_Addr Elfxx_Addr; typedef Elf64_Shdr Elfxx_Shdr; typedef Elf64_Sym Elfxx_Sym; #define ELFXX_ST_TYPE(var) ELF64_ST_TYPE(var) #define ELFXX_ST_BIND(var) ELF64_ST_BIND(var) #endif //========================================================================================================================================== // The information about ELF (Executable Linkable Format) needed to write this file // has been obtained from a file called 'ELF.doc.tar.gz'. You can get this file from // the net, for example: ftp://ftp.metalab.unc.edu/pub/Linux/GCC/ELF.doc.tar.gz. std::istream& operator>>(std::istream& is, Elfxx_Ehdr& header) { #if CWDEBUG_DEBUGM LIBCWD_TSD_DECLARATION; LIBCWD_ASSERT( !__libcwd_tsd.internal ); #endif is.read(reinterpret_cast(&header), sizeof(Elfxx_Ehdr)); return is; } //========================================================================================================================================== // The information about stabs (Symbol TABleS) was obtained from http://www.informatik.uni-frankfurt.de/doc/texi/stabs_toc.html. // // http://www.informatik.uni-frankfurt.de/doc/texi/stabs_6.html#SEC46 struct stab_st { Elfxx_Word n_strx; // Index into string table of name. unsigned char n_type; // Type of symbol. unsigned char n_other; // Misc info (usually empty). Elfxx_Half n_desc; // Description field. Elfxx_Addr n_value; // Value of symbol. }; // Type of symbol, n_type. static unsigned char const N_GSYM = 0x20; static unsigned char const N_FNAME = 0x22; static unsigned char const N_FUN = 0x24; static unsigned char const N_STSYM = 0x26; static unsigned char const N_LCSYM = 0x28; static unsigned char const N_MAIN = 0x2a; static unsigned char const N_PC = 0x30; static unsigned char const N_NSYMS = 0x32; static unsigned char const N_NOMAP = 0x34; static unsigned char const N_OBJ = 0x38; static unsigned char const N_OPT = 0x3c; static unsigned char const N_RSYM = 0x40; static unsigned char const N_M2C = 0x42; static unsigned char const N_SLINE = 0x44; static unsigned char const N_DSLINE = 0x46; static unsigned char const N_BSLINE = 0x48; static unsigned char const N_BROWS = 0x48; static unsigned char const N_DEFD = 0x4a; static unsigned char const N_EHDECL = 0x50; static unsigned char const N_MOD2 = 0x50; static unsigned char const N_CATCH = 0x54; static unsigned char const N_SSYM = 0x60; static unsigned char const N_SO = 0x64; static unsigned char const N_LSYM = 0x80; static unsigned char const N_BINCL = 0x82; static unsigned char const N_SOL = 0x84; static unsigned char const N_PSYM = 0xa0; static unsigned char const N_EINCL = 0xa2; static unsigned char const N_ENTRY = 0xa4; static unsigned char const N_LBRAC = 0xc0; static unsigned char const N_EXCL = 0xc2; static unsigned char const N_SCOPE = 0xc4; static unsigned char const N_RBRAC = 0xe0; static unsigned char const N_BCOMM = 0xe2; static unsigned char const N_ECOMM = 0xe4; static unsigned char const N_ECOML = 0xe8; static unsigned char const N_NBTEXT = 0xF0; static unsigned char const N_NBDATA = 0xF2; static unsigned char const N_NBBSS = 0xF4; static unsigned char const N_NBSTS = 0xF6; static unsigned char const N_NBLCS = 0xF8; static unsigned char const N_LENG = 0xfe; //========================================================================================================================================== // The information about DWARF was obtained from http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf // which is one of the worsed documentations I ever saw :/. // class LEB128_t { private: long M_val; public: LEB128_t(void) { } LEB128_t(LEB128_t const& leb) : M_val(leb.M_val) { } LEB128_t(long val) : M_val(val) { } LEB128_t& operator=(long val) { M_val = val; return *this; } operator long() const { return M_val; } long value(void) const { return M_val; } }; class uLEB128_t { private: unsigned long M_val; public: uLEB128_t(void) { } uLEB128_t(uLEB128_t const& leb) : M_val(leb.M_val) { } uLEB128_t(unsigned long val) : M_val(val) { } uLEB128_t& operator=(unsigned long val) { M_val = val; return *this; } operator unsigned long() const { return M_val; } unsigned long value(void) const { return M_val; } uLEB128_t& operator--(void) { --M_val; return *this; } }; static int const number_of_bits_in_LEB128_t = 8 * sizeof(LEB128_t); static int const number_of_bits_in_uLEB128_t = 8 * sizeof(uLEB128_t); static unsigned int const DW_TAG_array_type = 0x01; static unsigned int const DW_TAG_class_type = 0x02; static unsigned int const DW_TAG_entry_point = 0x03; static unsigned int const DW_TAG_enumeration_type = 0x04; static unsigned int const DW_TAG_formal_parameter = 0x05; static unsigned int const DW_TAG_imported_declaration = 0x08; static unsigned int const DW_TAG_label = 0x0a; static unsigned int const DW_TAG_lexical_block = 0x0b; static unsigned int const DW_TAG_member = 0x0d; static unsigned int const DW_TAG_pointer_type = 0x0f; static unsigned int const DW_TAG_reference_type = 0x10; static unsigned int const DW_TAG_compile_unit = 0x11; static unsigned int const DW_TAG_string_type = 0x12; static unsigned int const DW_TAG_structure_type = 0x13; static unsigned int const DW_TAG_subroutine_type = 0x15; static unsigned int const DW_TAG_typedef = 0x16; static unsigned int const DW_TAG_union_type = 0x17; static unsigned int const DW_TAG_unspecified_parameters = 0x18; static unsigned int const DW_TAG_variant = 0x19; static unsigned int const DW_TAG_common_block = 0x1a; static unsigned int const DW_TAG_common_inclusion = 0x1b; static unsigned int const DW_TAG_inheritance = 0x1c; static unsigned int const DW_TAG_inlined_subroutine = 0x1d; static unsigned int const DW_TAG_module = 0x1e; static unsigned int const DW_TAG_ptr_to_member_type = 0x1f; static unsigned int const DW_TAG_set_type = 0x20; static unsigned int const DW_TAG_subrange_type = 0x21; static unsigned int const DW_TAG_with_stmt = 0x22; static unsigned int const DW_TAG_access_declaration = 0x23; static unsigned int const DW_TAG_base_type = 0x24; static unsigned int const DW_TAG_catch_block = 0x25; static unsigned int const DW_TAG_const_type = 0x26; static unsigned int const DW_TAG_constant = 0x27; static unsigned int const DW_TAG_enumerator = 0x28; static unsigned int const DW_TAG_file_type = 0x29; static unsigned int const DW_TAG_friend = 0x2a; static unsigned int const DW_TAG_namelist = 0x2b; static unsigned int const DW_TAG_namelist_item = 0x2c; static unsigned int const DW_TAG_packed_type = 0x2d; static unsigned int const DW_TAG_subprogram = 0x2e; static unsigned int const DW_TAG_template_type_param = 0x2f; static unsigned int const DW_TAG_template_value_param = 0x30; static unsigned int const DW_TAG_thrown_type = 0x31; static unsigned int const DW_TAG_try_block = 0x32; static unsigned int const DW_TAG_variant_part = 0x33; static unsigned int const DW_TAG_variable = 0x34; static unsigned int const DW_TAG_volatile_type = 0x35; // DWARF 3. static unsigned int const DW_TAG_dwarf_procedure = 0x36; static unsigned int const DW_TAG_restrict_type = 0x37; static unsigned int const DW_TAG_interface_type = 0x38; static unsigned int const DW_TAG_namespace = 0x39; static unsigned int const DW_TAG_imported_module = 0x3a; static unsigned int const DW_TAG_unspecified_type = 0x3b; static unsigned int const DW_TAG_partial_unit = 0x3c; static unsigned int const DW_TAG_imported_unit = 0x3d; // User range. static unsigned int const DW_TAG_lo_user = 0x4080; static unsigned int const DW_TAG_hi_user = 0xffff; // SGI/MIPS Extensions. static unsigned int const DW_TAG_MIPS_loop = 0x4081; // GNU extensions. static unsigned int const DW_TAG_format_label = 0x4101; // For FORTRAN 77 and Fortran 90. static unsigned int const DW_TAG_function_template = 0x4102; // For C++. static unsigned int const DW_TAG_class_template = 0x4103; // For C++. static unsigned int const DW_TAG_GNU_BINCL = 0x4104; static unsigned int const DW_TAG_GNU_EINCL = 0x4105; #if DEBUGDWARF char const* print_DW_TAG_name(uLEB128_t tag) { switch(tag) { case DW_TAG_array_type: return "DW_TAG_array_type"; case DW_TAG_class_type: return "DW_TAG_class_type"; case DW_TAG_entry_point: return "DW_TAG_entry_point"; case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type"; case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter"; case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration"; case DW_TAG_label: return "DW_TAG_label"; case DW_TAG_lexical_block: return "DW_TAG_lexical_block"; case DW_TAG_member: return "DW_TAG_member"; case DW_TAG_pointer_type: return "DW_TAG_pointer_type"; case DW_TAG_reference_type: return "DW_TAG_reference_type"; case DW_TAG_compile_unit: return "DW_TAG_compile_unit"; case DW_TAG_string_type: return "DW_TAG_string_type"; case DW_TAG_structure_type: return "DW_TAG_structure_type"; case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type"; case DW_TAG_typedef: return "DW_TAG_typedef"; case DW_TAG_union_type: return "DW_TAG_union_type"; case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters"; case DW_TAG_variant: return "DW_TAG_variant"; case DW_TAG_common_block: return "DW_TAG_common_block"; case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion"; case DW_TAG_inheritance: return "DW_TAG_inheritance"; case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine"; case DW_TAG_module: return "DW_TAG_module"; case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type"; case DW_TAG_set_type: return "DW_TAG_set_type"; case DW_TAG_subrange_type: return "DW_TAG_subrange_type"; case DW_TAG_with_stmt: return "DW_TAG_with_stmt"; case DW_TAG_access_declaration: return "DW_TAG_access_declaration"; case DW_TAG_base_type: return "DW_TAG_base_type"; case DW_TAG_catch_block: return "DW_TAG_catch_block"; case DW_TAG_const_type: return "DW_TAG_const_type"; case DW_TAG_constant: return "DW_TAG_constant"; case DW_TAG_enumerator: return "DW_TAG_enumerator"; case DW_TAG_file_type: return "DW_TAG_file_type"; case DW_TAG_friend: return "DW_TAG_friend"; case DW_TAG_namelist: return "DW_TAG_namelist"; case DW_TAG_namelist_item: return "DW_TAG_namelist_item"; case DW_TAG_packed_type: return "DW_TAG_packed_type"; case DW_TAG_subprogram: return "DW_TAG_subprogram"; case DW_TAG_template_type_param: return "DW_TAG_template_type_param"; case DW_TAG_template_value_param: return "DW_TAG_template_value_param"; case DW_TAG_thrown_type: return "DW_TAG_thrown_type"; case DW_TAG_try_block: return "DW_TAG_try_block"; case DW_TAG_variant_part: return "DW_TAG_variant_part"; case DW_TAG_variable: return "DW_TAG_variable"; case DW_TAG_volatile_type: return "DW_TAG_volatile_type"; case DW_TAG_lo_user: return "DW_TAG_lo_user"; case DW_TAG_hi_user: return "DW_TAG_hi_user"; } switch(tag) { case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure"; case DW_TAG_restrict_type: return "DW_TAG_restrict_type"; case DW_TAG_interface_type: return "DW_TAG_interface_type"; case DW_TAG_namespace: return "DW_TAG_namespace"; case DW_TAG_imported_module: return "DW_TAG_imported_module"; case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type"; case DW_TAG_partial_unit: return "DW_TAG_partial_unit"; case DW_TAG_imported_unit: return "DW_TAG_imported_unit"; } LIBCWD_ASSERT(tag >= DW_TAG_lo_user && tag <= DW_TAG_hi_user); switch(tag) { case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; } switch(tag) { case DW_TAG_format_label: return "DW_TAG_format_label"; case DW_TAG_function_template: return "DW_TAG_function_template"; case DW_TAG_class_template: return "DW_TAG_class_template"; case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL"; case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL"; } static char unknown_tag[32]; sprintf(unknown_tag, "UNKNOWN DW_TAG 0x%lx", tag.value()); return unknown_tag; } #endif static unsigned char const DW_CHILDREN_no = 0; static unsigned char const DW_CHILDREN_yes = 1; static unsigned int const DW_AT_sibling = 0x01; // reference static unsigned int const DW_AT_location = 0x02; // block, constant static unsigned int const DW_AT_name = 0x03; // string static unsigned int const DW_AT_ordering = 0x09; // constant static unsigned int const DW_AT_byte_size = 0x0b; // constant static unsigned int const DW_AT_bit_offset = 0x0c; // constant static unsigned int const DW_AT_bit_size = 0x0d; // constant static unsigned int const DW_AT_stmt_list = 0x10; // constant static unsigned int const DW_AT_low_pc = 0x11; // address static unsigned int const DW_AT_high_pc = 0x12; // address static unsigned int const DW_AT_language = 0x13; // constant static unsigned int const DW_AT_discr = 0x15; // reference static unsigned int const DW_AT_discr_value = 0x16; // constant static unsigned int const DW_AT_visibility = 0x17; // constant static unsigned int const DW_AT_import = 0x18; // reference static unsigned int const DW_AT_string_length = 0x19; // block, constant static unsigned int const DW_AT_common_reference = 0x1a; // reference static unsigned int const DW_AT_comp_dir = 0x1b; // string static unsigned int const DW_AT_const_value = 0x1c; // string, constant, block static unsigned int const DW_AT_containing_type = 0x1d; // reference static unsigned int const DW_AT_default_value = 0x1e; // reference static unsigned int const DW_AT_inline = 0x20; // constant static unsigned int const DW_AT_is_optional = 0x21; // flag static unsigned int const DW_AT_lower_bound = 0x22; // constant, reference static unsigned int const DW_AT_producer = 0x25; // string static unsigned int const DW_AT_prototyped = 0x27; // flag static unsigned int const DW_AT_return_addr = 0x2a; // block, constant static unsigned int const DW_AT_start_scope = 0x2c; // constant static unsigned int const DW_AT_stride_size = 0x2e; // constant static unsigned int const DW_AT_upper_bound = 0x2f; // constant, reference static unsigned int const DW_AT_abstract_origin = 0x31; // reference static unsigned int const DW_AT_accessibility = 0x32; // constant static unsigned int const DW_AT_address_class = 0x33; // constant static unsigned int const DW_AT_artificial = 0x34; // flag static unsigned int const DW_AT_base_types = 0x35; // reference static unsigned int const DW_AT_calling_convention = 0x36; // constant static unsigned int const DW_AT_count = 0x37; // constant, reference static unsigned int const DW_AT_data_member_location = 0x38; // block, reference static unsigned int const DW_AT_decl_column = 0x39; // constant static unsigned int const DW_AT_decl_file = 0x3a; // constant static unsigned int const DW_AT_decl_line = 0x3b; // constant static unsigned int const DW_AT_declaration = 0x3c; // flag static unsigned int const DW_AT_discr_list = 0x3d; // block static unsigned int const DW_AT_encoding = 0x3e; // constant static unsigned int const DW_AT_external = 0x3f; // flag static unsigned int const DW_AT_frame_base = 0x40; // block, constant static unsigned int const DW_AT_friend = 0x41; // reference static unsigned int const DW_AT_identifier_case = 0x42; // constant static unsigned int const DW_AT_macro_info = 0x43; // constant static unsigned int const DW_AT_namelist_item = 0x44; // block static unsigned int const DW_AT_priority = 0x45; // reference static unsigned int const DW_AT_segment = 0x46; // block, constant static unsigned int const DW_AT_specification = 0x47; // reference static unsigned int const DW_AT_static_link = 0x48; // block, constant static unsigned int const DW_AT_type = 0x49; // reference static unsigned int const DW_AT_use_location = 0x4a; // block, constant static unsigned int const DW_AT_variable_parameter = 0x4b; // flag static unsigned int const DW_AT_virtuality = 0x4c; // constant static unsigned int const DW_AT_vtable_elem_location = 0x4d; // block, reference // DWARF 3 values. static unsigned int const DW_AT_allocated = 0x4e; static unsigned int const DW_AT_associated = 0x4f; static unsigned int const DW_AT_data_location = 0x50; static unsigned int const DW_AT_stride = 0x51; static unsigned int const DW_AT_entry_pc = 0x52; static unsigned int const DW_AT_use_UTF8 = 0x53; static unsigned int const DW_AT_extension = 0x54; static unsigned int const DW_AT_ranges = 0x55; static unsigned int const DW_AT_trampoline = 0x56; static unsigned int const DW_AT_call_column = 0x57; static unsigned int const DW_AT_call_file = 0x58; static unsigned int const DW_AT_call_line = 0x59; // User range. static unsigned int const DW_AT_lo_user = 0x2000; static unsigned int const DW_AT_hi_user = 0x3fff; // SGI/MIPS Extensions. static unsigned int const DW_AT_MIPS_fde = 0x2001; static unsigned int const DW_AT_MIPS_loop_begin = 0x2002; static unsigned int const DW_AT_MIPS_tail_loop_begin = 0x2003; static unsigned int const DW_AT_MIPS_epilog_begin = 0x2004; static unsigned int const DW_AT_MIPS_loop_unroll_factor = 0x2005; static unsigned int const DW_AT_MIPS_software_pipeline_depth = 0x2006; static unsigned int const DW_AT_MIPS_linkage_name = 0x2007; static unsigned int const DW_AT_MIPS_stride = 0x2008; static unsigned int const DW_AT_MIPS_abstract_name = 0x2009; static unsigned int const DW_AT_MIPS_clone_origin = 0x200a; static unsigned int const DW_AT_MIPS_has_inlines = 0x200b; // GNU extensions. static unsigned int const DW_AT_sf_names = 0x2101; static unsigned int const DW_AT_src_info = 0x2102; static unsigned int const DW_AT_mac_info = 0x2103; static unsigned int const DW_AT_src_coords = 0x2104; static unsigned int const DW_AT_body_begin = 0x2105; static unsigned int const DW_AT_body_end = 0x2106; static unsigned int const DW_AT_GNU_vector = 0x2107; // VMS Extensions. static unsigned int const DW_AT_VMS_rtnbeg_pd_address = 0x2201; #if DEBUGDWARF char const* print_DW_AT_name(uLEB128_t attr) { switch(attr) { case 0: return "0"; case DW_AT_sibling: return "DW_AT_sibling"; case DW_AT_location: return "DW_AT_location"; case DW_AT_name: return "DW_AT_name"; case DW_AT_ordering: return "DW_AT_ordering"; case DW_AT_byte_size: return "DW_AT_byte_size"; case DW_AT_bit_offset: return "DW_AT_bit_offset"; case DW_AT_bit_size: return "DW_AT_bit_size"; case DW_AT_stmt_list: return "DW_AT_stmt_list"; case DW_AT_low_pc: return "DW_AT_low_pc"; case DW_AT_high_pc: return "DW_AT_high_pc"; case DW_AT_language: return "DW_AT_language"; case DW_AT_discr: return "DW_AT_discr"; case DW_AT_discr_value: return "DW_AT_discr_value"; case DW_AT_visibility: return "DW_AT_visibility"; case DW_AT_import: return "DW_AT_import"; case DW_AT_string_length: return "DW_AT_string_length"; case DW_AT_common_reference: return "DW_AT_common_reference"; case DW_AT_comp_dir: return "DW_AT_comp_dir"; case DW_AT_const_value: return "DW_AT_const_value"; case DW_AT_containing_type: return "DW_AT_containing_type"; case DW_AT_default_value: return "DW_AT_default_value"; case DW_AT_inline: return "DW_AT_inline"; case DW_AT_is_optional: return "DW_AT_is_optional"; case DW_AT_lower_bound: return "DW_AT_lower_bound"; case DW_AT_producer: return "DW_AT_producer"; case DW_AT_prototyped: return "DW_AT_prototyped"; case DW_AT_return_addr: return "DW_AT_return_addr"; case DW_AT_start_scope: return "DW_AT_start_scope"; case DW_AT_stride_size: return "DW_AT_stride_size"; case DW_AT_upper_bound: return "DW_AT_upper_bound"; case DW_AT_abstract_origin: return "DW_AT_abstract_origin"; case DW_AT_accessibility: return "DW_AT_accessibility"; case DW_AT_address_class: return "DW_AT_address_class"; case DW_AT_artificial: return "DW_AT_artificial"; case DW_AT_base_types: return "DW_AT_base_types"; case DW_AT_calling_convention: return "DW_AT_calling_convention"; case DW_AT_count: return "DW_AT_count"; case DW_AT_data_member_location: return "DW_AT_data_member_location"; case DW_AT_decl_column: return "DW_AT_decl_column"; case DW_AT_decl_file: return "DW_AT_decl_file"; case DW_AT_decl_line: return "DW_AT_decl_line"; case DW_AT_declaration: return "DW_AT_declaration"; case DW_AT_discr_list: return "DW_AT_discr_list"; case DW_AT_encoding: return "DW_AT_encoding"; case DW_AT_external: return "DW_AT_external"; case DW_AT_frame_base: return "DW_AT_frame_base"; case DW_AT_friend: return "DW_AT_friend"; case DW_AT_identifier_case: return "DW_AT_identifier_case"; case DW_AT_macro_info: return "DW_AT_macro_info"; case DW_AT_namelist_item: return "DW_AT_namelist_item"; case DW_AT_priority: return "DW_AT_priority"; case DW_AT_segment: return "DW_AT_segment"; case DW_AT_specification: return "DW_AT_specification"; case DW_AT_static_link: return "DW_AT_static_link"; case DW_AT_type: return "DW_AT_type"; case DW_AT_use_location: return "DW_AT_use_location"; case DW_AT_variable_parameter: return "DW_AT_variable_parameter"; case DW_AT_virtuality: return "DW_AT_virtuality"; case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; // DWARF 3 attributes case DW_AT_allocated: return "DW_AT_allocated"; case DW_AT_associated: return "DW_AT_associated"; case DW_AT_data_location: return "DW_AT_data_location"; case DW_AT_stride: return "DW_AT_stride"; case DW_AT_entry_pc: return "DW_AT_entry_pc"; case DW_AT_use_UTF8: return "DW_AT_use_UTF8"; case DW_AT_extension: return "DW_AT_extension"; case DW_AT_ranges: return "DW_AT_ranges"; case DW_AT_trampoline: return "DW_AT_trampoline"; case DW_AT_call_column: return "DW_AT_call_column"; case DW_AT_call_file: return "DW_AT_call_file"; case DW_AT_call_line: return "DW_AT_call_line"; } LIBCWD_ASSERT(attr >= DW_AT_lo_user && attr <= DW_AT_hi_user); switch(attr) { case DW_AT_lo_user: return "DW_AT_lo_user"; case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor"; case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth"; case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride"; case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name"; case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin"; case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; } switch(attr) { case DW_AT_sf_names: return "DW_AT_sf_names"; case DW_AT_src_info: return "DW_AT_src_info"; case DW_AT_mac_info: return "DW_AT_mac_info"; case DW_AT_src_coords: return "DW_AT_src_coords"; case DW_AT_body_begin: return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; } switch(attr) { case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address"; } static char unknown_at[32]; sprintf(unknown_at, "UNKNOWN DW_AT 0x%lx", attr.value()); return unknown_at; } #endif static unsigned int const DW_FORM_addr = 0x01; // address static unsigned int const DW_FORM_block2 = 0x03; // block static unsigned int const DW_FORM_block4 = 0x04; // block static unsigned int const DW_FORM_data2 = 0x05; // constant static unsigned int const DW_FORM_data4 = 0x06; // constant static unsigned int const DW_FORM_data8 = 0x07; // constant static unsigned int const DW_FORM_string = 0x08; // string static unsigned int const DW_FORM_block = 0x09; // block static unsigned int const DW_FORM_block1 = 0x0a; // block static unsigned int const DW_FORM_data1 = 0x0b; // constant static unsigned int const DW_FORM_flag = 0x0c; // flag static unsigned int const DW_FORM_sdata = 0x0d; // constant static unsigned int const DW_FORM_strp = 0x0e; // string static unsigned int const DW_FORM_udata = 0x0f; // constant static unsigned int const DW_FORM_ref_addr = 0x10; // reference static unsigned int const DW_FORM_ref1 = 0x11; // reference static unsigned int const DW_FORM_ref2 = 0x12; // reference static unsigned int const DW_FORM_ref4 = 0x13; // reference static unsigned int const DW_FORM_ref8 = 0x14; // reference static unsigned int const DW_FORM_ref_udata = 0x15; // reference static unsigned int const DW_FORM_indirect = 0x16; // (see section 7.5.3) #if DEBUGDWARF char const* print_DW_FORM_name(uLEB128_t form) { switch(form) { case DW_FORM_addr: return "DW_FORM_addr"; case DW_FORM_block2: return "DW_FORM_block2"; case DW_FORM_block4: return "DW_FORM_block4"; case DW_FORM_data2: return "DW_FORM_data2"; case DW_FORM_data4: return "DW_FORM_data4"; case DW_FORM_data8: return "DW_FORM_data8"; case DW_FORM_string: return "DW_FORM_string"; case DW_FORM_block: return "DW_FORM_block"; case DW_FORM_block1: return "DW_FORM_block1"; case DW_FORM_data1: return "DW_FORM_data1"; case DW_FORM_flag: return "DW_FORM_flag"; case DW_FORM_sdata: return "DW_FORM_sdata"; case DW_FORM_strp: return "DW_FORM_strp"; case DW_FORM_udata: return "DW_FORM_udata"; case DW_FORM_ref_addr: return "DW_FORM_ref_addr"; case DW_FORM_ref1: return "DW_FORM_ref1"; case DW_FORM_ref2: return "DW_FORM_ref2"; case DW_FORM_ref4: return "DW_FORM_ref4"; case DW_FORM_ref8: return "DW_FORM_ref8"; case DW_FORM_ref_udata: return "DW_FORM_ref_udata"; case DW_FORM_indirect: return "DW_FORM_indirect"; case 0: return "0"; } return "UNKNOWN DW_FORM"; } #endif // Standard opcodes. static unsigned char const DW_LNS_copy = 1; static unsigned char const DW_LNS_advance_pc = 2; static unsigned char const DW_LNS_advance_line = 3; static unsigned char const DW_LNS_set_file = 4; static unsigned char const DW_LNS_set_column = 5; static unsigned char const DW_LNS_negate_stmt = 6; static unsigned char const DW_LNS_set_basic_block = 7; static unsigned char const DW_LNS_const_add_pc = 8; static unsigned char const DW_LNS_fixed_advance_pc = 9; // DWARF 3 static unsigned char const DW_LNS_set_prologue_end = 10; static unsigned char const DW_LNS_set_epilogue_begin = 11; static unsigned char const DW_LNS_set_isa = 12; // Extended opcodes. static unsigned int const DW_LNE_end_sequence = 1; static unsigned int const DW_LNE_set_address = 2; static unsigned int const DW_LNE_define_file = 3; static unsigned char address_size; // Should be sizeof(void*) - at least it is constant, // so it's thread safe to be static. //-------------------------------------------------------------------------------------------------------------------------- // The types (defined in "2.2 Attribute Types" of the draft). // address : Refers to some location in the address space of the described program. typedef Elfxx_Addr address_t; // block : An arbitrary number of uninterpreted bytes of data. struct block_t { unsigned char const* begin; size_t number_of_bytes; }; // constant : One, two, four or eight bytes of uninterpreted data, or data encoded // in the variable length format known as LEB128 (see section 7.6). // We don't handle 8 byte sizes if uLEB128_t doesn't either. typedef uLEB128_t constant_t; // flag : A small constant that indicates the presence or absence of an attribute. typedef bool flag_t; // reference : Refers to some member of the set of debugging information entries that // describe the program. There are two types of reference. The first is // an offset relative to the beginning of the compilation unit in which the // reference occurs and must refer to an entry within that same compilation // unit. The second type of reference is the address of any debugging // information entry within the same executable or shared object; it may // refer to an entry in a different compilation unit from the unit containing // the reference. typedef unsigned char const* reference_t; // string : A null-terminated sequence of zero or more (non-null) bytes. Data in this // form are generally printable strings. Strings may be represented directly // in the debugging information entry or as an offset in a separate string table. typedef char const* string_t; // lineptr : Refers to a location in the DWARF section that holds line number information. typedef unsigned char const* lineptr_t; //------------------------------------------------ template static inline T reinterpret_cast_align(unsigned char const* in) { union { T result; unsigned char input[sizeof(T)]; } aligner; for (size_t i = 0; i < sizeof(T); ++i) aligner.input[i] = in[i]; return aligner.result; } template static inline void dwarf_read(unsigned char const*& in, T& x) { x = reinterpret_cast_align(in); in += sizeof(T); } template<> void dwarf_read(unsigned char const*& in, uLEB128_t& x) { int shift = 7; uLEB128_t byte = *in; x = byte; while(byte >= 0x80) { ++in; byte = (*in) ^ 1; // We can't use this assertion because gcc writes constants as // signed integers to debug info (because of a bug in gdb version 4) // and the sign extension can cause more than 32 bits to be set. //LIBCWD_ASSERT( byte < (1UL << (number_of_bits_in_uLEB128_t - shift))); x = x.value() ^ (byte.value() << shift); shift += 7; } ++in; } template<> void dwarf_read(unsigned char const*& in, LEB128_t& x) { int shift = 7; LEB128_t byte = *in; x = byte; while(byte >= 0x80) { byte = (*++in) ^ 1; LIBCWD_ASSERT( byte < (1L << (number_of_bits_in_LEB128_t - shift)) ); x = x.value() ^ (byte.value() << shift); shift += 7; } if (shift < number_of_bits_in_LEB128_t && (byte & 0x40)) x = x.value() | (- (1L << shift)); ++in; } inline static void eat_string(unsigned char const*& debug_info_ptr) { #ifdef __i386__ // The optimization of gcc is horrible. Lets do it ourselfs. int __d0; asm("cld; repnz; scasb" : "=c" (__d0), "=D" (debug_info_ptr) : "0" (-1), "1" (debug_info_ptr), "a" (0)); #else // This is the same as 'while(*debug_info_ptr++);', but that results in horribly // inefficient code (tested with g++ 3.4). unsigned char const* tmp = debug_info_ptr; while(*tmp) ++tmp; debug_info_ptr = tmp + 1; #endif } //------------------------------------------------ // Conversion routines. // The following routines read a FORM of the expected type // and return the value as one of the types given above. inline address_t read_address(unsigned char const*& debug_info_ptr, uLEB128_t const DEBUGDWARF_OPT(form)) { #if DEBUGDWARF LIBCWD_ASSERT(form == DW_FORM_addr); #endif address_t result; dwarf_read(debug_info_ptr, result); #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::finish, result); #endif return result; } block_t read_block(unsigned char const*& debug_info_ptr, uLEB128_t const form) { #if DEBUGDWARF LIBCWD_ASSERT(form == DW_FORM_block1 || form == DW_FORM_block2 || form == DW_FORM_block4 || form == DW_FORM_block); #endif block_t result; result.begin = debug_info_ptr; switch(form) { case DW_FORM_block1: { uint8_t number_of_bytes; dwarf_read(debug_info_ptr, number_of_bytes); result.number_of_bytes = number_of_bytes; break; } case DW_FORM_block2: { uint16_t number_of_bytes; dwarf_read(debug_info_ptr, number_of_bytes); result.number_of_bytes = number_of_bytes; break; } case DW_FORM_block4: { uint32_t number_of_bytes; dwarf_read(debug_info_ptr, number_of_bytes); result.number_of_bytes = number_of_bytes; break; } case DW_FORM_block: { uLEB128_t number_of_bytes; dwarf_read(debug_info_ptr, number_of_bytes); result.number_of_bytes = number_of_bytes; break; } } debug_info_ptr += result.number_of_bytes; #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::finish, "FIXME"); #endif return result; } inline constant_t read_constant(unsigned char const*& debug_info_ptr, uLEB128_t const form) { #if DEBUGDWARF LIBCWD_ASSERT(form == DW_FORM_data1 || form == DW_FORM_data2 || form == DW_FORM_data4 || form == DW_FORM_udata); #endif constant_t result; switch(form) { case DW_FORM_data1: { uint8_t data; dwarf_read(debug_info_ptr, data); result = data; break; } case DW_FORM_data2: { uint16_t data; dwarf_read(debug_info_ptr, data); result = data; break; } case DW_FORM_data4: { uint32_t data; dwarf_read(debug_info_ptr, data); result = data; break; } case DW_FORM_udata: { uLEB128_t data; dwarf_read(debug_info_ptr, data); result = data; break; } // case DW_FORM_sdata: // case DW_FORM_data8: default: // Using default in order to avoid a warning 'result might be used uninitialized'. DoutFatal(dc::fatal, "read_constant() cannot handle this FORM"); } #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::finish, result); #endif return result; } inline flag_t read_flag(unsigned char const*& debug_info_ptr, uLEB128_t const DEBUGDWARF_OPT(form)) { #if DEBUGDWARF LIBCWD_ASSERT(form == DW_FORM_flag); LIBCWD_TSD_DECLARATION; // Needed for the DoutDwarf below. #endif uint8_t result; dwarf_read(debug_info_ptr, result); DoutDwarf(dc::finish, '(' << print_DW_FORM_name(form) << ") \"" << result << '"'); return result; } inline reference_t read_reference(unsigned char const*& debug_info_ptr, uLEB128_t const form, unsigned char const* debug_info_root, unsigned char const* debug_info_start) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; LIBCWD_ASSERT(form == DW_FORM_ref1 || form == DW_FORM_ref2 || form == DW_FORM_ref4 || form == DW_FORM_ref_udata || form == DW_FORM_ref_addr); size_t compilation_unit_offset = debug_info_root - debug_info_start; #endif switch(form) { case DW_FORM_ref1: { uint8_t offset; dwarf_read(debug_info_ptr, offset); DoutDwarf(dc::finish, '<' << std::hex << compilation_unit_offset + offset << '>'); return debug_info_root + offset; } case DW_FORM_ref2: { uint16_t offset; dwarf_read(debug_info_ptr, offset); DoutDwarf(dc::finish, '<' << std::hex << compilation_unit_offset + offset << '>'); return debug_info_root + offset; } case DW_FORM_ref4: { uint32_t offset; dwarf_read(debug_info_ptr, offset); DoutDwarf(dc::finish, '<' << std::hex << compilation_unit_offset + offset << '>'); return debug_info_root + offset; } case DW_FORM_ref_udata: { uLEB128_t offset; dwarf_read(debug_info_ptr, offset); DoutDwarf(dc::finish, '<' << std::hex << compilation_unit_offset + offset << '>'); return debug_info_root + offset; } case DW_FORM_ref_addr: { address_t offset; dwarf_read(debug_info_ptr, offset); DoutDwarf(dc::finish, '<' << std::hex << offset << '>'); return debug_info_start + offset; } #if 0 case DW_FORM_ref8: DoutFatal(dc::fatal, "read_reference() cannot handle DW_FORM_ref8"); #endif } abort(); } inline string_t read_string(unsigned char const*& debug_info_ptr, uLEB128_t const form, unsigned char const* debug_str) { string_t result; if (form == DW_FORM_string) { result = reinterpret_cast(debug_info_ptr); eat_string(debug_info_ptr); } else #if DEBUGDWARF if (form == DW_FORM_strp) #endif { result = reinterpret_cast(&debug_str[reinterpret_cast_align(debug_info_ptr)]); debug_info_ptr += 4; } #if DEBUGDWARF else DoutFatal(dc::core, "Calling read_string with form != DW_FORM_string && form != DW_FORM_strp"); LIBCWD_TSD_DECLARATION; DoutDwarf(dc::finish, '(' << print_DW_FORM_name(form) << ") \"" << result << '"'); #endif return result; } inline lineptr_t read_lineptr(unsigned char const*& debug_info_ptr DEBUGDWARF_OPT_COMMA(uLEB128_t const form), lineptr_t debug_line) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; LIBCWD_ASSERT(form == DW_FORM_data4); #endif uint32_t line_offset; dwarf_read(debug_info_ptr, line_offset); DoutDwarf(dc::finish, "0x" << std::hex << line_offset); return debug_line + line_offset; } // Inline encodings static unsigned int const DW_INL_not_inlined = 0; static unsigned int const DW_INL_inlined = 1; static unsigned int const DW_INL_declared_not_inlined = 2; static unsigned int const DW_INL_declared_inlined = 3; #if DEBUGDWARF char const* print_DW_INL_name(constant_t inline_encoding) { switch(inline_encoding) { case DW_INL_not_inlined: return "DW_INL_not_inlined"; case DW_INL_inlined: return "DW_INL_inlined"; case DW_INL_declared_not_inlined: return "DW_INL_declared_not_inlined"; case DW_INL_declared_inlined: return "DW_INL_declared_inlined"; } abort(); } #endif //========================================================================================================================================== // Because the functions in this compilation unit can be called from malloc(), we need to use // the alternative allocators. Moreover, `internal' should already be set everywhere and // the object_files_instance mutex should be write locked, so we will use `object_files_string'. // Also, define a replacement type for set here. #if CWDEBUG_ALLOC typedef std::basic_string, _private_::object_files_allocator> object_files_string; typedef std::set, _private_::object_files_allocator::rebind::other> object_files_string_set_ct; #else typedef std::string object_files_string; typedef std::set > object_files_string_set_ct; #endif //========================================================================================================================================== // struct location_ct // // Internal representation for locations. // struct range_st { Elfxx_Addr start; size_t size; }; struct location_st { object_files_string_set_ct::iterator M_stabs_symbol_funcname_iter; // Only valid when M_stabs_symbol is set. object_files_string_set_ct::iterator M_source_iter; Elfxx_Half M_line; bool M_stabs_symbol; location_st(void) { } location_st(location_st const& loc) : M_source_iter(loc.M_source_iter), M_line(loc.M_line), M_stabs_symbol(loc.M_stabs_symbol) { if (M_stabs_symbol) M_stabs_symbol_funcname_iter = loc.M_stabs_symbol_funcname_iter; } #if DEBUGSTABS || DEBUGDWARF friend std::ostream& operator<<(std::ostream& os, location_st const& loc); #endif }; class objfile_ct; class location_ct : private location_st { private: location_st M_prev_location; Elfxx_Addr M_address; range_st M_range; int M_flags; bool M_used; objfile_ct* M_object_file; public: location_ct(objfile_ct* object_file) : M_address(0), M_flags(0), M_object_file(object_file) { M_prev_location.M_line = (Elfxx_Half)-1; M_line = 0; M_stabs_symbol = false; M_range.start = 0; } void invalidate(void) { M_flags = 0; #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::bfd, "--> location invalidated."); #endif } void set_line(Elfxx_Half line) { if (!(M_flags & 1) || M_line != line) M_used = false; M_flags |= 1; M_line = line; #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::bfd, "--> location.M_line = " << M_line); #endif if (is_valid()) { DoutDwarf(dc::bfd, "--> location now valid."); M_store(); } } void set_address(Elfxx_Addr address) { if (M_address != address) M_used = false; M_flags |= 2; M_address = address; if (address == 0x0) // Happens when the reloc info in the .debug_line M_flags &= ~2; // section refers to non existing labels because // the corresponding function instantiation is // disregarded (being part of a .gnu.linkonce // section that was not used). We need to ignore // this debug info. // See the thread of http://gcc.gnu.org/ml/gcc/2003-10/msg00689.html // which is about the fact that GNU as version 2.4.90 // contains a bug that causes the address NOT to be set to 0 :(. #if DEBUGDWARF LIBCWD_TSD_DECLARATION; #endif DoutDwarf(dc::bfd, "--> location.M_address = 0x" << std::hex << address); if (is_valid()) { DoutDwarf(dc::bfd, "--> location now valid."); M_store(); } } void copy(void) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; #endif // Assume valid. if (is_valid()) if (M_address) { DoutDwarf(dc::bfd, "--> location assumed valid."); M_flags = 3; M_store(); } #if DEBUGDWARF else DoutDwarf(dc::bfd, "--> location not assumed valid (address is 0x0)."); #endif } void set_source_iter(object_files_string_set_ct::iterator const& iter) { M_source_iter = iter; M_used = false; } void set_func_iter(object_files_string_set_ct::iterator const& iter) { M_stabs_symbol_funcname_iter = iter; M_stabs_symbol = true; } // load_stabs doesn't use out M_address. bool is_valid_stabs(void) const { return (M_flags == 1); } void increment_line(int increment) { if (increment != 0) M_used = false; #if DEBUGDWARF bool was_not_valid = !(M_flags & 1); LIBCWD_TSD_DECLARATION; #endif M_flags |= 1; M_line += increment; DoutDwarf(dc::bfd, "--> location.M_line = " << M_line); if (is_valid()) { #if DEBUGDWARF if (was_not_valid) DoutDwarf(dc::bfd, "--> location now valid."); #endif M_store(); } } void increment_address(unsigned int increment) { if (increment > 0) M_used = false; if (M_address) // See comment in set_address() above. M_address += increment; #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::bfd, "--> location.M_address = 0x" << std::hex << M_address); #endif if (M_address) M_flags |= 2; } void sequence_end(void) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::bfd, "--> Sequence end."); #endif if (is_valid()) { M_line = 0; // Force storing of range, no range catenation is needed. M_store(); } // Invalidate range tracking, we will start all over. M_range.start = 0; } Elfxx_Half get_line(void) const { LIBCWD_ASSERT( (M_flags & 1) ); return M_line; } object_files_string_set_ct::iterator get_source_iter(void) const { return M_source_iter; } Elfxx_Addr get_address(void) const { return M_address; } void stabs_range(range_st const& range) const; private: bool is_valid(void) const { return (M_flags == 3); } void M_store(void); }; bool operator==(range_st const&, range_st const&) { DoutFatal(dc::core, "Calling operator==(range_st const& range1, range_st const& range2)"); } #if DEBUGSTABS || DEBUGDWARF std::ostream& operator<<(std::ostream& os, range_st const& range) { os << std::hex << range.start << " - " << range.start + range.size; return os; } std::ostream& operator<<(std::ostream& os, location_st const& loc) { os << (*loc.M_source_iter).data() << ':' << std::dec << loc.M_line; if (loc.M_stabs_symbol) os << " : \"" << loc.M_stabs_symbol_funcname_iter->data(); os << "\"."; return os; } std::ostream& operator<<(std::ostream& os, std::pair const& p) { os << std::hex << p.first.start << " - " << p.first.start + p.first.size << "; " << p.second << '.'; return os; } #endif struct compare_range_st { bool operator()(range_st const& range1, range_st const& range2) const { return range1.start >= range2.start + range2.size; } }; //========================================================================================================================================== // class section_ct // // This object represents an ELF section header. // class section_ct : public asection_st { private: Elfxx_Shdr M_section_header; public: section_ct(void) { } void init(char const* section_header_string_table, Elfxx_Shdr const& section_header); Elfxx_Shdr const& section_header(void) const { return M_section_header; } }; struct hash_list_st { char const* name; Elfxx_Addr addr; hash_list_st* next; bool already_added; }; // // class objfile_ct // // This object represents an ELF object file. // using _private_::compilation_units_vector_ct; class objfile_ct : public bfd_st { #if DEBUGSTABS || DEBUGDWARF friend void ::debug_load_object_file(char const* filename, bool shared); #endif #if CWDEBUG_ALLOC typedef std::map >::other> object_files_range_location_map_ct; #else typedef std::map object_files_range_location_map_ct; #endif private: std::ifstream* M_input_stream; Elfxx_Ehdr M_header; char* M_section_header_string_table; section_ct* M_sections; char* M_symbol_string_table; char* M_dyn_symbol_string_table; asymbol_st* M_symbols; int M_number_of_symbols; Elfxx_Word M_symbol_table_type; object_files_string_set_ct M_function_names; object_files_string_set_ct M_source_files; object_files_range_location_map_ct M_ranges; bool volatile M_debug_info_loaded; bool M_brac_relative_to_fun; #if LIBCWD_THREAD_SAFE static pthread_t S_thread_inside_find_nearest_line; #else bool M_inside_find_nearest_line; #endif #if DEBUGSTABS bool M_stabs_debug_info_loaded; #endif #if DEBUGDWARF bool M_dwarf_debug_info_loaded; #endif Elfxx_Word M_stabs_section_index; Elfxx_Word M_stabstr_section_index; Elfxx_Word M_dwarf_debug_info_section_index; Elfxx_Word M_dwarf_debug_abbrev_section_index; Elfxx_Word M_dwarf_debug_line_section_index; Elfxx_Word M_dwarf_debug_str_section_index; static uint32_t const hash_table_size = 2049; // Lets use a prime number. hash_list_st** M_hash_list; hash_list_st* M_hash_list_pool; compilation_units_vector_ct M_compilation_units; // Canonical list of compilation units of this DSO. public: objfile_ct(void); void initialize(char const* file_name); ~objfile_ct(); char const* get_section_header_string_table(void) const { return M_section_header_string_table; } section_ct const& get_section(int index) const { LIBCWD_ASSERT( index < M_header.e_shnum ); return M_sections[index]; } protected: virtual bool check_format(void) const; virtual long get_symtab_upper_bound(void); virtual long canonicalize_symtab(asymbol_st**); virtual void find_nearest_line(asymbol_st const*, Elfxx_Addr, char const**, char const**, unsigned int* LIBCWD_COMMA_TSD_PARAM); virtual void close(void); private: void delete_hash_list(void); char* allocate_and_read_section(int i); friend class location_ct; // location_ct::M_store and location_ct::stabs_range need access to `register_range'. void register_range(location_st const& location, range_st const& range); void load_stabs(void); void load_dwarf(void); uint32_t elf_hash(unsigned char const* name, unsigned char delim) const; void eat_form(unsigned char const*& debug_info_ptr, uLEB128_t const& form DEBUGDWARF_OPT_COMMA(unsigned char const* debug_str) DEBUGDWARF_OPT_COMMA(uint32_t debug_info_offset)); }; #if LIBCWD_THREAD_SAFE pthread_t objfile_ct::S_thread_inside_find_nearest_line; #endif //------------------------------------------------------------------------------------------------------------------------------------------- void location_ct::M_store(void) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; #endif if (M_used) { DoutDwarf(dc::bfd, "Skipping M_store: M_used is set."); return; } if (M_line == M_prev_location.M_line && M_prev_location.M_source_iter == M_source_iter) { DoutDwarf(dc::bfd, "Skipping M_store: location didn't change."); return; } #if DEBUGDWARF if (M_range.start > M_address) core_dump(); #endif if (M_range.start == M_address) DoutDwarf(dc::bfd, "Skipping M_store: address range is zero."); else if (M_range.start) { DoutDwarf(dc::bfd, "M_store(): Registering new range."); M_range.size = M_address - M_range.start; M_object_file->register_range(M_prev_location, M_range); } #if DEBUGDWARF else DoutDwarf(dc::bfd, "M_store(): M_range.start was 0."); #endif M_range.start = M_address; M_prev_location.M_stabs_symbol = M_stabs_symbol; if (M_stabs_symbol) M_prev_location.M_stabs_symbol_funcname_iter = M_stabs_symbol_funcname_iter; M_prev_location.M_source_iter = M_source_iter; M_prev_location.M_line = M_line; M_used = true; } inline void location_ct::stabs_range(range_st const& range) const { M_object_file->register_range(*this, range); } //------------------------------------------------------------------------------------------------------------------------------------------- // Implementation static asection_st const abs_section_c = { 0, "*ABS*", 0 }; asection_st const* const absolute_section_c = &abs_section_c; static bool check_elf_format(Elfxx_Ehdr const& header) { if (header.e_ident[EI_MAG0] != ELFMAG0 || header.e_ident[EI_MAG1] != ELFMAG1 || header.e_ident[EI_MAG2] != ELFMAG2 || header.e_ident[EI_MAG3] != ELFMAG3) Dout(dc::bfd, "Object file must be ELF."); #if defined(__x86_64__) || defined(__sparc64) || defined(__ia64__) else if (header.e_ident[EI_CLASS] != ELFCLASS64) Dout(dc::bfd, "Sorry, object file must be ELF64."); #else else if (header.e_ident[EI_CLASS] != ELFCLASS32) Dout(dc::bfd, "Sorry, object file must be ELF32."); #endif else if (header.e_ident[EI_DATA] != #ifdef __BYTE_ORDER #if __BYTE_ORDER == __LITTLE_ENDIAN ELFDATA2LSB #elif __BYTE_ORDER == __BIG_ENDIAN ELFDATA2MSB #else ELFDATANONE #endif #else // !__BYTE_ORDER #ifdef WORDS_BIGENDIAN ELFDATA2MSB #else ELFDATA2LSB #endif #endif // !__BYTE_ORDER ) Dout(dc::bfd, "Object file has non-native data encoding."); else if (header.e_ident[EI_VERSION] != EV_CURRENT) Dout(dc::warning, "Object file has different version than what libcwd understands."); else return false; return true; } void section_ct::init(char const* section_header_string_table, Elfxx_Shdr const& section_header) { std::memcpy(&M_section_header, §ion_header, sizeof(M_section_header)); static_cast(this)->M_size = M_section_header.sh_size; // Used to guess the size of the last symbol in a section. // Duplicated values: vma = M_section_header.sh_addr; name = §ion_header_string_table[M_section_header.sh_name]; } void objfile_ct::close(void) { LIBCWD_TSD_DECLARATION; #if CWDEBUG_DEBUGM LIBCWD_ASSERT( __libcwd_tsd.internal == 1 ); #endif _private_::set_alloc_checking_on(LIBCWD_TSD); Debug( libcw_do.off() ); delete M_input_stream; Debug( libcw_do.on() ); LIBCWD_DEFER_CLEANUP_PUSH(&_private_::rwlock_tct::cleanup, NULL); // The delete calls close(). BFD_ACQUIRE_WRITE_LOCK; _private_::set_alloc_checking_off(LIBCWD_TSD); delete this; _private_::set_alloc_checking_on(LIBCWD_TSD); BFD_RELEASE_WRITE_LOCK; LIBCWD_CLEANUP_POP_RESTORE(false); _private_::set_alloc_checking_off(LIBCWD_TSD); } objfile_ct::~objfile_ct() { delete_hash_list(); delete [] M_section_header_string_table; delete [] M_sections; delete [] M_symbol_string_table; delete [] M_dyn_symbol_string_table; delete [] M_symbols; } long objfile_ct::get_symtab_upper_bound(void) { return M_number_of_symbols * sizeof(asymbol_st*); } bool objfile_ct::check_format(void) const { return check_elf_format(M_header); } uint32_t objfile_ct::elf_hash(unsigned char const* name, unsigned char delim) const { uint32_t h = 0; uint32_t g; while (*name != delim) { h = (h << 4) + *name++; if ((g = (h & 0xf0000000))) h ^= g >> 24; h &= ~g; } return (h % hash_table_size); } long objfile_ct::canonicalize_symtab(asymbol_st** symbol_table) { #if DEBUGELFXX LIBCWD_TSD_DECLARATION; #endif M_symbols = new asymbol_st[M_number_of_symbols]; M_hash_list = new hash_list_st* [hash_table_size]; M_hash_list_pool = NULL; std::memset(M_hash_list, 0, hash_table_size * sizeof(hash_list_st*)); asymbol_st* new_symbol = M_symbols; int table_entries = 0; for(int i = 0; i < M_header.e_shnum; ++i) { if ((M_sections[i].section_header().sh_type == M_symbol_table_type) && M_sections[i].section_header().sh_size > 0) { int number_of_symbols = M_sections[i].section_header().sh_size / sizeof(Elfxx_Sym); DoutElfxx(dc::bfd, "Found symbol table " << M_sections[i].name << " with " << number_of_symbols << " symbols."); Elfxx_Sym* symbols = (Elfxx_Sym*)allocate_and_read_section(i); M_hash_list_pool = (hash_list_st*)malloc(sizeof(hash_list_st) * number_of_symbols); hash_list_st* hash_list_pool_next = M_hash_list_pool; for(int s = 0; s < number_of_symbols; ++s) { Elfxx_Sym& symbol(symbols[s]); if (M_sections[i].section_header().sh_type == SHT_SYMTAB) new_symbol->name = &M_symbol_string_table[symbol.st_name]; else new_symbol->name = &M_dyn_symbol_string_table[symbol.st_name]; if (!*new_symbol->name) continue; // Skip Symbols that do not have a name. if (symbol.st_shndx == SHN_ABS) { // Skip all absolute symbols except "_end". if (new_symbol->name[1] != 'e' || new_symbol->name[0] != '_' || new_symbol->name[2] != 'n' || new_symbol->name[3] != 'd' || new_symbol->name[4] != 0) continue; new_symbol->section = absolute_section_c; M_s_end_offset = new_symbol->value = symbol.st_value; } else if (symbol.st_shndx >= SHN_LORESERVE || symbol.st_shndx == SHN_UNDEF) continue; // Skip Special Sections and Undefined Symbols. else if (ELFXX_ST_TYPE(symbol.st_info) >= STT_FILE) continue; // Skip STT_FILE, STT_COMMON and STT_TLS symbols. else { new_symbol->section = &M_sections[symbol.st_shndx]; new_symbol->value = symbol.st_value - new_symbol->section->vma; // Is not an absolute value: make value relative #ifdef __sun__ // On solaris 2.8 _end is not absolute but in .bss. if (new_symbol->name[1] == 'e' && new_symbol->name[0] == '_' && new_symbol->name[2] == 'n' && new_symbol->name[3] == 'd' && new_symbol->name[4] == 0) M_s_end_offset = symbol.st_value; #endif // to start of section. DoutElfxx(dc::bfd, "Symbol \"" << new_symbol->name << "\" in section \"" << new_symbol->section->name << "\" at 0x" << std::hex << (new_symbol->section->vma + new_symbol->value) << "."); } new_symbol->bfd_ptr = this; new_symbol->size = symbol.st_size; new_symbol->flags = 0; switch(ELFXX_ST_BIND(symbol.st_info)) { case STB_LOCAL: new_symbol->flags |= cwbfd::BSF_LOCAL; break; case STB_GLOBAL: new_symbol->flags |= cwbfd::BSF_GLOBAL; break; case STB_WEAK: new_symbol->flags |= cwbfd::BSF_WEAK; break; default: // Ignored break; } switch(ELFXX_ST_TYPE(symbol.st_info)) { case STT_OBJECT: new_symbol->flags |= cwbfd::BSF_OBJECT; break; case STT_FUNC: new_symbol->flags |= cwbfd::BSF_FUNCTION; break; case STT_SECTION: new_symbol->flags |= cwbfd::BSF_SECTION_SYM; break; } // Filter out symbols that could endanger determining the size of a symbol. if ((new_symbol->flags & (cwbfd::BSF_GLOBAL|cwbfd::BSF_FUNCTION|cwbfd::BSF_OBJECT)) == 0) continue; uint32_t hash = elf_hash(reinterpret_cast(new_symbol->name), (unsigned char)0); hash_list_st** p = &M_hash_list[hash]; while(*p) p = &(*p)->next; *p = hash_list_pool_next++; (*p)->next = NULL; (*p)->name = new_symbol->name; (*p)->addr = symbol.st_value; (*p)->already_added = false; symbol_table[table_entries++] = new_symbol++; } // The assignment is needed in case hash_list_pool_next == M_hash_list_pool. M_hash_list_pool = (hash_list_st*)realloc(M_hash_list_pool, (hash_list_pool_next - M_hash_list_pool) * sizeof(hash_list_st)); delete [] symbols; break; // There *should* only be one symbol table section. } } LIBCWD_ASSERT( M_number_of_symbols >= table_entries ); M_number_of_symbols = table_entries; return M_number_of_symbols; } struct attr_st { union { unsigned long attr; // Really a uLEB128_t, but we can't use that in a union. unsigned char count; }; uLEB128_t form; }; struct abbrev_st { uLEB128_t code; uLEB128_t tag; attr_st* attributes; unsigned short attributes_size; unsigned short attributes_capacity; unsigned int fixed_size; bool starts_with_string; bool has_children; abbrev_st(abbrev_st const& abbrev); abbrev_st(void) : attributes(NULL), attributes_size(0), attributes_capacity(0) { } ~abbrev_st() { if (attributes && --attributes[attributes_capacity].count == 0) free(attributes); } }; abbrev_st::abbrev_st(abbrev_st const& abbrev) { if (&abbrev != this) { std::memcpy(this, &abbrev, sizeof(abbrev_st)); if (attributes) ++attributes[attributes_capacity].count; } } struct file_name_st { char const* name; uLEB128_t directory_index; uLEB128_t time_of_last_modification; uLEB128_t length_in_bytes_of_the_file; }; static object_files_string catenate_path(object_files_string const& dir, char const* subpath) { object_files_string res; int count = 0; while (subpath[0] == '.' && subpath[1] == '.' && subpath[2] == '/') { ++count; subpath += 3; } if (count > 0) { size_t pos = dir.size() - 1; for(; count > 0; --count) pos = dir.find_last_of('/', pos - 1); res.assign(dir, 0, pos + 1); } else res.assign(dir); res.append(subpath); return res; } void objfile_ct::delete_hash_list(void) { if (M_hash_list) { if (M_hash_list_pool) { free(M_hash_list_pool); M_hash_list_pool = NULL; } delete [] M_hash_list; M_hash_list = NULL; } } void objfile_ct::eat_form(unsigned char const*& debug_info_ptr, uLEB128_t const& form DEBUGDWARF_OPT_COMMA(unsigned char const* debug_str) DEBUGDWARF_OPT_COMMA(uint32_t debug_info_offset)) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; DoutDwarf(dc::continued, '(' << print_DW_FORM_name(form) << ") "); #endif switch(form) { case DW_FORM_data1: case DW_FORM_ref1: case DW_FORM_flag: DoutDwarf(dc::finish, (int)*reinterpret_cast(debug_info_ptr)); debug_info_ptr += 1; break; case DW_FORM_data2: case DW_FORM_ref2: DoutDwarf(dc::finish, reinterpret_cast_align(debug_info_ptr)); debug_info_ptr += 2; break; case DW_FORM_data4: case DW_FORM_strp: case DW_FORM_ref4: #if DEBUGDWARF if (form == DW_FORM_data4) DoutDwarf(dc::finish, reinterpret_cast_align(debug_info_ptr)); else if (form == DW_FORM_strp) { unsigned int pos = reinterpret_cast_align(debug_info_ptr); DoutDwarf(dc::finish, pos << " (\"" << &debug_str[pos] << "\")"); } else DoutDwarf(dc::finish, '<' << std::hex << reinterpret_cast_align(debug_info_ptr) + debug_info_offset << '>'); #endif debug_info_ptr += 4; break; case DW_FORM_data8: case DW_FORM_ref8: #if DEBUGDWARF && (defined(__x86_64__) || defined(__sparc64) || defined(__ia64__)) if (form == DW_FORM_data8) DoutDwarf(dc::finish, reinterpret_cast_align(debug_info_ptr)); else DoutDwarf(dc::finish, '<' << std::hex << reinterpret_cast_align(debug_info_ptr) + debug_info_offset << '>'); #endif debug_info_ptr += 8; break; case DW_FORM_indirect: { uLEB128_t tmpform = form; DoutDwarf(dc::continued, "-> "); dwarf_read(debug_info_ptr, tmpform); eat_form(debug_info_ptr, tmpform DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_offset)); break; } case DW_FORM_string: { DoutDwarf(dc::finish, "\"" << reinterpret_cast(debug_info_ptr) << '"'); eat_string(debug_info_ptr); break; } case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: { uLEB128_t data; dwarf_read(debug_info_ptr, data); DoutDwarf(dc::finish, data); break; } case DW_FORM_ref_addr: case DW_FORM_addr: DoutDwarf(dc::finish, reinterpret_cast_align(debug_info_ptr)); debug_info_ptr += address_size; break; case DW_FORM_block1: { uint8_t length; dwarf_read(debug_info_ptr, length); DoutDwarf(dc::finish, "[" << (unsigned int)length << " bytes]"); debug_info_ptr += length; break; } case DW_FORM_block2: { uint16_t length; dwarf_read(debug_info_ptr, length); DoutDwarf(dc::finish, "[" << length << " bytes]"); debug_info_ptr += length; break; } case DW_FORM_block4: { uint32_t length; dwarf_read(debug_info_ptr, length); DoutDwarf(dc::finish, "[" << length << " bytes]"); debug_info_ptr += length; break; } case DW_FORM_block: { uLEB128_t length; dwarf_read(debug_info_ptr, length); DoutDwarf(dc::finish, "[" << length << " bytes]"); debug_info_ptr += length; break; } } } void objfile_ct::load_dwarf(void) { #if DEBUGDWARF LIBCWD_TSD_DECLARATION; uint32_t total_length; #endif #if CWDEBUG_ALLOC #if !DEBUGDWARF LIBCWD_TSD_DECLARATION; #endif int saved_internal = __libcwd_tsd.internal; __libcwd_tsd.internal = false; #endif Dout(dc::bfd|continued_cf|flush_cf, "Loading debug info from " << this->filename_str << "... "); #if CWDEBUG_ALLOC __libcwd_tsd.internal = saved_internal; #endif #if DEBUGDWARF // Not loaded already. LIBCWD_ASSERT( !M_dwarf_debug_info_loaded ); M_dwarf_debug_info_loaded = true; // Don't have fixed entry sizes. LIBCWD_ASSERT( M_sections[M_dwarf_debug_line_section_index].section_header().sh_entsize == 0 ); LIBCWD_ASSERT( M_sections[M_dwarf_debug_info_section_index].section_header().sh_entsize == 0 ); LIBCWD_ASSERT( M_sections[M_dwarf_debug_abbrev_section_index].section_header().sh_entsize == 0 ); // gcc 3.1 sets sh_entsize to 1, previous versions set it to 0. LIBCWD_ASSERT( M_dwarf_debug_str_section_index == 0 || M_sections[M_dwarf_debug_str_section_index].section_header().sh_entsize <= 1 ); // Initialization of debug variable. total_length = 0; #endif // Start of .debug_abbrev section. unsigned char* debug_abbrev = (unsigned char*)allocate_and_read_section(M_dwarf_debug_abbrev_section_index); // Start of .debug_info section. unsigned char* debug_info = (unsigned char*)allocate_and_read_section(M_dwarf_debug_info_section_index); unsigned char* const debug_info_start = debug_info; unsigned char* debug_info_end = debug_info + M_sections[M_dwarf_debug_info_section_index].section_header().sh_size; // Start of .debug_line section. lineptr_t debug_line = reinterpret_cast(allocate_and_read_section(M_dwarf_debug_line_section_index)); lineptr_t debug_line_end = debug_line + M_sections[M_dwarf_debug_line_section_index].section_header().sh_size; lineptr_t debug_line_ptr; // Start of .debug_str section. // Needed for DW_FORM_strp. unsigned char* debug_str = (unsigned char*)allocate_and_read_section(M_dwarf_debug_str_section_index); // Run over all compilation units. for (unsigned char const* debug_info_ptr = debug_info; debug_info_ptr < debug_info_end;) { unsigned char const* const debug_info_root = debug_info_ptr; uint32_t length; dwarf_read(debug_info_ptr, length); #if DEBUGDWARF LIBCWD_TSD_DECLARATION; if (doutdwarfon) { _private_::set_alloc_checking_on(LIBCWD_TSD); // Needed for Dout(). Dout(dc::bfd, "debug_info_ptr = " << (void*)debug_info_ptr << "; debug_info_end = " << (void*)debug_info_end); Dout(dc::bfd, "length = " << length); total_length += length + 4; Dout(dc::bfd, "total length = " << total_length << " (of " << M_sections[M_dwarf_debug_info_section_index].section_header().sh_size << ")."); _private_::set_alloc_checking_off(LIBCWD_TSD); } LIBCWD_ASSERT( total_length <= M_sections[M_dwarf_debug_info_section_index].section_header().sh_size ); #endif uint16_t version; dwarf_read(debug_info_ptr, version); if ( version == 2 ) // DWARF version 2 (and 3) { uint32_t abbrev_offset; dwarf_read(debug_info_ptr, abbrev_offset); unsigned char const* debug_abbrev_ptr = debug_abbrev + abbrev_offset; DoutDwarf(dc::bfd, "abbrev_offset = " << std::hex << abbrev_offset); dwarf_read(debug_info_ptr, address_size); LIBCWD_ASSERT( address_size == sizeof(void*) ); unsigned int expected_code = 1; #if CWDEBUG_ALLOC std::vector::other> abbrev_entries(256); #else std::vector abbrev_entries(256); #endif while(true) { if (expected_code >= abbrev_entries.size()) abbrev_entries.resize(abbrev_entries.size() + 256); abbrev_st& abbrev(abbrev_entries[expected_code]); dwarf_read(debug_abbrev_ptr, abbrev.code); if (abbrev.code == 0) break; dwarf_read(debug_abbrev_ptr, abbrev.tag); unsigned char children; dwarf_read(debug_abbrev_ptr, children); abbrev.has_children = (children == DW_CHILDREN_yes); bool has_fixed_size = !abbrev.has_children; unsigned int fixed_size = 0; bool first_time = true; abbrev.starts_with_string = false; DoutDwarf(dc::bfd, "Abbr. " << abbrev.code << " \t" << print_DW_TAG_name(abbrev.tag) << " \t[" << (children ? "has" : "no") << " children]"); LIBCWD_ASSERT( abbrev.code == expected_code ); ++expected_code; while(true) { if (abbrev.attributes_size == abbrev.attributes_capacity) { abbrev.attributes_capacity += 32; abbrev.attributes = (attr_st*)realloc(abbrev.attributes, (abbrev.attributes_capacity + 1) * sizeof(attr_st)); abbrev.attributes[abbrev.attributes_capacity].count = 1; } uLEB128_t& attr(*reinterpret_cast(&abbrev.attributes[abbrev.attributes_size].attr)); uLEB128_t& form(abbrev.attributes[abbrev.attributes_size].form); dwarf_read(debug_abbrev_ptr, attr); dwarf_read(debug_abbrev_ptr, form); DoutDwarf(dc::bfd, " Attribute/Form: " << print_DW_AT_name(attr) << ", " << print_DW_FORM_name(form)); if (attr == 0 && form == 0) break; if (has_fixed_size) { switch(form) { case DW_FORM_data1: case DW_FORM_ref1: case DW_FORM_flag: fixed_size += 1; break; case DW_FORM_data2: case DW_FORM_ref2: fixed_size += 2; break; case DW_FORM_data4: case DW_FORM_ref4: case DW_FORM_strp: fixed_size += 4; break; case DW_FORM_data8: case DW_FORM_ref8: fixed_size += 8; break; case DW_FORM_ref_addr: case DW_FORM_addr: fixed_size += address_size; break; default: if (first_time) { abbrev.starts_with_string = (form == DW_FORM_string); if (abbrev.starts_with_string) break; } has_fixed_size = false; break; } } first_time = false; ++abbrev.attributes_size; } abbrev.fixed_size = has_fixed_size ? fixed_size : 0; abbrev.attributes_capacity = abbrev.attributes_size; abbrev.attributes = (attr_st*)realloc(abbrev.attributes, (abbrev.attributes_capacity + 1) * sizeof(attr_st)); abbrev.attributes[abbrev.attributes_capacity].count = 1; } using _private_::compilation_unit_ct; compilation_unit_ct* current_compilation_unit = 0; int abstract_instances = 0; int abstract_instances_referenced = 0; int level = 0; unsigned char const* debug_info_ptr_end = debug_info_ptr + length - sizeof(version) - sizeof(abbrev_offset) - sizeof(address_size); while(debug_info_ptr < debug_info_ptr_end) { #if DEBUGDWARF unsigned int reference = debug_info_ptr - debug_info_start; #endif uLEB128_t code; dwarf_read(debug_info_ptr, code); if (code == 0) { DoutDwarf(dc::bfd, '<' << std::hex << reference << "> code: 0"); if (DEBUGDWARF) Debug( libcw_do.marker().assign(libcw_do.marker().c_str(), libcw_do.marker().size() - 1) ); if (--level <= 0) { if (DEBUGDWARF) LIBCWD_ASSERT( level == 0 ); break; } continue; } LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev(abbrev_entries[code]); DoutDwarf(dc::bfd, '<' << std::hex << reference << "> Abbrev Number: " << std::dec << code << " (" << print_DW_TAG_name(abbrev.tag) << ')'); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); attr_st* attr = abbrev.attributes; if (abbrev.tag == DW_TAG_compile_unit) { object_files_string default_dir; object_files_string cur_dir; object_files_string default_source; address_t low_pc = 0; address_t high_pc = 0; bool found_stmt_list = false; M_compilation_units.push_back(compilation_unit_ct()); current_compilation_unit = &M_compilation_units.back(); for (int i = 0; i < abbrev.attributes_size; ++i, ++attr) { uLEB128_t form = attr->form; DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr->attr) << ' '); if (attr->attr == DW_AT_stmt_list) { debug_line_ptr = read_lineptr(debug_info_ptr DEBUGDWARF_OPT_COMMA(form), debug_line); found_stmt_list = true; continue; } else if (attr->attr == DW_AT_name || attr->attr == DW_AT_comp_dir) { string_t str = read_string(debug_info_ptr, attr->form, debug_str); if (attr->attr == DW_AT_comp_dir) { default_dir.assign(str); default_dir += '/'; current_compilation_unit->set_compilation_directory(default_dir); } else { if (str[0] == '.' && str[1] == '/') str += 2; default_source.assign(str); current_compilation_unit->set_source_file(default_source); default_source += '\0'; } continue; } else if (attr->attr == DW_AT_high_pc || attr->attr == DW_AT_low_pc) { address_t address = read_address(debug_info_ptr, form); if (attr->attr == DW_AT_high_pc) { high_pc = address; current_compilation_unit->set_highpc(high_pc); } else { low_pc = address; current_compilation_unit->set_lowpc(low_pc); } continue; } eat_form(debug_info_ptr, form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); } if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); if (abbrev.has_children) { ++level; if (DEBUGDWARF) Debug( libcw_do.marker().append("|", 1) ); } if (found_stmt_list && debug_line_ptr < debug_line_end && !(low_pc && high_pc && low_pc == high_pc)) { // ===========================================================================================================================17" // State machine. // See paragraph 6.2 of "DWARF Debugging Information Format" document. uLEB128_t file; // An unsigned integer indicating the identity of the source file corresponding to a machine // instruction. uLEB128_t column; // An unsigned integer indicating a column number within a source line. Columns are numbered // beginning at 1. The value 0 is reserved to indicate that a statement begins at the left // edge of the line. bool is_stmt; // A boolean indicating that the current instruction is the beginning of a statement. bool basic_block __attribute__((unused)); // A boolean indicating that the current instruction is the beginning of a basic block. bool end_sequence; // A boolean indicating that the current address is that of the first byte after the end of // a sequence of target machine instructions. uint32_t total_length; // The size in bytes of the statement information for this compilation unit (not including // the total_length field itself). uint16_t version; // Version identifier for the statement information format. uint32_t prologue_length; // The number of bytes following the prologue_length field to the beginning of the first // byte of the statement program itself. unsigned char minimum_instruction_length; // The size in bytes of the smallest target machine instruction. Statement // program opcodes that alter the address register first multiply their operands by this value. unsigned char default_is_stmt;// The initial value of the is_stmt register. signed char line_base; // This parameter affects the meaning of the special opcodes. unsigned char line_range; // This parameter affects the meaning of the special opcodes. unsigned char opcode_base; // The number assigned to the first special opcode. unsigned char const* standard_opcode_lengths; #if CWDEBUG_ALLOC std::vector::other> include_directories; std::vector::other> file_names; #else std::vector include_directories; std::vector file_names; #endif dwarf_read(debug_line_ptr, total_length); unsigned char const* debug_line_ptr_end = debug_line_ptr + total_length; dwarf_read(debug_line_ptr, version); dwarf_read(debug_line_ptr, prologue_length); unsigned char const* statement_program_start = debug_line_ptr + prologue_length; dwarf_read(debug_line_ptr, minimum_instruction_length); dwarf_read(debug_line_ptr, default_is_stmt); dwarf_read(debug_line_ptr, line_base); dwarf_read(debug_line_ptr, line_range); dwarf_read(debug_line_ptr, opcode_base); standard_opcode_lengths = debug_line_ptr; debug_line_ptr += (opcode_base - 1); while(*debug_line_ptr) { DoutDwarf(dc::bfd, "Include directory: " << reinterpret_cast(debug_line_ptr)); include_directories.push_back(reinterpret_cast(debug_line_ptr)); while(*debug_line_ptr++) ; } ++debug_line_ptr; while(true) { if (DEBUGDWARF) LIBCWD_ASSERT( debug_line_ptr < statement_program_start ); file_name_st file_name; file_name.name = reinterpret_cast(debug_line_ptr); if (!*debug_line_ptr++) break; while(*debug_line_ptr++) ; dwarf_read(debug_line_ptr, file_name.directory_index); dwarf_read(debug_line_ptr, file_name.time_of_last_modification); dwarf_read(debug_line_ptr, file_name.length_in_bytes_of_the_file); DoutDwarf(dc::bfd, "File name: " << file_name.name); file_names.push_back(file_name); } LIBCWD_ASSERT( debug_line_ptr == statement_program_start ); object_files_string cur_dir; object_files_string cur_source; location_ct location(this); while( debug_line_ptr < debug_line_ptr_end ) { file = 0; // One less than the `file' mentioned in the documentation. column = 0; is_stmt = default_is_stmt; basic_block = false; end_sequence = false; if (default_source[0] == '/') cur_dir.erase(); else cur_dir = default_dir; cur_source = catenate_path(cur_dir, default_source.data()); if (default_dir[0] == '.' && default_dir[1] == '.' && default_dir[2] == '/') { cur_source.assign(cur_dir, 0, cur_dir.find_last_of('/', cur_dir.size() - 2) + 1); cur_source.append(default_source, 3, object_files_string::npos); } else cur_source = cur_dir + default_source; location.invalidate(); location.set_source_iter(M_source_files.insert(cur_source).first); location.set_line(1); while(!end_sequence) { unsigned char opcode; dwarf_read(debug_line_ptr, opcode); if (opcode < opcode_base) // Standard opcode? { switch(opcode) { case 0: // Extended opcode. { uLEB128_t size; // Size in bytes. dwarf_read(debug_line_ptr, size); LIBCWD_ASSERT( size > 0 ); uLEB128_t extended_opcode; dwarf_read(debug_line_ptr, extended_opcode); LIBCWD_ASSERT( extended_opcode < 0x80 ); // Then it's size is one: --size; switch(extended_opcode) { case DW_LNE_end_sequence: LIBCWD_ASSERT( size == 0 ); end_sequence = true; DoutDwarf(dc::bfd, "DW_LNE_end_sequence: Address: 0x" << std::hex << location.get_address()); location.sequence_end(); break; case DW_LNE_set_address: { Elfxx_Addr address; LIBCWD_ASSERT( size == sizeof(address) ); dwarf_read(debug_line_ptr, address); DoutDwarf(dc::bfd, "DW_LNE_set_address: 0x" << std::hex << address); location.set_address(address); break; } case DW_LNE_define_file: { unsigned char const* end = debug_line_ptr + size; file_name_st file_name; file_name.name = reinterpret_cast(debug_line_ptr); if (file_name.name[0] == '.' && file_name.name[1] == '/') file_name.name += 2; while(*debug_line_ptr++) ; dwarf_read(debug_line_ptr, file_name.directory_index); dwarf_read(debug_line_ptr, file_name.time_of_last_modification); dwarf_read(debug_line_ptr, file_name.length_in_bytes_of_the_file); LIBCWD_ASSERT( debug_line_ptr == end ); DoutDwarf(dc::bfd, "DW_LNE_define_file: " << file_name.name); file_names.push_back(file_name); break; } default: { DoutDwarf(dc::bfd, "Unknown extended opcode: " << std::hex << extended_opcode); debug_line_ptr += size; break; } } break; } case DW_LNS_copy: DoutDwarf(dc::bfd, "DW_LNS_copy"); location.copy(); basic_block = false; break; case DW_LNS_advance_pc: { uLEB128_t address_increment; dwarf_read(debug_line_ptr, address_increment); DoutDwarf(dc::bfd, "DW_LNS_advance_pc: " << std::hex << address_increment); location.increment_address(minimum_instruction_length * address_increment); break; } case DW_LNS_advance_line: { LEB128_t line_increment; dwarf_read(debug_line_ptr, line_increment); DoutDwarf(dc::bfd, "DW_LNS_advance_line: " << line_increment); location.invalidate(); location.increment_line(line_increment); break; } case DW_LNS_set_file: { dwarf_read(debug_line_ptr, file); --file; DoutDwarf(dc::bfd, "DW_LNS_set_file: \"" << file_names[file].name << '"'); location.invalidate(); if (*file_names[file].name == '/') cur_source.assign(file_names[file].name); else { if (file_names[file].directory_index == 0) cur_dir = default_dir; else { if (*include_directories[file_names[file].directory_index - 1] != '/') { cur_dir.assign(current_compilation_unit->get_compilation_directory().data(), current_compilation_unit->get_compilation_directory().length()); cur_dir += include_directories[file_names[file].directory_index - 1]; } else cur_dir.assign(include_directories[file_names[file].directory_index - 1]); cur_dir += '/'; } cur_source = catenate_path(cur_dir, file_names[file].name); } cur_source += '\0'; location.set_source_iter(M_source_files.insert(cur_source).first); break; } case DW_LNS_set_column: dwarf_read(debug_line_ptr, column); DoutDwarf(dc::bfd, "DW_LNS_set_column: " << column); break; case DW_LNS_negate_stmt: is_stmt = !is_stmt; DoutDwarf(dc::bfd, "DW_LNS_negate_stmt: " << (is_stmt ? "true" : "false")); break; case DW_LNS_set_basic_block: basic_block = true; DoutDwarf(dc::bfd, "DW_LNS_set_basic_block"); break; case DW_LNS_const_add_pc: { DoutDwarf(dc::bfd, "DW_LNS_const_add_pc"); unsigned int address_increment = (255 - opcode_base) / line_range; location.increment_address(minimum_instruction_length * address_increment); break; } case DW_LNS_fixed_advance_pc: { DoutDwarf(dc::bfd, "DW_LNS_fixed_advance_pc"); unsigned short int address_increment; dwarf_read(debug_line_ptr, address_increment); location.increment_address(minimum_instruction_length * address_increment); break; } default: { DoutDwarf(dc::bfd, "Unknown standard opcode: " << std::hex << (int)opcode); uLEB128_t argument; for (int n = standard_opcode_lengths[opcode - 1]; n > 0; --n) dwarf_read(debug_line_ptr, argument); break; } } } else { // Special opcode. int line_increment = line_base + ((opcode - opcode_base) % line_range); unsigned int address_increment = (opcode - opcode_base) / line_range; DoutDwarf(dc::bfd, "Special opcode. Address/Line increments: 0x" << std::hex << address_increment << ", " << std::dec << line_increment); location.increment_address(minimum_instruction_length * address_increment); location.increment_line(line_increment); basic_block = false; } } } LIBCWD_ASSERT( debug_line_ptr == debug_line_ptr_end ); // End state machine code. // ===========================================================================================================================17" } else { DoutDwarf(dc::bfd, "Skipping compilation unit." << default_dir << default_source.data()); } continue; } #if 0 else if (abbrev.tag == DW_TAG_subprogram) { bool saw_low_pc = false; bool saw_high_pc = false; bool saw_declaration = false; bool saw_specification_declaration = false; bool saw_specification = false; bool saw_linkage_name = false; bool saw_inline = false; address_t low_pc = 0; address_t high_pc = 0; string_t linkage_name = 0; string_t name = 0; constant_t inline_attr = 0; for (int i = 0; i < abbrev.attributes_size; ++i, ++attr) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr->attr) << ' '); switch(attr->attr) { case DW_AT_inline: LIBCWD_ASSERT(attr->form == DW_FORM_data1); inline_attr = read_constant(debug_info_ptr, attr->form); DoutDwarf(dc::bfd, "DW_AT_inline flag is " << inline_attr); ((uint8_t*)debug_info_ptr)[-1] |= 16; DoutDwarf(dc::bfd, "DW_AT_inline flag set to " << (unsigned int)(((uint8_t*)debug_info_ptr)[-1])); ++abstract_instances; DoutDwarf(dc::bfd, "DW_AT_inline count set to " << abstract_instances); saw_inline = true; break; case DW_AT_low_pc: low_pc =read_address(debug_info_ptr, attr->form); saw_low_pc = true; break; case DW_AT_high_pc: high_pc = read_address(debug_info_ptr, attr->form); saw_high_pc = true; break; case DW_AT_MIPS_linkage_name: saw_linkage_name = true; linkage_name = read_string(debug_info_ptr, attr->form, debug_str); break; case DW_AT_abstract_origin: { LIBCWD_ASSERT( attr->form != DW_FORM_ref_addr); // Must be same compilation unit. reference_t abstract_debug_info_ptr = read_reference(debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); dwarf_read(abstract_debug_info_ptr, code); LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev2(abbrev_entries[code]); LIBCWD_ASSERT(abbrev2.tag == DW_TAG_subprogram); bool saw_inline2 = false; attr_st* attr2 = abbrev2.attributes; for (int i = 0; i < abbrev2.attributes_size; ++i, ++attr2) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr2->attr) << ' '); switch(attr2->attr) { case DW_AT_inline: { LIBCWD_ASSERT(attr2->form == DW_FORM_data1); constant_t inline_attr = read_constant(abstract_debug_info_ptr, attr2->form); DoutDwarf(dc::bfd, "DW_AT_inline flag is " << inline_attr); LIBCWD_ASSERT((inline_attr & 16) == 16); if ((inline_attr & 32) == 0) { ((uint8_t*)abstract_debug_info_ptr)[-1] |= 32; DoutDwarf(dc::bfd, "DW_AT_inline flag set to " << (unsigned int)(((uint8_t*)abstract_debug_info_ptr)[-1])); ++abstract_instances_referenced; DoutDwarf(dc::bfd, "DW_AT_inline reference count set to " << abstract_instances_referenced); } saw_inline2 = true; break; } case DW_AT_specification: { LIBCWD_ASSERT( attr2->form != DW_FORM_ref_addr); // Must be same compilation unit. reference_t declaration_debug_info_ptr = read_reference(abstract_debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); dwarf_read(declaration_debug_info_ptr, code); LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev3(abbrev_entries[code]); LIBCWD_ASSERT(abbrev3.tag == DW_TAG_subprogram); attr_st* attr3 = abbrev3.attributes; for (int i = 0; i < abbrev3.attributes_size; ++i, ++attr3) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr3->attr) << ' '); switch(attr3->attr) { case DW_AT_MIPS_linkage_name: saw_linkage_name = true; linkage_name = read_string(declaration_debug_info_ptr, attr3->form, debug_str); break; case DW_AT_name: name = read_string(declaration_debug_info_ptr, attr3->form, debug_str); break; case DW_AT_inline: case DW_AT_abstract_origin: DoutFatal(dc::core, "Huh? DW_AT_specification contains " << print_DW_AT_name(attr3->attr)); default: eat_form(declaration_debug_info_ptr, attr3->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; } } if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); break; } default: eat_form(abstract_debug_info_ptr, attr2->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; } } LIBCWD_ASSERT( saw_inline2 ); if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); break; } case DW_AT_specification: { LIBCWD_ASSERT( attr->form != DW_FORM_ref_addr); // Must be same compilation unit. saw_specification = true; reference_t declaration_debug_info_ptr = read_reference(debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); dwarf_read(declaration_debug_info_ptr, code); LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev2(abbrev_entries[code]); LIBCWD_ASSERT(abbrev2.tag == DW_TAG_subprogram); attr_st* attr2 = abbrev2.attributes; for (int i = 0; i < abbrev2.attributes_size; ++i, ++attr2) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr2->attr) << ' '); switch(attr2->attr) { case DW_AT_MIPS_linkage_name: saw_linkage_name = true; linkage_name = read_string(declaration_debug_info_ptr, attr2->form, debug_str); break; case DW_AT_name: name = read_string(declaration_debug_info_ptr, attr2->form, debug_str); break; case DW_AT_declaration: saw_specification_declaration = true; // Fall through. default: eat_form(declaration_debug_info_ptr, attr2->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; case DW_AT_inline: case DW_AT_abstract_origin: DoutFatal(dc::core, "Huh? DW_AT_specification contains " << print_DW_AT_name(attr2->attr)); } } if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); break; } case DW_AT_name: name = read_string(debug_info_ptr, attr->form, debug_str); break; case DW_AT_declaration: saw_declaration = true; // Fall through. default: eat_form(debug_info_ptr, attr->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; } } LIBCWD_ASSERT( saw_low_pc == saw_high_pc ); // Dies with DW_AT_inline are abstract. LIBCWD_ASSERT( saw_inline || saw_low_pc != saw_declaration ); LIBCWD_ASSERT( !saw_low_pc || !saw_declaration ); LIBCWD_ASSERT( saw_specification == saw_specification_declaration ); if(!(saw_declaration || saw_inline || saw_linkage_name)) DoutDwarf(dc::bfd, "Missing DW_AT_MIPS_linkage_name for " << name); if (saw_low_pc && saw_linkage_name) { DoutDwarf(dc::bfd, std::hex << "low_pc = " << low_pc << std::hex << "; high_pc = " << high_pc << "; linkage_name = " << linkage_name); // Look up the symbol. bool found = false; using namespace cwbfd; function_symbols_ct const& function_symbols(object_file->get_function_symbols()); for(function_symbols_ct::const_iterator i2(function_symbols.begin()); i2 != function_symbols.end(); ++i2) { static unsigned int const setflags = BSF_FUNCTION; symbol_ct const& symbol(*i2); if ((symbol.get_symbol()->flags & setflags) == setflags) { if (!strcmp(linkage_name, symbol.get_symbol()->name)) { DoutDwarf(dc::bfd, "Found symbol at " << std::hex << (address_t)symbol_start_addr(symbol.get_symbol()) << "; symbol value = " << std::hex << symbol.get_symbol()->value << "; symbol value + section offset = " << std::hex << symbol.get_symbol()->value + symbol.get_symbol()->section->offset << "; low_pc plus symbol size = " << std::hex << low_pc + symbol_size(symbol.get_symbol())); found = true; LIBCWD_ASSERT( low_pc == symbol.get_symbol()->value + symbol.get_symbol()->section->offset ); if (low_pc + symbol_size(symbol.get_symbol()) != high_pc ) { // Alignment can cause the next function to start beyond the end of this function. LIBCWD_ASSERT( low_pc + symbol_size(symbol.get_symbol()) > high_pc ); // The alignment is maximal 16. LIBCWD_ASSERT( low_pc + symbol_size(symbol.get_symbol()) - high_pc < 16 ); // The last instruction is a ret or a jmp. LIBCWD_ASSERT(*((unsigned char*)symbol_start_addr(symbol.get_symbol()) - 1 + high_pc - low_pc) == 0xc3 || *((unsigned char*)symbol_start_addr(symbol.get_symbol()) - 3 + high_pc - low_pc) == 0xc2 || *((unsigned char*)symbol_start_addr(symbol.get_symbol()) - 5 + high_pc - low_pc) == 0xe8 || *((unsigned char*)symbol_start_addr(symbol.get_symbol()) - 5 + high_pc - low_pc) == 0xe9 || *((unsigned char*)symbol_start_addr(symbol.get_symbol()) - 2 + high_pc - low_pc) == 0xeb); // All remaining bytes should be alignment for (unsigned char* p = (unsigned char*)symbol_start_addr(symbol.get_symbol()) + high_pc - low_pc; p < (unsigned char*)symbol_start_addr(symbol.get_symbol()) + symbol_size(symbol.get_symbol()); ++p) { // nop if (*p == 0x90) continue; // lea 0x0(%esi,1),%esi if (*p == 0x8d && p[1] == 0xb4 && p[2] == 0x26 && p[3] == 0x0 && p[4] == 0x0 && p[5] == 0x0 && p[6] == 0x0) { p += 6; continue; } DoutFatal(dc::core, "Unrecognizable alignment"); } } } } } if (!found) { DoutDwarf(dc::bfd, "DSO: " << object_file->get_bfd()->filename); DoutFatal(dc::core, "Could not find DWARF function symbol in ELF symbol table."); } } } else if (abbrev.tag == DW_TAG_inlined_subroutine) { string_t linkage_name = 0; string_t name = 0; bool saw_linkage_name = false; constant_t inline_attr = 0; for (int i = 0; i < abbrev.attributes_size; ++i, ++attr) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr->attr) << ' '); switch(attr->attr) { case DW_AT_inline: LIBCWD_ASSERT(attr->form == DW_FORM_data1); inline_attr = read_constant(debug_info_ptr, attr->form); DoutDwarf(dc::bfd, "DW_AT_inline flag is " << inline_attr); ((uint8_t*)debug_info_ptr)[-1] |= 16; DoutDwarf(dc::bfd, "DW_AT_inline flag set to " << (unsigned int)(((uint8_t*)debug_info_ptr)[-1])); ++abstract_instances; DoutDwarf(dc::bfd, "DW_AT_inline count set to " << abstract_instances); //saw_inline = true; break; case DW_AT_abstract_origin: { LIBCWD_ASSERT( attr->form != DW_FORM_ref_addr); // Must be same compilation unit. reference_t abstract_debug_info_ptr = read_reference(debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); dwarf_read(abstract_debug_info_ptr, code); LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev2(abbrev_entries[code]); LIBCWD_ASSERT(abbrev2.tag == DW_TAG_subprogram); bool saw_inline2 = false; attr_st* attr2 = abbrev2.attributes; for (int i = 0; i < abbrev2.attributes_size; ++i, ++attr2) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr2->attr) << ' '); switch(attr2->attr) { case DW_AT_inline: { LIBCWD_ASSERT(attr2->form == DW_FORM_data1); constant_t inline_attr = read_constant(abstract_debug_info_ptr, attr2->form); DoutDwarf(dc::bfd, "DW_AT_inline flag is " << inline_attr); if ((inline_attr & 32) == 0) { ((uint8_t*)abstract_debug_info_ptr)[-1] |= 32; DoutDwarf(dc::bfd, "DW_AT_inline flag set to " << (unsigned int)(((uint8_t*)abstract_debug_info_ptr)[-1])); ++abstract_instances_referenced; DoutDwarf(dc::bfd, "DW_AT_inline reference count set to " << abstract_instances_referenced); } saw_inline2 = true; break; } case DW_AT_specification: { LIBCWD_ASSERT( attr2->form != DW_FORM_ref_addr); // Must be same compilation unit. reference_t declaration_debug_info_ptr = read_reference(abstract_debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.inc_indent(4)); dwarf_read(declaration_debug_info_ptr, code); LIBCWD_ASSERT( code < abbrev_entries.size() ); abbrev_st& abbrev3(abbrev_entries[code]); LIBCWD_ASSERT(abbrev3.tag == DW_TAG_subprogram); attr_st* attr3 = abbrev3.attributes; for (int i = 0; i < abbrev3.attributes_size; ++i, ++attr3) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr3->attr) << ' '); switch(attr3->attr) { case DW_AT_MIPS_linkage_name: saw_linkage_name = true; linkage_name = read_string(declaration_debug_info_ptr, attr3->form, debug_str); break; case DW_AT_name: name = read_string(declaration_debug_info_ptr, attr3->form, debug_str); break; case DW_AT_inline: case DW_AT_abstract_origin: DoutFatal(dc::core, "Huh? DW_AT_specification contains " << print_DW_AT_name(attr3->attr)); default: eat_form(declaration_debug_info_ptr, attr3->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; } } if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); break; } default: eat_form(abstract_debug_info_ptr, attr2->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); break; } } LIBCWD_ASSERT( saw_inline2 ); if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); break; } default: eat_form(debug_info_ptr, attr->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); } } } #endif else { // The not-so-important tags - scan through them as fast as possible. if (abbrev.fixed_size) { if (abbrev.starts_with_string) eat_string(debug_info_ptr); debug_info_ptr += abbrev.fixed_size; } else { // DW_AT_sibling is always the first attribute. if (abbrev.attributes_size > 0 && attr->attr == DW_AT_sibling && abbrev.tag != DW_TAG_structure_type && abbrev.tag != DW_TAG_class_type && abbrev.tag != DW_TAG_namespace && abbrev.tag != DW_TAG_lexical_block // Do DW_TAG_lexical_block ever have a DW_AT_sibling? ) { LIBCWD_ASSERT(abbrev.has_children); // Skip the children. DoutDwarf(dc::bfd|continued_cf, "decoding DW_AT_sibling "); debug_info_ptr = read_reference(debug_info_ptr, attr->form, debug_info_root, debug_info_start); if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); continue; } for (int i = 0; i < abbrev.attributes_size; ++i, ++attr) { DoutDwarf(dc::bfd|continued_cf, "decoding " << print_DW_AT_name(attr->attr) << ' '); eat_form(debug_info_ptr, attr->form DEBUGDWARF_OPT_COMMA(debug_str) DEBUGDWARF_OPT_COMMA(debug_info_root - debug_info_start)); } } } if (DEBUGDWARF) Debug(libcw_do.dec_indent(4)); if (abbrev.has_children) { ++level; if (DEBUGDWARF) Debug( libcw_do.marker().append("|", 1) ); } } LIBCWD_ASSERT( debug_info_ptr == debug_info_ptr_end ); LIBCWD_ASSERT( abstract_instances >= abstract_instances_referenced ); if (abstract_instances > abstract_instances_referenced) { DoutDwarf(dc::bfd|flush_cf, "Redundant abstract instances in " << current_compilation_unit->get_source_file() << " : abstract_instances == " << abstract_instances << "; abstract_instances_referenced == " << abstract_instances_referenced); } } else { LIBCWD_TSD_DECLARATION; _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(dc::warning, "DWARF version " << version << " is not understood by libcwd."); _private_::set_alloc_checking_off(LIBCWD_TSD); debug_info_ptr += length - sizeof(version); } } delete [] debug_line; delete [] debug_info; delete [] debug_abbrev; delete [] debug_str; M_dwarf_debug_line_section_index = 0; if (!M_stabs_section_index) delete_hash_list(); M_debug_info_loaded = true; #if CWDEBUG_ALLOC saved_internal = __libcwd_tsd.internal; __libcwd_tsd.internal = false; #endif Dout(dc::finish, "done"); #if CWDEBUG_ALLOC __libcwd_tsd.internal = saved_internal; #endif } void objfile_ct::load_stabs(void) { #if DEBUGSTABS LIBCWD_TSD_DECLARATION; LIBCWD_ASSERT( !M_stabs_debug_info_loaded ); M_stabs_debug_info_loaded = true; LIBCWD_ASSERT( M_sections[M_stabs_section_index].section_header().sh_entsize == sizeof(stab_st) ); #endif stab_st* stabs = (stab_st*)allocate_and_read_section(M_stabs_section_index); #ifndef __sun__ // The native Solaris 2.8 linker (ld) doesn't fill in the value of sh_link and also n_desc seems to have a different meaning. if (DEBUGSTABS) { LIBCWD_ASSERT( M_stabstr_section_index == M_sections[M_stabs_section_index].section_header().sh_link ); LIBCWD_ASSERT( !strcmp(&M_section_header_string_table[M_sections[M_stabstr_section_index].section_header().sh_name], ".stabstr") ); LIBCWD_ASSERT( stabs->n_desc == (Elfxx_Half)(M_sections[M_stabs_section_index].section_header().sh_size / M_sections[M_stabs_section_index].section_header().sh_entsize - 1) ); } #endif char* stabs_string_table = allocate_and_read_section(M_stabstr_section_index); if (DEBUGSTABS) Debug( libcw_do.inc_indent(4) ); Elfxx_Addr func_addr = 0; object_files_string cur_dir; object_files_string cur_source; object_files_string cur_func; location_ct location(this); range_st range; bool skip_function = false; bool source_file_changed_and_we_didnt_copy_it_yet = true; bool source_file_changed_but_line_number_not_yet = true; object_files_string_set_ct::iterator last_source_iter; for (unsigned int j = 0; j < M_sections[M_stabs_section_index].section_header().sh_size / M_sections[M_stabs_section_index].section_header().sh_entsize; ++j) { switch(stabs[j].n_type) { case N_SO: case N_SOL: { char const* filename = &stabs_string_table[stabs[j].n_strx]; if (*filename == '/') { if (filename[strlen(filename) - 1] == '/') { cur_dir.assign(filename); DoutStabs(dc::bfd, ((stabs[j].n_type == N_SO) ? "N_SO : \"" : "N_SOL: \"") << cur_dir << "\"."); break; } else cur_source.assign(filename); } else { if (filename[0] == '.' && filename[1] == '/') filename += 2; cur_source = catenate_path(cur_dir, filename); } cur_source += '\0'; last_source_iter = M_source_files.insert(cur_source).first; source_file_changed_and_we_didnt_copy_it_yet = source_file_changed_but_line_number_not_yet = true; DoutStabs(dc::bfd, ((stabs[j].n_type == N_SO) ? "N_SO : \"" : "N_SOL: \"") << cur_source.data() << "\"."); break; } case N_LBRAC: { DoutStabs(dc::bfd, "N_LBRAC: " << std::hex << stabs[j].n_value << '.'); if (stabs[j].n_value == 0) // Fix me: shouldn't be done (yet) while function start == source file start. M_brac_relative_to_fun = true; break; } case N_RBRAC: // We assume that the first N_RBRACE comes AFTER the last N_SLINE, // see http://www.informatik.uni-frankfurt.de/doc/texi/stabs_2.html#SEC14 { DoutStabs(dc::bfd, "N_RBRAC: " << std::hex << stabs[j].n_value << '.'); if (location.is_valid_stabs()) { DoutStabs(dc::bfd, "N_RBRAC: " << "end at " << std::hex << stabs[j].n_value << '.'); range.size = 0; // The closing brace has size 0... if (!skip_function) location.stabs_range(range); skip_function = false; location.invalidate(); } break; } case N_FUN: { char const* fn; char const* fn_end; if (stabs[j].n_strx == 0 #ifdef __sun__ // A function should always be represented by an `F' symbol descriptor for a global (extern) function, // and `f' for a static (local) function. See http://www.informatik.uni-frankfurt.de/doc/texi/stabs_2.html#SEC12 // But on solaris there turn out to be non-standard N_FUN stabs that mean I don't know what. Skip them here. || *(fn = &stabs_string_table[stabs[j].n_strx]) == 0 || !(fn_end = strchr(fn, ':')) || (fn_end[1] != 'F' && fn_end[1] != 'f') #endif ) { if (location.is_valid_stabs()) // Location is invalidated when we already processed the end of the function by N_RBRAC. { DoutStabs(dc::bfd, "N_FUN: " << "end at " << std::hex << stabs[j].n_value << '.'); range.size = func_addr + stabs[j].n_value - range.start; if (!skip_function) location.stabs_range(range); skip_function = false; location.invalidate(); } } else { #ifndef __sun__ fn = &stabs_string_table[stabs[j].n_strx]; fn_end = strchr(fn, ':'); #if DEBUGSTABS LIBCWD_ASSERT( fn_end && (fn_end[1] == 'F' || fn_end[1] == 'f') ); #endif #endif size_t fn_len = fn_end - fn; cur_func.assign(fn, fn_len); cur_func += '\0'; range.start = func_addr = stabs[j].n_value; DoutStabs(dc::bfd, "N_FUN: " << std::hex << func_addr << " : \"" << &stabs_string_table[stabs[j].n_strx] << "\"."); if (func_addr == 0 && location.is_valid_stabs()) { // Start of function is not given (bug in assembler?), try to find it by name: uint32_t hash = elf_hash(reinterpret_cast(fn), (unsigned char)':'); for(hash_list_st* p = M_hash_list[hash]; p; p = p->next) if (!strncmp(p->name, fn, fn_len)) { range.start = func_addr = p->addr; if (!p->already_added) { p->already_added = true; break; } } if (func_addr == 0) { // This can happen for .gnu.link_once section symbols: it might be that // a function is present in the current object file but is not used; // the dynamic linker has put it in the 'undefined' section and no // address is known even though there is still this N_FUN entry. skip_function = true; location.invalidate(); break; } else DoutStabs(dc::bfd, "Hash lookup: " << std::hex << range.start << '.'); } #if DEBUGSTABS else { Elfxx_Addr func_addr_test = 0; uint32_t hash = elf_hash(reinterpret_cast(fn), (unsigned char)':'); for(hash_list_st* p = M_hash_list[hash]; p; p = p->next) if (!strncmp(p->name, fn, fn_len)) { func_addr_test = p->addr; if (!p->already_added || func_addr_test == func_addr) { p->already_added = true; break; } } LIBCWD_ASSERT( func_addr_test == func_addr ); } #endif location.set_func_iter(M_function_names.insert(cur_func).first); location.invalidate(); // See N_SLINE } break; } case N_SLINE: DoutStabs(dc::bfd, "N_SLINE: " << stabs[j].n_desc << " at " << std::hex << stabs[j].n_value << '.'); if (stabs[j].n_value != 0) { // Always false when function was changed since last line because location.invalidate() was called in that case. // Catenate ranges with same location. if (!source_file_changed_and_we_didnt_copy_it_yet && location.is_valid_stabs() && stabs[j].n_desc == location.get_line()) break; range.size = func_addr + stabs[j].n_value - range.start; // Delay one source/line change when there was no code since last source file change. // The is apparently needed to deal with inlined functions. if (range.size == 0 && source_file_changed_but_line_number_not_yet) { source_file_changed_but_line_number_not_yet = false; break; } if (!skip_function && !source_file_changed_and_we_didnt_copy_it_yet) location.stabs_range(range); range.start += range.size; } // Store the source/line for the next range. location.set_source_iter(last_source_iter); location.set_line(stabs[j].n_desc); source_file_changed_and_we_didnt_copy_it_yet = false; source_file_changed_but_line_number_not_yet = false; break; } } if (DEBUGSTABS) Debug( libcw_do.dec_indent(4) ); delete [] stabs; delete [] stabs_string_table; M_stabs_section_index = 0; if (!M_dwarf_debug_line_section_index) delete_hash_list(); M_debug_info_loaded = true; } void objfile_ct::find_nearest_line(asymbol_st const* symbol, Elfxx_Addr offset, char const** file, char const** func, unsigned int* line LIBCWD_COMMA_TSD_PARAM) { while (!M_debug_info_loaded) // So we can use 'break'. { // The call to load_dwarf()/load_stabs() below can call malloc, causing us to recursively enter this function // for this object or another objfile_ct. #if !LIBCWD_THREAD_SAFE if (M_inside_find_nearest_line) // Break loop caused by re-entry through a call to malloc. { *file = NULL; *func = symbol->name; *line = 0; return; } M_inside_find_nearest_line = true; #else // LIBCWD_THREAD_SAFE // `S_thread_inside_find_nearest_line' is only *changed* inside the critical area // of `object_files_instance'. Therefore, when it is set to our thread id at // this moment - then other threads can't change it. if (pthread_equal(S_thread_inside_find_nearest_line, pthread_self())) { // This thread set the lock. Don't try to acquire it again... *file = NULL; *func = symbol->name; *line = 0; return; } // Ok, now we are sure that THIS thread doesn't hold the following lock, try to acquire it. // `object_files_string' and the STL containers using `_private_::object_files_allocator' in the following functions need this lock. #if CWDEBUG_ALLOC int saved_internal; #endif LIBCWD_DEFER_CLEANUP_PUSH(&_private_::rwlock_tct::cleanup, NULL); _private_::rwlock_tct::wrlock(); // Now we acquired the lock, check again if another thread not already read the debug info. if (!M_debug_info_loaded) { S_thread_inside_find_nearest_line = pthread_self(); #endif libcwd::debug_ct::OnOffState state; libcwd::channel_ct::OnOffState state2; if (DEBUGSTABS || DEBUGDWARF || (_private_::always_print_loading && !_private_::suppress_startup_msgs)) { // We want debug output to BFD Debug( libcw_do.force_on(state) ); Debug( dc::bfd.force_on(state2, "BFD") ); } if (M_dwarf_debug_line_section_index) load_dwarf(); else if (!M_stabs_section_index && !this->object_file->get_object_file()->has_no_debug_line_sections()) { this->object_file->get_object_file()->set_has_no_debug_line_sections(); #if CWDEBUG_ALLOC int saved_internal2 = __libcwd_tsd.internal; __libcwd_tsd.internal = false; #endif Dout( dc::warning, "Object file " << this->filename_str << " does not have debug info. Address lookups inside " "this object file will result in a function name only, not a source file location."); #if CWDEBUG_ALLOC __libcwd_tsd.internal = saved_internal2; #endif } if (M_stabs_section_index) load_stabs(); if (DEBUGSTABS || DEBUGDWARF || (_private_::always_print_loading && !_private_::suppress_startup_msgs)) { Debug(dc::bfd.restore(state2)); Debug(libcw_do.restore(state)); } int saved_internal3 = _private_::set_library_call_on(LIBCWD_TSD); M_input_stream->close(); _private_::set_library_call_off(saved_internal3 LIBCWD_COMMA_TSD); #if LIBCWD_THREAD_SAFE S_thread_inside_find_nearest_line = (pthread_t) 0; } _private_::rwlock_tct::wrunlock(); #if CWDEBUG_ALLOC saved_internal = __libcwd_tsd.internal; __libcwd_tsd.internal = false; #endif LIBCWD_CLEANUP_POP_RESTORE(false); #if CWDEBUG_ALLOC __libcwd_tsd.internal = saved_internal; #endif #else M_inside_find_nearest_line = false; #endif break; } range_st range; range.start = offset; range.size = 1; object_files_range_location_map_ct::const_iterator i(M_ranges.find(static_cast(range))); if (i == M_ranges.end() || ((*i).second.M_stabs_symbol && strcmp((*(*i).second.M_stabs_symbol_funcname_iter).data(), symbol->name))) { *file = NULL; *func = symbol->name; *line = 0; } else { *file = (*(*i).second.M_source_iter).data(); if ((*i).second.M_stabs_symbol) *func = (*(*i).second.M_stabs_symbol_funcname_iter).data(); else // dwarf *func = symbol->name; *line = (*i).second.M_line; } return; } char* objfile_ct::allocate_and_read_section(int i) { char* p = new char[M_sections[i].section_header().sh_size]; LIBCWD_TSD_DECLARATION; int saved_internal = _private_::set_library_call_on(LIBCWD_TSD); LIBCWD_DISABLE_CANCEL; M_input_stream->rdbuf()->pubseekpos(M_sections[i].section_header().sh_offset); M_input_stream->read(p, M_sections[i].section_header().sh_size); LIBCWD_ENABLE_CANCEL; _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); return p; } void objfile_ct::register_range(location_st const& location, range_st const& range) { #if DEBUGSTABS || DEBUGDWARF LIBCWD_TSD_DECLARATION; if ((DEBUGDWARF && M_dwarf_debug_line_section_index) || (DEBUGSTABS && M_stabs_section_index)) { if (doutdwarfon || doutstabson) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(dc::bfd, std::hex << range.start << " - " << (range.start + range.size) << "; " << location << '.'); _private_::set_alloc_checking_off(LIBCWD_TSD); } } #endif std::pair p(M_ranges.insert(std::pair(range, location))); if (p.second) return; // Do some error recovery. std::pair old(*p.first); // Currently stored range. std::pair nw(range, location); // New range. #if DEBUGSTABS || DEBUGDWARF Elfxx_Addr low = old.first.start; Elfxx_Addr high = old.first.start + old.first.size - 1; char const* low_mn = pc_mangled_function_name((char const*)this->object_file->get_lbase() + low); char const* high_mn = pc_mangled_function_name((char const*)this->object_file->get_lbase() + high); if (doutdwarfon || doutstabson) { if (low_mn != high_mn) { Dout(dc::bfd, std::hex << low << " == " << low_mn); Dout(dc::bfd, std::hex << high << " == " << high_mn); } else Dout(dc::bfd, "Function: " << low_mn); } #endif bool need_old_reinsert = false; bool need_restore = false; range_st save_old_range = { 0, 0 }; // Avoid compiler warning. #if DEBUGSTABS || DEBUGDWARF _private_::set_alloc_checking_on(LIBCWD_TSD); #endif if (!location.M_stabs_symbol || !(*p.first).second.M_stabs_symbol || (*p.first).second.M_stabs_symbol_funcname_iter != location.M_stabs_symbol_funcname_iter) #if DEBUGSTABS || DEBUGDWARF if (doutdwarfon || doutstabson) Dout(dc::bfd, "WARNING: Collision between different functions (" << *p.first << ")!?"); #else ; #endif else { bool different_start = (*p.first).first.start != range.start; bool different_lines = (*p.first).second.M_line != location.M_line; if (different_start && different_lines) { // The most important reason for this, is a bug in GNU as version 2.3.90: // The last address increment just prior to the end of a function // is too large. So, it is the end of the range that we cannot trust. // // Cut off the first range so at least we cover the total. // Before: // |<--range1-->| // |<--range2-->| // After: // ||<--range2-->| // // Now GNU as version 2.4.90 does not have this bug, but has another bug. // that bug is a lot harder to recover from, less frequently happening // and at the moment of writing not in use by many people; therefore no // attempt to recover from that has been added but instead this has been // reported as a bug to the binutils people. // See http://sources.redhat.com/ml/binutils/2003-10/msg00456.html if (nw.first.start < old.first.start) { // + |<--old range-->| // |<--new range------>? nw.first.size = old.first.start - nw.first.start; // Cut short new range. } else { // |<--old range------>? // ? |<--new range-->| #if DEBUGSTABS || DEBUGDWARF if (doutdwarfon || doutstabson) Dout(dc::bfd, "WARNING: New range overlaps old range, removing (" << *p.first << "),"); #else LIBCWD_TSD_DECLARATION; #endif save_old_range = old.first; // Backup. _private_::set_alloc_checking_off(LIBCWD_TSD); M_ranges.erase(p.first); _private_::set_alloc_checking_on(LIBCWD_TSD); need_restore = true; old.first.size = nw.first.start - old.first.start; // Cut short old range. if (old.first.size > 0) { #if DEBUGSTABS || DEBUGDWARF if (doutdwarfon || doutstabson) Dout(dc::bfd, " ... and adding (" << old << ")."); #endif need_old_reinsert = true; } } #if DEBUGSTABS || DEBUGDWARF _private_::set_alloc_checking_off(LIBCWD_TSD); if (doutdwarfon || doutstabson) Dout(dc::bfd, "WARNING: New range being added instead: " << nw); LIBCWD_ASSERT( nw.first.size > 0 ); // Check that new range falls within one function. char const* nwlow_mn = pc_mangled_function_name((char const*)this->object_file->get_lbase() + nw.first.start); LIBCWD_ASSERT( nwlow_mn == pc_mangled_function_name((char const*)this->object_file->get_lbase() + nw.first.start + nw.first.size - 1)); // This is specific to the (only known) gas bug; check that this is at the end of function. // Note we only get here when the collision was with a range in the same source file, so we can // use the same this->object_file for the next function. LIBCWD_ASSERT( nwlow_mn != pc_mangled_function_name((char const*)this->object_file->get_lbase() + nw.first.start + ((nw.first.start < old.first.start) ? (int)nw.first.size : -1))); #endif if (!M_ranges.insert(nw).second) { #if DEBUGSTABS || DEBUGDWARF if (doutdwarfon || doutstabson) Dout(dc::bfd, "WARNING: Insertion of new range still failed"); #endif if (need_restore) { old.first = save_old_range; #if DEBUGSTABS || DEBUGDWARF if (doutdwarfon || doutstabson) Dout(dc::bfd, " ... backing up to old situation (" << old << ")."); #endif need_old_reinsert = true; } } if (need_old_reinsert) { #if DEBUGSTABS || DEBUGDWARF p = #endif M_ranges.insert(old); #if DEBUGSTABS || DEBUGDWARF if (!p.second) if (doutdwarfon || doutstabson) DoutFatal(dc::core, "Re-adding of shortened old range failed."); #endif } return; } #if DEBUGSTABS || DEBUGDWARF else if (doutdwarfon || doutstabson) { if ((*p.first).second.M_source_iter != location.M_source_iter) Dout(dc::bfd, "Collision with " << *p.first << "."); else if (different_start) Dout(dc::bfd, "WARNING: Different start for same function (" << *p.first << ")!?"); else if (different_lines) Dout(dc::bfd, "WARNING: Different line numbers for overlapping range (" << *p.first << ")!?"); else if ((*p.first).first.size != range.size) Dout(dc::bfd, "WARNING: Different sizes for same function!"); } #endif } #if DEBUGSTABS || DEBUGDWARF _private_::set_alloc_checking_off(LIBCWD_TSD); #endif } objfile_ct::objfile_ct(void) : M_section_header_string_table(NULL), M_sections(NULL), M_symbol_string_table(NULL), M_dyn_symbol_string_table(NULL), M_symbols(NULL), M_number_of_symbols(0), M_symbol_table_type(0), M_hash_list(NULL) { } void objfile_ct::initialize(char const* file_name) { filename_str = file_name; LIBCWD_TSD_DECLARATION; int saved_internal = _private_::set_library_call_on(LIBCWD_TSD); Debug( libcw_do.off() ); _private_::set_invisible_on(LIBCWD_TSD); M_input_stream = new std::ifstream; // LEAK10 M_input_stream->open(file_name); _private_::set_invisible_off(LIBCWD_TSD); Debug( libcw_do.on() ); if (!M_input_stream->good()) DoutFatal(dc::fatal|error_cf, "std::ifstream.open(\"" << file_name << "\")"); _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); _private_::set_library_call_on(LIBCWD_TSD); *M_input_stream >> M_header; _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); LIBCWD_ASSERT(M_header.e_shentsize == sizeof(Elfxx_Shdr)); if (M_header.e_shoff == 0 || M_header.e_shnum == 0) return; _private_::set_library_call_on(LIBCWD_TSD); M_input_stream->rdbuf()->pubseekpos(M_header.e_shoff); _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); Elfxx_Shdr* section_headers = new Elfxx_Shdr [M_header.e_shnum]; _private_::set_library_call_on(LIBCWD_TSD); M_input_stream->read(reinterpret_cast(section_headers), M_header.e_shnum * sizeof(Elfxx_Shdr)); _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); if (DEBUGELFXX) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(dc::bfd, "Number of section headers: " << M_header.e_shnum); _private_::set_alloc_checking_off(LIBCWD_TSD); } LIBCWD_ASSERT( section_headers[M_header.e_shstrndx].sh_size > 0 && section_headers[M_header.e_shstrndx].sh_size >= section_headers[M_header.e_shstrndx].sh_name ); M_section_header_string_table = new char[section_headers[M_header.e_shstrndx].sh_size]; // LEAK11 _private_::set_library_call_on(LIBCWD_TSD); M_input_stream->rdbuf()->pubseekpos(section_headers[M_header.e_shstrndx].sh_offset); M_input_stream->read(M_section_header_string_table, section_headers[M_header.e_shstrndx].sh_size); _private_::set_library_call_off(saved_internal LIBCWD_COMMA_TSD); LIBCWD_ASSERT( !strcmp(&M_section_header_string_table[section_headers[M_header.e_shstrndx].sh_name], ".shstrtab") ); M_sections = new section_ct[M_header.e_shnum]; // LEAK11 if (DEBUGELFXX) Debug( libcw_do.inc_indent(4) ); M_debug_info_loaded = false; M_brac_relative_to_fun = false; #if !LIBCWD_THREAD_SAFE M_inside_find_nearest_line = false; #endif #if DEBUGSTABS M_stabs_debug_info_loaded = false; #endif #if DEBUGDWARF M_dwarf_debug_info_loaded = false; #endif M_stabs_section_index = 0; M_dwarf_debug_line_section_index = 0; M_dwarf_debug_str_section_index = 0; for(int i = 0; i < M_header.e_shnum; ++i) { if (DEBUGELFXX && section_headers[i].sh_name) { _private_::set_alloc_checking_on(LIBCWD_TSD); Dout(dc::bfd, "Section name: \"" << &M_section_header_string_table[section_headers[i].sh_name] << '"'); _private_::set_alloc_checking_off(LIBCWD_TSD); } M_sections[i].init(M_section_header_string_table, section_headers[i]); if (!strcmp(M_sections[i].name, ".strtab")) M_symbol_string_table = allocate_and_read_section(i); else if (!strcmp(M_sections[i].name, ".dynstr")) M_dyn_symbol_string_table = allocate_and_read_section(i); else if (M_dwarf_debug_line_section_index == 0 && !strcmp(M_sections[i].name, ".stab")) M_stabs_section_index = i; else if (!strcmp(M_sections[i].name, ".stabstr")) M_stabstr_section_index = i; else if (!strcmp(M_sections[i].name, ".debug_line")) M_dwarf_debug_line_section_index = i; else if (!strcmp(M_sections[i].name, ".debug_abbrev")) M_dwarf_debug_abbrev_section_index = i; else if (!strcmp(M_sections[i].name, ".debug_info")) M_dwarf_debug_info_section_index = i; else if (!strcmp(M_sections[i].name, ".debug_str")) M_dwarf_debug_str_section_index = i; if (section_headers[i].sh_type == SHT_SYMTAB) M_is_stripped = false; if ((section_headers[i].sh_type == SHT_SYMTAB || section_headers[i].sh_type == SHT_DYNSYM) && section_headers[i].sh_size > 0) { M_has_syms = true; LIBCWD_ASSERT( section_headers[i].sh_entsize == sizeof(Elfxx_Sym) ); LIBCWD_ASSERT( M_symbol_table_type != SHT_SYMTAB || section_headers[i].sh_type != SHT_SYMTAB); // There should only be one SHT_SYMTAB. if (M_symbol_table_type != SHT_SYMTAB) // If there is one, use it. { M_symbol_table_type = section_headers[i].sh_type; M_number_of_symbols = section_headers[i].sh_size / section_headers[i].sh_entsize; } } } if (DEBUGELFXX) { _private_::set_alloc_checking_on(LIBCWD_TSD); Debug( libcw_do.dec_indent(4) ); Dout(dc::bfd, "Number of symbols: " << M_number_of_symbols); _private_::set_alloc_checking_off(LIBCWD_TSD); } delete [] section_headers; } bfd_st* bfd_st::openr(char const* file_name) { #if LIBCWD_THREAD_SAFE _private_::rwlock_tct::wrlock(); #endif objfile_ct* objfile = new objfile_ct; // LEAK9 #if LIBCWD_THREAD_SAFE _private_::rwlock_tct::wrunlock(); #endif objfile->initialize(file_name); return objfile; } } // namespace elfxx } // namespace libcwd #if DEBUGSTABS || DEBUGDWARF namespace libcwd { namespace cwbfd { bfile_ct* load_object_file(char const* name, void* l_addr); } } // This can be used to load and print an arbitrary object file (for debugging purposes). void debug_load_object_file(char const* filename, bool /* shared */ = true) { using namespace libcwd; cwbfd::bfile_ct* bfile = cwbfd::load_object_file(filename, 0); if (!bfile) return; LIBCWD_TSD_DECLARATION; libcwd::_private_::set_alloc_checking_off(LIBCWD_TSD); using namespace libcwd::elfxx; doutdwarfon = true; objfile_ct* of = static_cast(bfile->get_bfd()); if (of->M_dwarf_debug_line_section_index) of->load_dwarf(); else if (!of->M_stabs_section_index && !of->object_file->get_object_file()->has_no_debug_line_sections()) { of->object_file->get_object_file()->set_has_no_debug_line_sections(); libcwd::_private_::set_alloc_checking_on(LIBCWD_TSD); Dout( dc::warning, "Object file " << of->filename_str << " does not have debug info. Address lookups inside " "this object file will result in a function name only, not a source file location."); libcwd::_private_::set_alloc_checking_off(LIBCWD_TSD); } if (of->M_stabs_section_index) of->load_stabs(); libcwd::_private_::set_alloc_checking_on(LIBCWD_TSD); of->M_input_stream->close(); doutdwarfon = false; } #endif #endif // CWDEBUG_LOCATION libcwd-1.0.4/nodebug.h0000644000175000017500000000163010642737347013553 0ustar carlocarlo#define AllocTag1(p) #define AllocTag2(p, desc) #define AllocTag_dynamic_description(p, data) #define AllocTag(p, data) #define Debug(STATEMENT...) #define Dout(cntrl, data) #define DoutFatal(cntrl, data) LibcwDoutFatal(, , cntrl, data) #define ForAllDebugChannels(STATEMENT...) #define ForAllDebugObjects(STATEMENT...) #define LibcwDebug(dc_namespace, STATEMENT...) #define LibcwDout(dc_namespace, d, cntrl, data) #define LibcwDoutFatal(dc_namespace, d, cntrl, data) do { ::std::cerr << data << ::std::endl; ::std::exit(EXIT_FAILURE); } while(1) #define LibcwdForAllDebugChannels(dc_namespace, STATEMENT...) #define LibcwdForAllDebugObjects(dc_namespace, STATEMENT...) #define NEW(x) new x #define CWDEBUG_ALLOC 0 #define CWDEBUG_MAGIC 0 #define CWDEBUG_LOCATION 0 #define CWDEBUG_LIBBFD 0 #define CWDEBUG_DEBUG 0 #define CWDEBUG_DEBUGOUTPUT 0 #define CWDEBUG_DEBUGM 0 #define CWDEBUG_DEBUGT 0 #define CWDEBUG_MARKER 0 libcwd-1.0.4/libcwd.spec.in0000644000175000017500000000673710642737347014521 0ustar carlocarloSummary: The C++ Debugging Support Library, for ostream debug output and memory allocation debugging. Name: libcwd %define __prefix /usr %define version @VERSION@ Version: %{version} Release: 1 Group: Development/Libraries Source: http://download.sourceforge.net/libcwd/libcwd-%{version}.tar.gz License: QPL %ifos linux Requires: gcc-c++ >= 3.0, binutils >= 2.9 %endif Buildroot: %{_tmppath}/%{name}-root BuildPrereq: make, m4, which >= 2.5, autoconf >= 2.13, automake >= 1.6, libtool >= 1.4.2 URL: http://libcwd.sourceforge.net/ %description Libcwd is a full-featured, professional, well documented library to support C++ developers with debugging their applications. It includes support for ostream-based debug output, custom debug channels and devices, threading, powerful memory allocation debugging, run-time sourcefile:linenumber information and demangled type-names of variables. %prep %setup %build ./configure --prefix=%{__prefix} make %install rm -rf "$RPM_BUILD_ROOT" make DESTDIR="$RPM_BUILD_ROOT" install tar --exclude .svn -czf example-project.tar.gz example-project %clean rm -rf "$RPM_BUILD_ROOT" %post PATH="$PATH:/sbin" ldconfig -n %{__prefix}/lib echo echo "Please look at %{__prefix}/doc/libcwd-%{version}/example-project.tar.gz" echo "for an example of how to write an application that uses libcwd." echo "Detailed documentation can be found in" echo "file://%{__prefix}/doc/libcwd-%{version}/index.html" echo %files %defattr(-,root,root) %doc example-project.tar.gz %doc documentation/0README %doc documentation/tutorial %doc documentation/reference-manual %doc documentation/scripts %doc documentation/styles %doc documentation/images %doc documentation/external %doc documentation/doxygen-examples %doc documentation/www %doc documentation/index.html %dir %{__prefix}/include/libcwd %{__prefix}/lib/* %{__prefix}/lib/pkgconfig/*.pc %{__prefix}/include/libcwd/* %{__prefix}/share/libcwd/libcwdrc %changelog * Fri Mar 12 2004 Carlo Wood - Added pkgconfig support. * Sat May 3 2003 Carlo Wood - 0.99.29 needs g++ 3.0 or higher. - Headers were moved to include/libcwd. * Mon Apr 14 2003 Carlo Wood - Renamed include/libcw to include/libcwd. * Tue Mar 19 2002 Carlo Wood - Corrected URL and source url. - Reference manual sits in documentation/reference-manual as of 0.99.19. - Require libtool 1.4.2 or higher. - Improved summary. * Mon Mar 18 2002 Carlo Wood - Require automake 1.5 or higher. * Wed Mar 14 2002 Carlo Wood - Added documentation/www and documentation/index.html as main page. * Wed Feb 13 2002 Carlo Wood - Allow also version of autoconf larger than 2.13. * Sun Dec 09 2001 Carlo Wood - Added a URL: and BuildPrereq: entry. - Added doxygen documentation to the rpm. * Wed Sep 13 2000 Carlo Wood - Added example-project to doc/ and added a %post instruction echo. * Sat Sep 02 2000 Carlo Wood - Still generate libcwd.lsm and libcwd.spec in config.status, but only when initiated from maintMakefile according to Makefile rules. Put them in $(srcdir) because they need to be put in the distribution. - Add file list to %files. Added a 'Requires:' and started to use macros for prefix and version. - Use '@@' instead of '!!' because now the spec file is generated from spec.in by config.status. * Thu Aug 31 2000 Carlo Wood - Remove build root in %clean. - Initial version. libcwd-1.0.4/valgrind.supp0000644000175000017500000007112410642737347014503 0ustar carlocarlo{ libcwd/LEAK2/List with debug channels Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_17debug_channels_ct4initEv } { libcwd/LEAK3/List with debug channels Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_17debug_channels_ct15init_and_rdlockEv } { libcwd/LEAK4/Map with memory blocks Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd16init_debugmallocEv } { libcwd/LEAK5 Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd11location_ct13M_pc_locationEPKv fun:_ZN6libcwd11location_ctC1EPKv fun:_ZN6libcwd14location_cacheEPKv } { libcwd/LEAK6/Object file with debug symbols Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK7/Default marker string Memcheck:Leak fun:malloc fun:malloc fun:_ZN6libcwd15debug_string_ct16NS_internal_initEPKcj fun:_ZN6libcwd12debug_tsd_st4initEv fun:_ZN6libcwd8debug_ct7NS_initEv fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK8/Object file path Memcheck:Leak fun:malloc fun:malloc fun:_ZN6libcwd14object_file_ctC1EPKc fun:_ZN6libcwd5cwbfd8bfile_ctC1EPKcPv fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK9/Object file Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK10/Object file input stream Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znwj fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK11/Object file sections and section header string table Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK12/Object file symbol table Memcheck:Leak fun:malloc fun:malloc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK13/ Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:malloc fun:__fopen_internal fun:fopen64 fun:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK14/ Memcheck:Leak fun:realloc fun:realloc fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK15/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct25allocate_and_read_sectionEi fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK16/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct25allocate_and_read_sectionEi fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK17/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct25allocate_and_read_sectionEi fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK18/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorINS0_19compilation_unit_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAllocILb0ELin2EEELNS1_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAlloc* fun:_ZNSt6vectorIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK19/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK20/ Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:malloc fun:__fopen_internal fun:fopen64 fun:_ZNSt12__basic_fileIcE4openEPKcSt13_Ios_Openmodei fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK21/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeISbIcSt11char_traitsIcENS1_IcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EEEEES6_LS7_1EE8allocateEj fun:_ZNSt8_Rb_treeISbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptor* fun:_ZNSt8_Rb_treeISbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptor* fun:_ZNSt8_Rb_treeISbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptor* fun:_ZNSt8_Rb_treeISbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptor* fun:_ZNSt3setISbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEESt4lessIS9_ENS4_IS9_S6_LS7_1EEEE6insertERKS9_ fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK22/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd9_private_19compilation_unit_ct15set_source_fileERKSbIcSt11char_traitsIcENS0_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EEEE fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK23/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK24/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd5cwbfd30ST_get_full_path_to_executableERSbIcSt11char_traitsIcENS_9_private_17allocator_adaptorIcNS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE fun:_ZN6libcwd5cwbfd7ST_initEv fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK25/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd5cwbfd30ST_get_full_path_to_executableERSbIcSt11char_traitsIcENS_9_private_17allocator_adaptorIcNS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE fun:_ZN6libcwd5cwbfd7ST_initEv fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK26/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIPNS_10channel_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZN6libcwd10channel_ct13NS_initializeEPKcb fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK27/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIPNS_10channel_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZN6libcwd10channel_ct13NS_initializeEPKcb fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK28/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIPNS_10channel_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZN6libcwd10channel_ct13NS_initializeEPKcb fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK29/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIPNS_10channel_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIPN6libcwd10channel_ctENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZN6libcwd10channel_ct13NS_initializeEPKcb fun:_ZN6libcwd10channel_ctC1EPKcb fun:_Z41__static_initialization_and_destruction_0ii } { libcwd/LEAK30/ Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znaj fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK31/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK32/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeISt4pairIKNS_5elf328range_stENS4_11location_stEEENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt3mapIN6libcwd5elf328range_stENS1_11location_stENS1_16compare_range_stENS0_9_private_17allocator_adaptorISt4pairIKS2_S3_ENS5_13CharPoolAllocILb0ELin2EEELNS5_7pool_ntE1EEEE6insertERKS9_ fun:_ZN6libcwd5elf3210objfile_ct14register_rangeERKNS0_11location_stERKNS0_8range_stE fun:_ZN6libcwd5elf3211location_ct7M_storeEv fun:_ZN6libcwd5elf3211location_ct4copyEv fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK33/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK34/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK35/ Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znaj fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE27_M_allocate_internal_bufferEv fun:_ZNSt13basic_filebufIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK36/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeISt4pairIKNS_5elf328range_stENS4_11location_stEEENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt3mapIN6libcwd5elf328range_stENS1_11location_stENS1_16compare_range_stENS0_9_private_17allocator_adaptorISt4pairIKS2_S3_ENS5_13CharPoolAllocILb0ELin2EEELNS5_7pool_ntE1EEEE6insertERKS9_ fun:_ZN6libcwd5elf3210objfile_ct14register_rangeERKNS0_11location_stERKNS0_8range_stE fun:_ZN6libcwd5elf3211location_ct7M_storeEv fun:_ZN6libcwd5elf3211location_ct12sequence_endEv fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK37/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeINS_5cwbfd9symbol_ctEENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt3setIN6libcwd5cwbfd9symbol_ctENS1_18symbol_key_greaterENS0_9_private_17allocator_adaptorIS2_NS4_13CharPoolAllocILb0ELin2EEELNS4_7pool_ntE1EEEE6insertERKS2_ fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK38/ Memcheck:Leak fun:realloc fun:realloc fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK39/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeINS_5cwbfd9symbol_ctEENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt8_Rb_treeIN6libcwd5cwbfd9symbol_ctES2_St9_IdentityIS2_ENS1_18symbol_key_greater* fun:_ZNSt3setIN6libcwd5cwbfd9symbol_ctENS1_18symbol_key_greaterENS0_9_private_17allocator_adaptorIS2_NS4_13CharPoolAllocILb0ELin2EEELNS4_7pool_ntE1EEEE6insertERKS2_ fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK40/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct25allocate_and_read_sectionEi fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK41/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct19canonicalize_symtabEPPNS0_10asymbol_stE fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK42/ Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd5elf3210objfile_ct25allocate_and_read_sectionEi fun:_ZN6libcwd5elf3210objfile_ct10initializeEPKc fun:_ZN6libcwd5elf326bfd_st5openrEPKc fun:_ZN6libcwd5cwbfd8bfile_ct10initializeEPKcb fun:_ZN6libcwd5cwbfd16load_object_fileEPKcPv } { libcwd/LEAK43/ Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorISt13_Rb_tree_nodeISt4pairIKNS_5elf328range_stENS4_11location_stEEENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt8_Rb_treeIN6libcwd5elf328range_stESt4pairIKS2_NS1_11location_stEESt10_Select1st* fun:_ZNSt3mapIN6libcwd5elf328range_stENS1_11location_stENS1_16compare_range_stENS0_9_private_17allocator_adaptorISt4pairIKS2_S3_ENS5_13CharPoolAllocILb0ELin2EEELNS5_7pool_ntE1EEEE6insertERKS9_ fun:_ZN6libcwd5elf3210objfile_ct14register_rangeERKNS0_11location_stERKNS0_8range_stE fun:_ZN6libcwd5elf3211location_ct7M_storeEv fun:_ZN6libcwd5elf3211location_ct14increment_lineEi fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK44 Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd9_private_10make_labelEPKc } { libcwd/LEAK45 Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd25allocate_AllocTag_WS_descEj } { libcwd/LEAK46 Memcheck:Leak fun:malloc fun:malloc fun:_ZN6libcwd15debug_string_ct16NS_internal_initEPKcj fun:_ZN6libcwd12debug_tsd_st4initEv fun:_ZN6libcwd8debug_ct7NS_initEv } { libcwd/LEAK47 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd5elf3213catenate_pathERKSbIcSt11char_traitsIcENS_9_private_17allocator_adaptorIcNS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEEPKc fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK48 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorINS_5elf3212file_name_stENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIN6libcwd5elf3212file_name_stENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIN6libcwd5elf3212file_name_stENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIN6libcwd5elf3212file_name_stENS0_9_private_17allocator_adaptorIS2_NS3_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK49 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd14memblk_info_ctC1EPKNS_8appblockEjNS_15memblk_types_ntERK7timevalPKNS_11location_ctE } { libcwd/LEAK50 Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znwj fun:_ZNSs4_Rep9_S_createEjjRKSaIcE fun:_ZNSs4_Rep8_M_cloneERKSaIcEj fun:_ZNSs7reserveEj fun:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi fun:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKci fun:_ZNSo5writeEPKci fun:_ZN6libcwd9buffer_ct7writetoEPSoRNS_8debug_ctEbb } { libcwd/LEAK51 Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znwj fun:_ZNSs4_Rep9_S_createEjjRKSaIcE fun:_ZNSs4_Rep8_M_cloneERKSaIcEj fun:_ZNSs7reserveEj fun:_ZNSs6appendEPKcj fun:_ZN6libcwd15demangle_symbolEPKcRSs } { libcwd/LEAK52 Memcheck:Leak fun:malloc fun:_Znwj fun:dlopen } { libcwd/LEAK53 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZN6libcwd9_private_19compilation_unit_ct25set_compilation_directoryERKSbIcSt11char_traitsIcENS0_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EEEE fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK54 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZNSbIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS2_13CharPoolAlloc* fun:_ZStplIcSt11char_traitsIcEN6libcwd9_private_17allocator_adaptorIcNS3_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK46/A margin string Memcheck:Leak fun:malloc fun:malloc fun:_ZN6libcwd15debug_string_ct16NS_internal_initEPKcj fun:_ZN6libcwd15debug_string_ctC1ERKS0_ fun:_ZN6libcwd29debug_string_stack_element_ctC1ERKNS_15debug_string_ctE fun:_ZN6libcwd8debug_ct11push_marginEv } { libcwd/LEAK55 Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd11location_ct13M_pc_locationEPKv fun:_ZN6libcwd11location_ct29handle_delayed_initializationERKNS_15alloc_filter_ctE fun:_ZN6libcwd14location_cacheEPKv } { libcwd/LEAK56 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorIPKcNS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIPKcN6libcwd9_private_17allocator_adaptorIS1_NS3_13CharPoolAllocILb0ELin2EEELNS3_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIPKcN6libcwd9_private_17allocator_adaptorIS1_NS3_13CharPoolAlloc* fun:_ZNSt6vectorIPKcN6libcwd9_private_17allocator_adaptorIS1_NS3_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK57 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_8FreeList8allocateEij fun:_ZN6libcwd9_private_13CharPoolAllocILb0ELin2EE8allocateEj fun:_ZN6libcwd9_private_17allocator_adaptorINS0_19compilation_unit_ctENS0_13CharPoolAllocILb0ELin2EEELNS0_7pool_ntE1EE8allocateEj fun:_ZNSt12_Vector_baseIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAllocILb0ELin2EEELNS1_7pool_ntE1EEEE11_M_allocateEj fun:_ZNSt6vectorIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAlloc* fun:_ZNSt6vectorIN6libcwd9_private_19compilation_unit_ctENS1_17allocator_adaptorIS2_NS1_13CharPoolAlloc* fun:_ZN6libcwd5elf3210objfile_ct10load_dwarfEv } { libcwd/LEAK58/type_info_of name Memcheck:Leak fun:malloc fun:_Znaj fun:_ZN6libcwd9_private_18extract_exact_nameEPKcS2_ } { libcwd/LEAK59 Memcheck:Leak fun:malloc fun:_Znwj fun:_ZN6libcwd9_private_16debug_objects_ct4initEv fun:_ZN6libcwd8debug_ct7NS_initEv fun:_ZN6libcwd21ST_initialize_globalsEv } { libcwd/LEAK60 Memcheck:Leak fun:malloc fun:_ZN6libcwd15internal_mallocEjNS_15memblk_types_ntEPvj fun:_Znwj fun:_ZN6libcwd12debug_tsd_st5startERNS_8debug_ctERNS_19channel_set_data_stE } libcwd-1.0.4/libcwdrc0000644000175000017500000000205010642737347013470 0ustar carlocarlo# This is the default rcfile of libcwd. # It will be read when you issue a Debug(read_rcfile()); # in your program and there is no ./.libcwdrc or $HOME/.libcwdrc. # Usage: # # int main() # { # Debug( libcw_do.on() ); # Debug( read_rcfile() ); # Turn this on if you don't want detailed RCFILE messages to be printed. # If you also don't want to see any warnings that this file might produce, # then don't turn on the debug object before calling Debug(read_rcfile()); silent = off # Turn all channels off by default. channels_default = off # Toggle (turn on) channels matching these masks. # This must be a comma seperated list of channel label masks # that will be matched case insensitive against the labels # of the channels. channels_toggle = M*,BFD, n*tice # Always turn on the WARNING channel! channels_on = warning # You can also just give a list #channels_off = notice,malloc # Where to find gdb. gdb = /usr/bin/gdb # Commandline to execute in order to open a window (for starting gdb at run time). xterm = konsole -geometry =1024x400+0+0 -e %s libcwd-1.0.4/testsuite/0000755000175000017500000000000011405442001013762 5ustar carlocarlolibcwd-1.0.4/testsuite/libcwd.nodebug/0000755000175000017500000000000011405442001016650 5ustar carlocarlolibcwd-1.0.4/testsuite/libcwd.nodebug/nodebug.cc0000644000175000017500000000064010642737343020624 0ustar carlocarlo#include "sys.h" #include int main(void) { #if !CWDEBUG_ALLOC || !CWDEBUG_LOCATION DoutFatal(dc::fatal, "Expected Failure."); #endif Debug( libcw_do.on() ); Debug( dc::malloc.on() ); #if CWDEBUG_LOCATION Debug( dc::bfd.on() ); #endif int* p = new int [100]; Debug( make_all_allocations_invisible_except(p) ); Debug( list_allocations_on(libcw_do) ); delete [] p; return 0; } libcwd-1.0.4/testsuite/libcwd.nodebug/nodebug.re0000644000175000017500000000256210642737343020652 0ustar carlocarlo// input lines 5 // output till (Loading debug info.*/nodebug_nodebug_s|Warning: Address|Address lookups inside this object) ((WARNING : core size is limited.* )*(BFD : Loading debug symbols from.* )*(BFD : Loading debug info from .*/libcwd\.so\.0\.\.\. done )*MALLOC : operator new\[\] \(size = 400\) = ) // input lines 6 // output till ^MALLOC ((BFD : Loading debug info from.*/nodebug_nodebug_s.....\.\.\. done )*(BFD : Warning: Address 0x[a-f0-9]+ in section \.text of object file "nodebug_nodebug_(shared|static)" does not have a line number, perhaps the unit containing the function `_*main' wasn't compiled with flag -(g|ggdb)\? )|(WARNING : Object file .*/nodebug_nodebug_shared does not have debug info\. Address lookups inside this object file will result in a function name only, not a source file location\. )) MALLOC : 0x[a-f0-9]+ \[nodebug_nodebug_shared:main\] // input lines 2 // output till ^MALLOC (WARNING : Object file /lib/libc\.so\.6 does not have debug info.* )* MALLOC : Allocated memory: (400|408) bytes in (1|2) blocks\. new\[\] 0x[a-f0-9]+ (_*main|) *; \(sz = 400\) // input lines 2 // output till ^MALLOC (malloc 0x[a-f0-9]+ *eh_globals\.cc:[0-9]* *; \(sz = 8\) )* MALLOC : delete\[\] 0x[a-f0-9]+ (_*main|) *; \(sz = 400\) libcwd-1.0.4/testsuite/libcwd.nodebug/nodebug.exp0000644000175000017500000000076510642737343021043 0ustar carlocarloglobal srcdir subdir global STATIC SHARED catch "glob -nocomplain $srcdir/$subdir/*.cc" srcfiles #set srcfiles $srcdir/$subdir/type_info.cc verbose "srcfiles are $srcfiles" set prefix "" foreach x $srcfiles { regsub "\\.cc$" $x "" prefix set resfile "${prefix}.re" set options "regexp_match nodebug" if { $STATIC == "yes" } { test_libcwd "static $options" "${prefix}.cc" $resfile } if { $SHARED == "yes" } { test_libcwd "$options" "${prefix}.cc" $resfile } } libcwd-1.0.4/testsuite/lib/0000755000175000017500000000000011405442001014530 5ustar carlocarlolibcwd-1.0.4/testsuite/lib/libcwd.exp0000644000175000017500000001463610642737343016546 0ustar carlocarloload_lib "libgloss.exp" load_lib "targetdb.exp" # # Run the test specified by srcfile and resultfile. # proc test_libcwd { options srcfile resultfile } { global base_dir global objdir global board verbose "Calling test_libcwd:" verbose " options = \"$options\"" verbose " srcfile = \"$srcfile\"" verbose " resultfile = \"$resultfile\"" set board [target_info name] regsub "^.*/libcwd\.(\[^/\]+)/(\[^/.\]+)\.\[^/.\]*$" "$srcfile" "\\1_\\2" out verbose " out = \"$out\"" if { [regexp -- "static" $options] } { set executable "${objdir}/$out\_static" } else { set executable "${objdir}/$out\_shared" } set errname "[file tail $executable]" set target "[file tail $executable]" verbose "Executing \"exec gmake -s $target\"" set compileroutput "[exec gmake -s $target]" # Kludge to remove linker _warnings_ from output. # The expected form is: /usr/lib/libc.so.4: warning: ... # or: /usr/lib/libc.so.4: WARNING! ... regsub -all -line -nocase -- "^.*: warning\[!:\].*$" "$compileroutput" "" compileroutput # Remove lines like # make[3]: Entering directory `/home/carlo/c++/libcwd/testsuite # make[3]: Leaving directory `/home/carlo/c++/libcwd/testsuite regsub -all -line -- "^g*make\\\[\[0-9\]*\\\]:.*ing directory.*$" "$compileroutput" "" compileroutput # Finally remove all new-lines if any: regsub -- "^\[^`'.,!_/a-zA-Z0-9 ():;\]*$" "$compileroutput" "" compileroutput verbose "Filtered compiler output is: `$compileroutput'" if { "$compileroutput" != "" } { fail "$errname compilation" setup_xfail "*-*-*" fail "$errname execution" setup_xfail "*-*-*" fail "$errname output" return; } pass "$errname compilation" set result [libcwd_load $executable "" ""]; set status [lindex $result 0]; set output [lindex $result 1]; # Strip pending new-lines from the output, because we do that also from the expected input. regsub "\n*$" $output "" output $status "$errname execution" if { $status != "pass" } { setup_xfail "*-*-*" fail "$errname output" return; } verbose "resultfile is $resultfile" if ![file exists $resultfile] { return; } set resultid [open $resultfile r]; # Constants set state_parse 1 set state_collectinputlines 2 set state_compare 3 # Initialization set passed 1 set state $state_parse set numberofinputlines 1 set numberofoutputlines 1 if { [regexp -- "regexp_match" $options] } { set regexp_match 1 } else { set regexp_match 0 } # Read first input line set inputline [gets $resultid]; set done [eof $resultid]; # Loop over all input lines while { $done == 0 } { verbose "Entering while loop; state = $state" 2 # Strip newline from input line (if any) regsub "\n" $inputline "" inputline verbose "inputline = \"$inputline\"" # Decode meaning of current input line based on history if { $state == $state_parse } { set inputlines "" # Decode input line if { [regexp -- "^// " $inputline] } { if { "// type regexp" == $inputline } { set regexp_match 1 } if { "// type exact" == $inputline } { set regexp_match 0 } if { [regexp -- "^// input " $inputline] } { if { [regexp -- "^// input lines " $inputline] } { set numberofinputlines [string range $inputline 15 end]; } } if { [regexp -- "^// output " $inputline] } { if { [regexp -- "^// output lines " $inputline] } { set numberofoutputlines [string range $inputline 16 end]; } if { [regexp -- "^// output till " $inputline] } { set numberofoutputlines -1 set matchtill [string range $inputline 15 end]; verbose "matchtill = \"$matchtill\"" } } verbose "numberofinputlines = $numberofinputlines" verbose "numberofoutputlines = $numberofoutputlines" } else { set state $state_collectinputlines } } # Do we need to collect input lines? if { $state == $state_collectinputlines } { append inputlines $inputline set numberofinputlines [expr $numberofinputlines - 1] if { $numberofinputlines == 0 } { set state $state_compare set numberofinputlines 1 } else { append inputlines "\n" } } # Did we collect all input? if { $state == $state_compare } { # Collect output lines that we need to compare this with set outputlines "" set count 0 while { $count != $numberofoutputlines } { # Extract next line from output set index [string first "\n" $output]; verbose "index = $index" 2 if { $index == -1 } { set outputline $output if { $numberofoutputlines == -1 } { set count -1 } else { set output "" } } else { set len [string length $output]; verbose "len = $len" 2 set outputline [string range $output 0 [expr $index - 1]]; if { $numberofoutputlines == -1 && [regexp -- $matchtill $outputline] } { set count -1 } else { set output [string range $output [expr $index + 1] end]; } } verbose "outputline = \"$outputline\"" verbose "output is now \"$output\"" 2 if { $count != -1 } { append outputlines $outputline incr count } if { $count != $numberofoutputlines } { append outputlines "\n" } } verbose "outputlines = \"$outputlines\"" set numberofoutputlines 1 # Do the actual compare if { $regexp_match == 1 } { # Construct regular expression set re "^(" append re $inputlines append re ")$" verbose "expected regular expression is: \"$re\"" if { [regexp -- $re $outputlines] == 0 } { clone_output "expected: \"$re\"" clone_output "got : \"$outputlines\"" set passed 0; set done 1; } } else { if { $inputlines != $outputlines } { clone_output "expected: \"$inputlines\"" clone_output "got : \"$outputlines\"" set passed 0; set done 1; } } set state $state_parse } # Read next input line from file set inputline [gets $resultid]; if { $done == 0 } { set done [eof $resultid]; } } # Did we match everything or is there output left? if { $output != "" } { if { $passed == 1 } { clone_output "output left: \"$output\"" } set passed 0; } # Finish if { $passed == 1 } { pass "$errname output" } else { fail "$errname output" } # Close input file close $resultid; } libcwd-1.0.4/testsuite/config/0000755000175000017500000000000011405442001015227 5ustar carlocarlolibcwd-1.0.4/testsuite/config/unix.exp0000644000175000017500000000003010642737343016743 0ustar carlocarloload_lib "standard.exp" libcwd-1.0.4/testsuite/libcwd.tst/0000755000175000017500000000000011405442001016037 5ustar carlocarlolibcwd-1.0.4/testsuite/libcwd.tst/marker.re0000644000175000017500000000417110643502423017663 0ustar carlocarlo// input lines 3 // output till ^MALLOC ((WARNING : core size is limited.* )*(BFD : Loading debug .* )*) MALLOC : operator new \(size = 12\) = 0x[0-9a-f]* \[marker\.cc:54\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[marker\.cc:59\] // input lines 2 // output till ^MALLOC (WARNING : Object file (/usr/lib/debug)*/lib/libc-2.[.0-9]*.so does not have debug info.* )* MALLOC : New libcwd::marker_ct at 0x[0-9a-f]* MALLOC : operator new\[\] \(size = 120\) = 0x[0-9a-f]* \[marker\.cc:63\] MALLOC : operator new\[\] \(size = 120\) = 0x[0-9a-f]* \[marker\.cc:65\] MALLOC : Allocated memory: (260|268) bytes in 4 blocks\. \(MARKER\) 0x[0-9a-f]* marker\.cc:59 ; \(sz = (8|16)\) A test marker new\[\] 0x[0-9a-f]* marker\.cc:65 int\[30\]; \(sz = 120\) Created after the marker new\[\] 0x[0-9a-f]* marker\.cc:63 Am\[10\]; \(sz = 120\) Created after the marker 0x[0-9a-f]* marker\.cc:54 Am; \(sz = 12\) First created NOTICE : Moving the int array outside of the marker\.\.\. MALLOC : Allocated memory: (260|268) bytes in 4 blocks\. new\[\] 0x[0-9a-f]* marker\.cc:65 int\[30\]; \(sz = 120\) Created after the marker \(MARKER\) 0x[0-9a-f]* marker\.cc:59 ; \(sz = (8|16)\) A test marker new\[\] 0x[0-9a-f]* marker\.cc:63 Am\[10\]; \(sz = 120\) Created after the marker 0x[0-9a-f]* marker\.cc:54 Am; \(sz = 12\) First created MALLOC : Removing libcwd::marker_ct at 0x[0-9a-f]* \(A test marker\) \* WARNING : Memory leak detected! \* new\[\] 0x[0-9a-f]* marker\.cc:63 Am\[10\]; \(sz = 120\) Created after the marker MALLOC : delete 0x[0-9a-f]* marker\.cc:59 ; \(sz = (8|16)\) A test marker MALLOC : delete\[\] 0x[0-9a-f]* marker\.cc:65 int\[30\]; \(sz = 120\) Created after the marker MALLOC : delete\[\] 0x[0-9a-f]* marker\.cc:63 Am\[10\]; \(sz = 120\) Created after the marker MALLOC : delete 0x[0-9a-f]* marker\.cc:54 Am; \(sz = 12\) First created NOTICE : Finished successfully\. libcwd-1.0.4/testsuite/libcwd.tst/dlopen.cc0000644000175000017500000000354611233632030017641 0ustar carlocarlo#include "sys.h" #include #include #include typedef void* (*f_type)(bool); f_type f; MAIN_FUNCTION { PREFIX_CODE Debug( check_configuration() ); #if CWDEBUG_ALLOC && !defined(THREADTEST) int* dummy = new int; // Make sure initialization of libcwd is done. libcwd::make_all_allocations_invisible_except(NULL); // Don't show allocations that are done as part of initialization. #endif Debug( libcw_do.on() ); Debug( dc::malloc.on() ); #if CWDEBUG_LOCATION Debug( dc::bfd.on() ); #endif Debug( dc::notice.on() ); #ifdef STATIC Dout(dc::notice, "You cannot use dlopen in a statically linked application."); #else // !STATIC void* handle; do { #ifdef THREADTEST char const* module_name = "module_r.so"; #else char const* module_name = "module.so"; #endif handle = dlopen(module_name, RTLD_NOW|RTLD_GLOBAL); if (!handle) { if (errno != EAGAIN) { char const* error_str = dlerror(); DoutFatal(dc::fatal, "Failed to load \"" << module_name << "\": " << error_str); } } } while (!handle); #if __GNUC__ == 2 && __GNUC_MINOR__ < 97 char const* sym = "global_test_symbol__Fb"; #else char const* sym = "_Z18global_test_symbolb"; #endif f = (f_type)dlsym(handle, sym); if (!f) { char const* error_str = dlerror(); DoutFatal(dc::fatal, "Failed find function \"" << sym << "\": " << error_str); } void* ptr1 = (*f)(false); void* ptr2 = (*f)(true); Debug( alloc_filter_ct alloc_filter(show_objectfile); alloc_filter.hide_untagged_allocations(); alloc_filter.hide_unknown_locations(); list_allocations_on(libcw_do, alloc_filter) ); free(ptr1); free(ptr2); dlclose(handle); #endif // !STATIC Dout(dc::notice, "Finished"); Debug( dc::malloc.off() ); #if CWDEBUG_ALLOC && !defined(THREADTEST) delete dummy; #endif EXIT(0); } libcwd-1.0.4/testsuite/libcwd.tst/debug.h0000644000175000017500000000075010642737344017323 0ustar carlocarlo#ifndef EXAMPLE_DEBUG_H #define EXAMPLE_DEBUG_H #ifdef CWDEBUG #define DEBUGCHANNELS ::example::debug::channels #include namespace example { namespace debug { namespace channels { namespace dc { using namespace ::libcwd::channels::dc; extern ::libcwd::channel_ct warp; } } } } #else #define Dout(cntrl, data) #define DoutFatal(cntrl, data) LibcwDoutFatal(::std, /*nothing*/, cntrl, data) #define Debug(x) #endif #endif // EXAMPLE_DEBUG_H libcwd-1.0.4/testsuite/libcwd.tst/dc.cc0000644000175000017500000000270610642737344016764 0ustar carlocarlo#include "sys.h" #include "debug.h" namespace example { namespace debug { namespace channels { namespace dc { ::libcwd::channel_ct warp("WARP"); } } } } MAIN_FUNCTION { PREFIX_CODE #if !CWDEBUG_ALLOC || !CWDEBUG_LOCATION DoutFatal(dc::fatal, "Expected Failure."); #endif Debug( check_configuration() ); #if !defined(THREADTEST) && CWDEBUG_ALLOC libcwd::make_all_allocations_invisible_except(NULL); #endif Debug( libcw_do.on() ); Debug( dc::warp.on() ); Debug( dc::notice.on() ); Dout(dc::notice, "Debug channel Test."); Dout(dc::warp, "Custom channel Test."); ForAllDebugChannels( if (debugChannel.is_on()) debugChannel.off() ); Debug( list_channels_on(libcw_do) ); ForAllDebugChannels( while (!debugChannel.is_on()) debugChannel.on() ); Debug( list_channels_on(libcw_do) ); #if CWDEBUG_LOCATION Dout(dc::bfd, "bfd Testing"); #else Dout(dc::notice, "bfd Testing disabled"); #endif Dout(dc::debug, "debug Testing"); Dout(dc::malloc, "malloc Testing"); Dout(dc::notice, "notice Testing"); Dout(dc::system, "system Testing"); Dout(dc::warning, "warning Testing"); Dout( dc::notice|dc::system|dc::warning, "Hello World" ); Debug( dc::notice.off() ); Dout( dc::notice|dc::system|dc::warning, "Hello World" ); Debug( dc::system.off() ); Dout( dc::notice|dc::system|dc::warning, "Hello World" ); Debug( dc::warning.off() ); Dout( dc::notice|dc::system|dc::warning, "Hello World (not)" ); EXIT(0); } libcwd-1.0.4/testsuite/libcwd.tst/alloctag.re0000644000175000017500000000640210642737344020202 0ustar carlocarlo// input lines 3 // output till ^BFD : (Disabled|Loading debug info) ((WARNING : core size is limited.* )*(BFD : Loading debug symbols from.* )*) // input lines 2 // output till ^BFD : Disabled (BFD : Loading debug info from .*/libcwd\.so\.0\.[.0-9]*\.\.\. done )* BFD : Disabled DEBUG : Disabled MALLOC : Enabled NOTICE : Enabled SYSTEM : Enabled WARNING : Enabled // input lines 2 // output till ^MALLOC ((BFD : Loading debug info from .*/libstdc\+\+\.so\.6\.[.0-9]*\.\.\. done|WARNING : Object file .*/libstdc\+\+\.so\.6\.[.0-9]* does not have debug info\. Address lookups inside this object file will result in a function name only, not a source file location\. )*) // input lines 4 // output till ^MALLOC : operator new \(size = 4\) (MALLOC : operator new\[\] \(size = 50\) = (| BFD : Loading debug info from .*/tst_alloctag_s.....\.\.\. done MALLOC : )0x[0-9a-f]* \[alloctag\.cc:62\] ) MALLOC : operator new \(size = 4\) = 0x[0-9a-f]* \[alloctag\.cc:70\] MALLOC : malloc\(33\) = 0x[0-9a-f]* \[alloctag\.cc:73\] MALLOC : malloc\(55\) = 0x[0-9a-f]* \[alloctag\.cc:76\] MALLOC : calloc\(22, 10\) = 0x[0-9a-f]* \[alloctag\.cc:79\] MALLOC : calloc\(55, 10\) = 0x[0-9a-f]* \[alloctag\.cc:82\] MALLOC : malloc\(11\) = 0x[0-9a-f]* \[alloctag\.cc:85\] MALLOC : realloc\(0x[0-9a-f]*, 1000\) = 0x[0-9a-f]* \[alloctag\.cc:88\] MALLOC : malloc\(66\) = 0x[0-9a-f]* \[alloctag\.cc:91\] MALLOC : realloc\(0x[0-9a-f]*, 1000\) = 0x[0-9a-f]* \[alloctag\.cc:94\] MALLOC : Allocated memory: [0-9]* bytes in [8|9] blocks\. realloc 0x[0-9a-f]* alloctag\.cc:94 int\[250\]; \(sz = 1000\) Test of "\(int\*\)realloc\(mpi, 1000\)" realloc 0x[0-9a-f]* alloctag\.cc:88 void\*; \(sz = 1000\) Test of "\(void\*\)realloc\(mp, 1000\)" malloc 0x[0-9a-f]* alloctag\.cc:82 int\[137\]; \(sz = 550\) Test of "\(int\*\)calloc\(55, 10\)" malloc 0x[0-9a-f]* alloctag\.cc:79 void\*; \(sz = 220\) Test of "\(void\*\)calloc\(22, 10\)" malloc 0x[0-9a-f]* alloctag\.cc:76 int\[13\]; \(sz = 55\) Test of "\(int\*\)malloc\(55\)" malloc 0x[0-9a-f]* alloctag\.cc:73 void\*; \(sz = 33\) Test of "\(void\*\)malloc\(33\)" 0x[0-9a-f]* alloctag\.cc:70 int; \(sz = 4\) Test of "new int" new[] 0x[0-9a-f]* alloctag\.cc:62 char\[50\]; \(sz = 50\) Test of "new char\[50\]" MALLOC : delete[] 0x[0-9a-f]* alloctag\.cc:62 char\[50\]; \(sz = 50\) Test of "new char\[50\]" MALLOC : delete 0x[0-9a-f]* alloctag\.cc:70 int; \(sz = 4\) Test of "new int" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:73 void\*; \(sz = 33\) Test of "\(void\*\)malloc\(33\)" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:76 int\[13\]; \(sz = 55\) Test of "\(int\*\)malloc\(55\)" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:79 void\*; \(sz = 220\) Test of "\(void\*\)calloc\(22, 10\)" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:82 int\[137\]; \(sz = 550\) Test of "\(int\*\)calloc\(55, 10\)" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:88 void\*; \(sz = 1000\) Test of "\(void\*\)realloc\(mp, 1000\)" MALLOC : free\(0x[0-9a-f]*\) alloctag\.cc:94 int\[250\]; \(sz = 1000\) Test of "\(int\*\)realloc\(mpi, 1000\)" libcwd-1.0.4/testsuite/libcwd.tst/find_alloc.re0000644000175000017500000000044510642737344020507 0ustar carlocarlo// input lines 3 // output till ^MALLOC ((WARNING : core size is limited.* )*(BFD : Loading debug.* )*) MALLOC : operator new\[\] \(size = 4\) = 0x[0-9a-f]* \[find_alloc\.cc:41\] MALLOC : operator new\[\] \(size = 5\) = 0x[0-9a-f]* \[find_alloc\.cc:42\] NOTICE : Finished successfully. libcwd-1.0.4/testsuite/libcwd.tst/type_info.re0000644000175000017500000000054110642737344020406 0ustar carlocarlo// input lines 3 // output till ^int : 0 ((WARNING : core size is limited.* )*(BFD : Loading debug symbols from.* )*) // type exact int : 0 int* : 4 A : 0 A* : 64 void* : 0 int : 0 int const* : 4 A : 0 A const* : 64 B const& : 0 B const* : 64 void* : 0 A const* A const* const* A const* const* const* B const* B const* const* B const* const* const* libcwd-1.0.4/testsuite/libcwd.tst/leak.re0000644000175000017500000002416010643502266017323 0ustar carlocarlo// input lines 3 // output till ^MALLOC ((WARNING : core size is limited.* )*(BFD : Loading debug .* )*) MALLOC : malloc\(1111\) = 0x[0-9a-f]* \[leak\.cc:89\] MALLOC : malloc\(2222\) = 0x[0-9a-f]* \[leak\.cc:94\] MALLOC : malloc\(3333\) = 0x[0-9a-f]* \[leak\.cc:99\] MALLOC : malloc\(4444\) = 0x[0-9a-f]* \[leak\.cc:104\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[leak\.cc:113\] // input lines 2 // output till ^MALLOC (WARNING : Object file (/usr/lib/debug)*/lib/libc-2.[.0-9]*.so does not have debug info.* )* MALLOC : New libcwd::marker_ct at 0x[0-9a-f]* MALLOC : operator new \(size = (16|32)\) = 0x[0-9a-f]* \[leak\.cc:116\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[leak.cc:53\] MALLOC : malloc\(1212\) = 0x[0-9a-f]* \[leak\.cc:34\] MALLOC : malloc\(7334\) = 0x[0-9a-f]* \[leak\.cc:36\] MALLOC : malloc\(12345\) = 0x[0-9a-f]* \[leak\.cc:55\] MALLOC : malloc\(111\) = 0x[0-9a-f]* \[leak\.cc:57\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[leak\.cc:59\] MALLOC : malloc\(1212\) = 0x[0-9a-f]* \[leak\.cc:34\] MALLOC : malloc\(7334\) = 0x[0-9a-f]* \[leak\.cc:36\] MALLOC : malloc\(5555\) = 0x[0-9a-f]* \[leak\.cc:123\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[leak\.cc:53\] MALLOC : malloc\(1212\) = 0x[0-9a-f]* \[leak\.cc:34\] MALLOC : malloc\(7334\) = 0x[0-9a-f]* \[leak\.cc:36\] MALLOC : malloc\(12345\) = 0x[0-9a-f]* \[leak\.cc:55\] MALLOC : malloc\(111\) = 0x[0-9a-f]* \[leak\.cc:57\] MALLOC : operator new \(size = (8|16)\) = 0x[0-9a-f]* \[leak\.cc:59\] MALLOC : malloc\(1212\) = 0x[0-9a-f]* \[leak.cc:34\] MALLOC : malloc\(7334\) = 0x[0-9a-f]* \[leak\.cc:36\] MALLOC : Allocated memory: (75817|75873) bytes in 23 blocks\. \(MARKER\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:34 void\*; \(sz = 1212\) AA::ptr 0x[0-9a-f]* leak\.cc:59 AA; \(sz = (8|16)\) test_object::b malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:55 void\*; \(sz = 12345\) test_object::ptr malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:34 void\*; \(sz = 1212\) AA::ptr 0x[0-9a-f]* leak\.cc:53 AA; \(sz = (8|16)\) test_object::a malloc 0x[0-9a-f]* leak\.cc:123 void\*; \(sz = 5555\) ptr5 malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:34 void\*; \(sz = 1212\) AA::ptr 0x[0-9a-f]* leak\.cc:59 AA; \(sz = (8|16)\) test_object::b malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:55 void\*; \(sz = 12345\) test_object::ptr malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:34 void\*; \(sz = 1212\) AA::ptr 0x[0-9a-f]* leak\.cc:53 AA; \(sz = (8|16)\) test_object::a 0x[0-9a-f]* leak\.cc:116 test_object; \(sz = (16|32)\) malloc 0x[0-9a-f]* leak\.cc:104 void\*; \(sz = 4444\) ptr4 malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 malloc 0x[0-9a-f]* leak\.cc:89 void\*; \(sz = 1111\) ptr1 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:34 void\*; \(sz = 1212\) AA::ptr MALLOC : delete 0x[0-9a-f]* leak\.cc:59 AA; \(sz = (8|16)\) test_object::b MALLOC : free\(0x[0-9a-f]*\) leak\.cc:55 void\*; \(sz = 12345\) test_object::ptr MALLOC : free\(0x[0-9a-f]*\) leak\.cc:34 void\*; \(sz = 1212\) AA::ptr MALLOC : delete 0x[0-9a-f]* leak\.cc:53 AA; \(sz = (8|16)\) test_object::a MALLOC : free\(0x[0-9a-f]*\) leak\.cc:89 void\*; \(sz = 1111\) ptr1 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:104 void\*; \(sz = 4444\) ptr4 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:34 void\*; \(sz = 1212\) AA::ptr MALLOC : delete 0x[0-9a-f]* leak\.cc:59 AA; \(sz = (8|16)\) test_object::b MALLOC : free\(0x[0-9a-f]*\) leak\.cc:55 void\*; \(sz = 12345\) test_object::ptr MALLOC : free\(0x[0-9a-f]*\) leak\.cc:34 void\*; \(sz = 1212\) AA::ptr MALLOC : delete 0x[0-9a-f]* leak\.cc:53 AA; \(sz = (8|16)\) test_object::a MALLOC : delete 0x[0-9a-f]* leak\.cc:116 test_object; \(sz = (16|32)\) MALLOC : free\(0x[0-9a-f]*\) leak\.cc:123 void\*; \(sz = 5555\) ptr5 MALLOC : Allocated memory: (35121|35129) bytes in 9 blocks\. \(MARKER\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : Removing libcwd::marker_ct at 0x[0-9a-f]* \(test marker\) \* WARNING : Memory leak detected! \* malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA \* malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak \* malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA \* malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA \* malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak \* malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA MALLOC : delete 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker MALLOC : free\(0x[0-9a-f]*\) leak\.cc:57 void\*; \(sz = 111\) test_object::leak MALLOC : Allocated memory: (35010|35018) bytes in 8 blocks\. \(deleted\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA MALLOC : Allocated memory: (27676|27684) bytes in 7 blocks\. \(deleted\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA MALLOC : Allocated memory: (20342|20350) bytes in 6 blocks\. \(deleted\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA MALLOC : Allocated memory: (13008|13016) bytes in 5 blocks\. \(deleted\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:57 void\*; \(sz = 111\) test_object::leak malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:57 void\*; \(sz = 111\) test_object::leak MALLOC : Allocated memory: (12897|12905) bytes in 4 blocks\. \(deleted\) 0x[0-9a-f]* leak\.cc:113 ; \(sz = (8|16)\) test marker malloc 0x[0-9a-f]* leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:36 void\*; \(sz = 7334\) AA::leakAA MALLOC : Allocated memory: 5555 bytes in 2 blocks\. malloc 0x[0-9a-f]* leak\.cc:99 void\*; \(sz = 3333\) ptr3 malloc 0x[0-9a-f]* leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:94 void\*; \(sz = 2222\) ptr2 MALLOC : free\(0x[0-9a-f]*\) leak\.cc:99 void\*; \(sz = 3333\) ptr3 libcwd-1.0.4/testsuite/libcwd.tst/demangler.cc0000644000175000017500000002502010642737344020326 0ustar carlocarlo#ifndef INSTANTIATE #include "sys.h" #include #include #include char const* test_cases [] = { "_ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_", "_ZGVN5libcw24_GLOBAL__N_cbll.cc0ZhUKa23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE", "_ZN6libcwd13cwprint_usingIN5libcw9_private_12GlobalObjectEEENS_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE", "_ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv", "_ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_", "_ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_", "_ZNSbIcSt11char_traitsIcEN6libcwd27no_alloc_checking_allocatorEE12_S_constructIPcEES5_T_S6_RKS2_", "_Z1fI1APS0_PKS0_EvT_T0_T1_PA4_S3_M1CS8_", "_Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_", "_ZSt1BISt1DIP1ARKS2_PS3_ES0_IS2_RS2_PS2_ES2_ET0_T_SB_SA_PT1_", "_ZngILi42EEvN1AIXplT_Li2EEE1TE", "_X11TransParseAddress", "_ZNSt13_Alloc_traitsISbIcSt18string_char_traitsIcEN6libcwd9_private_17allocator_adaptorIcSt24__default_alloc_templateILb0ELi327664EELb1EEEENS4_IS8_S6_Lb1EEEE15_S_instancelessE", "_GLOBAL__I__Z2fnv", "_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_", "_Z1xINiEE", "_Z3fooIA6_KiEvA9_KT_rVPrS4_", "_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE", "_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE", "_Z1fPFYPFiiEiE", "_Z1fI1XENT_1tES2_", "_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE", "_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE", "_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE", "_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE", "_Z4dep9ILi3EEvP3fooIXgtT_Li2EEE" }; MAIN_FUNCTION { PREFIX_CODE Debug( check_configuration() ); Debug( libcw_do.on() ); std::string result; for (size_t i = 0; i < sizeof(test_cases)/sizeof(char const*); ++i) { libcwd::demangle_symbol(test_cases[i], result); #ifndef _REENTRANT std::cout << result << '\n'; #else // We could do this: // // pthread_mutex_lock(&cout_mutex); // std::cout << result << '\n'; // pthread_mutex_unlock(&cout_mutex); // // but that would cause this output to // follow 'continued' debug output and // debug output that uses nonewline_cf // on the same line: // // Thread1&2: NOTICE Loading a file... _X11TransParseAddress // Thread1 : done. // // While using the below will result in the // better readable: // // Thread1 : NOTICE Loading a file... // Thread2 : _X11TransParseAddress // Thread1 : NOTICE done. // // // Or (although the use of nonewline_cf is discouraged in the multi-threaded case!) // // Thread1&2: NOTICE This line does not end on a newline_X11TransParseAddress // Thread1 : , but this does. // // will instead look like: // // Thread1 : NOTICE This line does not end on a newline // Thread2 : _X11TransParseAddress // Thread1 : , but this does. // Dout(dc::always|noprefix_cf, result); #endif result.erase(); } EXIT(0); } #else // INSTANTIATE namespace std { template class allocator { }; template > class vector { public: vector(void); void size(void) const { } }; class ostream { }; template class priority_queue { public: void top(void) const { } }; template > class deque { }; } // _ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_ class libcw_app_ct { public: void dummy(char const*) { } template static void add_option(void (T::*)(char const*), char const*, char, char const*, char const*); }; template void libcw_app_ct::add_option(void (T::*)(char const*), char const*, char, char const*, char const*) { } void fn(void) { // Instantiation. libcw_app_ct::add_option(&libcw_app_ct::dummy, "", '\0', "", ""); } // _ZGVN5libcw16_GLOBAL__N__Z1fv23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE namespace libcw { namespace debug { class memblk_types_manipulator_data_ct { }; } template class omanip_id_tct { }; namespace { template class compiler_bug_workaround { public: static std::vector ids; }; template std::vector compiler_bug_workaround::ids; typedef std::vector > vector_t; compiler_bug_workaround dummy; } } void g(void) { // Instantiation. libcw::dummy.ids.size(); } // _ZN6libcwd13cwprint_usingIN5libcw9_private_12GlobalObjectEEENS_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE namespace libcw { namespace _private_ { class GlobalObject { public: void dummy(std::ostream&) const; }; } } namespace libcwd { template class cwprint_using_tct { }; template cwprint_using_tct cwprint_using(T const&, void (T::*)(std::ostream&) const); } void h(void) { // Instantiation. libcw::_private_::GlobalObject dummy; (void)libcwd::cwprint_using(dummy, &libcw::_private_::GlobalObject::dummy); } // _ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv class timer_event_request_base_ct { }; struct timer_greater { }; void i(void) { // Instantiation. std::priority_queue, timer_greater> dummy; dummy.top(); } // _ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_ struct memory_block_st { }; namespace std { template class _Deque_iterator { public: void operator==(_Deque_iterator const&) const { } }; } void j(void) { // Instantiation. std::_Deque_iterator dummy; dummy.operator==(dummy); } // _ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_ struct option { }; namespace std { template class __normal_iterator { public: void operator-(__normal_iterator const&) const { } }; } void k(void) { // Instantiation. std::__normal_iterator