Merge lp:~aviksil/ubuntu/natty/ltrace/merge-with-upstream into lp:ubuntu/natty/ltrace

Proposed by Avik Sil
Status: Needs review
Proposed branch: lp:~aviksil/ubuntu/natty/ltrace/merge-with-upstream
Merge into: lp:ubuntu/natty/ltrace
Diff against target: 8638 lines (+4047/-2787)
122 files modified
.gitignore (+53/-0)
ChangeLog (+263/-0)
Makefile.am (+106/-0)
Makefile.in (+0/-74)
README (+1/-0)
VERSION (+0/-1)
aclocal.m4 (+0/-833)
autogen.sh (+25/-0)
breakpoints.c (+9/-3)
common.h (+27/-4)
configure (+0/-157)
configure.ac (+272/-0)
debian/changelog (+15/-0)
debian/control (+3/-4)
debian/control.in (+0/-25)
debian/rules (+1/-0)
debug.h (+4/-0)
defs.h (+1/-1)
display_args.c (+7/-7)
elf.c (+0/-619)
elf.h (+0/-49)
etc/ltrace.conf (+1/-0)
execute_program.c (+8/-0)
handle_event.c (+58/-35)
ltrace-elf.c (+827/-0)
ltrace-elf.h (+63/-0)
ltrace.1 (+18/-5)
mkdist (+0/-19)
options.c (+36/-2)
options.h (+19/-12)
output.c (+22/-1)
proc.c (+17/-0)
sysdeps/Makefile.am (+11/-0)
sysdeps/README (+1/-0)
sysdeps/linux-gnu/Makefile (+0/-60)
sysdeps/linux-gnu/Makefile.am (+40/-0)
sysdeps/linux-gnu/alpha/Makefile (+0/-10)
sysdeps/linux-gnu/alpha/Makefile.am (+16/-0)
sysdeps/linux-gnu/arch_syscallent.h (+1/-0)
sysdeps/linux-gnu/arm/Makefile (+0/-10)
sysdeps/linux-gnu/arm/Makefile.am (+18/-0)
sysdeps/linux-gnu/arm/plt.c (+13/-1)
sysdeps/linux-gnu/arm/regs.c (+2/-1)
sysdeps/linux-gnu/arm/trace.c (+2/-2)
sysdeps/linux-gnu/cris/Makefile (+10/-0)
sysdeps/linux-gnu/cris/arch.h (+6/-0)
sysdeps/linux-gnu/cris/plt.c (+12/-0)
sysdeps/linux-gnu/cris/ptrace.h (+1/-0)
sysdeps/linux-gnu/cris/regs.c (+37/-0)
sysdeps/linux-gnu/cris/signalent.h (+32/-0)
sysdeps/linux-gnu/cris/syscallent.h (+325/-0)
sysdeps/linux-gnu/cris/trace.c (+75/-0)
sysdeps/linux-gnu/events.c (+8/-2)
sysdeps/linux-gnu/i386/Makefile (+0/-10)
sysdeps/linux-gnu/i386/Makefile.am (+16/-0)
sysdeps/linux-gnu/ia64/Makefile (+0/-10)
sysdeps/linux-gnu/ia64/Makefile.am (+17/-0)
sysdeps/linux-gnu/m68k/Makefile (+0/-10)
sysdeps/linux-gnu/m68k/Makefile.am (+16/-0)
sysdeps/linux-gnu/mips (+1/-0)
sysdeps/linux-gnu/mipsel/Makefile (+0/-22)
sysdeps/linux-gnu/mipsel/Makefile.am (+20/-0)
sysdeps/linux-gnu/mipsel/mipsel.h (+2/-1)
sysdeps/linux-gnu/mipsel/plt.c (+1/-1)
sysdeps/linux-gnu/mipsel/regs.c (+0/-1)
sysdeps/linux-gnu/mipsel/signalent.h (+32/-32)
sysdeps/linux-gnu/mipsel/syscallent.h (+330/-241)
sysdeps/linux-gnu/mipsel/trace.c (+43/-19)
sysdeps/linux-gnu/mksyscallent_mips (+43/-0)
sysdeps/linux-gnu/ppc/Makefile (+0/-10)
sysdeps/linux-gnu/ppc/Makefile.am (+16/-0)
sysdeps/linux-gnu/ppc/ptrace.h (+15/-0)
sysdeps/linux-gnu/ppc/trace.c (+88/-54)
sysdeps/linux-gnu/proc.c (+248/-0)
sysdeps/linux-gnu/s390/Makefile (+0/-13)
sysdeps/linux-gnu/s390/Makefile.am (+20/-0)
sysdeps/linux-gnu/s390/arch.h (+5/-0)
sysdeps/linux-gnu/s390/trace.c (+9/-2)
sysdeps/linux-gnu/signalent1.h (+1/-0)
sysdeps/linux-gnu/sparc/Makefile (+0/-9)
sysdeps/linux-gnu/sparc/Makefile.am (+16/-0)
sysdeps/linux-gnu/syscallent1.h (+1/-0)
sysdeps/linux-gnu/trace.c (+45/-3)
sysdeps/linux-gnu/x86_64/Makefile (+0/-9)
sysdeps/linux-gnu/x86_64/Makefile.am (+18/-0)
sysdeps/linux-gnu/x86_64/ptrace.h (+13/-0)
sysdeps/linux-gnu/x86_64/trace.c (+101/-61)
sysdeps/sysdep.h (+1/-0)
testsuite/Makefile (+0/-71)
testsuite/Makefile.am (+41/-0)
testsuite/lib/ltrace.exp (+40/-5)
testsuite/ltrace.main/Makefile (+0/-33)
testsuite/ltrace.main/Makefile.am (+37/-0)
testsuite/ltrace.main/main-internal.exp (+3/-3)
testsuite/ltrace.main/main.exp (+5/-5)
testsuite/ltrace.main/parameters-lib.c (+21/-3)
testsuite/ltrace.main/parameters.c (+13/-2)
testsuite/ltrace.main/parameters.conf (+4/-1)
testsuite/ltrace.main/parameters.exp (+34/-22)
testsuite/ltrace.main/signals.exp (+3/-3)
testsuite/ltrace.main/system_calls.exp (+22/-22)
testsuite/ltrace.minor/Makefile (+0/-36)
testsuite/ltrace.minor/Makefile.am (+49/-0)
testsuite/ltrace.minor/attach-process.exp (+4/-4)
testsuite/ltrace.minor/count-record.exp (+15/-18)
testsuite/ltrace.minor/demangle-lib.cpp (+1/-1)
testsuite/ltrace.minor/demangle.exp (+6/-6)
testsuite/ltrace.minor/libdl-simple-lib.c (+4/-0)
testsuite/ltrace.minor/libdl-simple.c (+24/-0)
testsuite/ltrace.minor/libdl-simple.exp (+52/-0)
testsuite/ltrace.minor/print-instruction-pointer.exp (+5/-5)
testsuite/ltrace.minor/time-record-T.exp (+4/-4)
testsuite/ltrace.minor/time-record-tt.exp (+4/-4)
testsuite/ltrace.minor/time-record-ttt.exp (+4/-4)
testsuite/ltrace.minor/trace-clone.exp (+5/-15)
testsuite/ltrace.minor/trace-exec.exp (+10/-19)
testsuite/ltrace.minor/trace-fork.c (+1/-1)
testsuite/ltrace.minor/trace-fork.exp (+23/-18)
testsuite/ltrace.torture/Makefile (+0/-33)
testsuite/ltrace.torture/Makefile.am (+25/-0)
testsuite/ltrace.torture/signals.c (+1/-1)
testsuite/ltrace.torture/signals.exp (+3/-3)
To merge this branch: bzr merge lp:~aviksil/ubuntu/natty/ltrace/merge-with-upstream
Reviewer Review Type Date Requested Status
Steve Langasek Pending
Review via email: mp+53491@code.launchpad.net

Description of the change

Merged the latest upstream available today

To post a comment you must log in.

Unmerged revisions

18. By Avik Sil

* Add memmove prototype to etc/ltrace.conf
* New upstream release
* Support for cris added
* Numerous bugfixes for MIPS, ARM, and PPC
* Support for libunwind and libdl

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.gitignore'
2--- .gitignore 1970-01-01 00:00:00 +0000
3+++ .gitignore 2011-03-15 17:56:13 +0000
4@@ -0,0 +1,53 @@
5+*.la
6+*.so
7+*.lo
8+*.o
9+*.ltrace
10+*~
11+
12+Makefile
13+Makefile.in
14+
15+.deps
16+.dirstamp
17+.libs
18+
19+/aclocal.m4
20+/autom4te.cache
21+/config
22+/config.h
23+/config.h.in
24+/config.log
25+/config.status
26+/configure
27+/libtool
28+/ltrace
29+/ltrace-*.tar.*
30+/stamp-h1
31+
32+site.exp
33+site.bak
34+ltrace.log
35+ltrace.sum
36+testrun.log
37+testrun.sum
38+
39+testsuite/ltrace.main/main
40+testsuite/ltrace.main/main-internal
41+testsuite/ltrace.main/parameters
42+testsuite/ltrace.main/signals
43+testsuite/ltrace.main/system_calls
44+testsuite/ltrace.minor/attach-process
45+testsuite/ltrace.minor/count-record
46+testsuite/ltrace.minor/demangle
47+testsuite/ltrace.minor/libdl-simple
48+testsuite/ltrace.minor/print-instruction-pointer
49+testsuite/ltrace.minor/time-record-T
50+testsuite/ltrace.minor/time-record-tt
51+testsuite/ltrace.minor/time-record-ttt
52+testsuite/ltrace.minor/trace-clone
53+testsuite/ltrace.minor/trace-exec
54+testsuite/ltrace.minor/trace-exec1
55+testsuite/ltrace.minor/trace-fork
56+testsuite/ltrace.torture/signals
57+
58
59=== modified file 'ChangeLog'
60--- ChangeLog 2010-10-01 16:06:14 +0000
61+++ ChangeLog 2011-03-15 17:56:13 +0000
62@@ -1,7 +1,270 @@
63+2011-02-16 Petr Machata <pmachata@redhat.com>
64+
65+ * etc/ltrace.conf: Add memmove.
66+
67+2011-01-06 Joe Damato <ice799@gmail.com>
68+
69+ * New release 0.6.0
70+
71+2010-12-08 Zachary T Welch <zwelch@codesourcery.com>
72+
73+ * configure.ac: Make warning output independent of debug option.
74+ Add option to allow -Werror to be disabled. Switch CFLAGS,
75+ CPPFLAGS, and LDFLAGS to their AM_ variants to allow users to
76+ provide alternate settings during 'make'. Remove -g/-O1/-O2
77+ options from configure script; autoconf sets them appropriately
78+ and the user should be in control of the desired optimizations.
79+ Check elf_hash parameter to see if it is signed/unsigned char,
80+ setting ELF_HASH_TAKES_SIGNED_CHAR as appropriate.
81+ * handle_event.c (handle_breakpoint): Fix regression in
82+ system_calls.exp test on ARMv7a. Also fixes libdl-simple.exp
83+ test on same platform.
84+ * display_args.c, ltrace-elf.[ch], options.[ch],
85+ sysdeps/linux-gnu/{arm/trace,proc,trace}.c: Eliminate warnings
86+ that will cause build to fail with -Werror; these mostly were
87+ changes to avoid signed/unsigned comparisions.
88+ * ltrace-elf.c (in_load_libraries): Use ELF_HASH_TAKES_SIGNED_CHAR
89+
90+2010-12-06 Zachary T Welch <zwelch@codesourcery.com>
91+
92+ * configure.ac: Fix e-mail address.
93+ * testsuite/lib/ltrace.exp: Fix failure reporting string
94+ * ltrace-elf.c, sysdeps/linux-gnu/proc.c: Use portable
95+ format specifiers from inttypes.h
96+ * sysdeps/linux-gnu/trace.c (umovebytes): Remove unused variable
97+ * Makefile.am: Fix distribution of renamed debian/control file.
98+ * testsuite/ltrace.minor/Makefile.am: Include libdl-simple test
99+ in the distribution tarballs.
100+
101+2010-12-04 Joe Damato <ice799@gmail.com>
102+
103+ * debian/control.in: Renamed to debian/control.
104+ * debian/control: Added new build dependencies.
105+ * debian/rules: Added support for autotools.
106+
107+2010-11-19 Petr Machata <pmachata@redhat.com>
108+
109+ * testsuite/ltrace.main/system_calls.exp: On s390x, names of mmap,
110+ fstat and stat system calls are different.
111+
112+2010-11-19 Petr Machata <pmachata@redhat.com>
113+
114+ * testsuite/lib/ltrace.exp (ltrace_verify_output): Add function
115+ argument with grep flavor to use.
116+
117+2010-11-19 Petr Machata <pmachata@redhat.com>
118+
119+ * testsuite/lib/ltrace.exp (ltrace_verify_output): Add function
120+ argument with grep flavor to use.
121+
122+2010-11-18 Petr Machata <pmachata@redhat.com>
123+
124+ * sysdeps/linux-gnu/ppc/ptrace.h (GET_FPREG): New macro.
125+ (proc_archdep): Drop func_args, sysc_args.
126+ * sysdeps/linux-gnu/ppc/trace.c: Use GET_FPREG.
127+
128+2010-11-05 Zachary T Welch <zwelch@codesourcery,com>
129+
130+ * testsuite/: Convert to autotools and add to distribution.
131+ Update test files to allow out-of-tree builds.
132+ * configure.ac: Add maintainer mode, create Makefiles in
133+ testsuite/ tree, improve --with-libunwind configuration
134+ to accept non-standard install path.
135+ * Makefile.am: Don't distribute autogen.sh and .gitignore.
136+ Remove config.h.in during 'make maintainer-clean'
137+ * .gitignore: Exclude test suite build/run artifacts.
138+
139+2010-11-03 Petr Machata <pmachata@redhat.com>
140+
141+ * common.h: Add arch_ptr to callstack_element
142+ * handle_event.c: Move callstack manipulation so that it's around
143+ the output calls--push before output_left, pop after output_right.
144+ (callstack_pop): Free the arch_ptr if it was set.
145+ * sysdeps/linux-gnu/x86_64/ptrace.h: Split the archdep struct to
146+ the proc part and the callstack_element part.
147+ * sysdeps/linux-gnu/x86_64/trace.c (save_register_args): Init
148+ callstack_element.arch_ptr.
149+ (gimme_arg): Use it.
150+
151+2010-11-03 Petr Machata <pmachata@redhat.com>
152+
153+ * testsuite/ltrace.main/parameters.* (func_work, func_call): new
154+ functions for testing nested library calls
155+
156+2010-11-03 Petr Machata <pmachata@redhat.com>
157+
158+ * sysdeps/linux-gnu/x86_64/trace.c: Fix passing and returning
159+ float and double values.
160+ * sysdeps/linux-gnu/x86_64/ptrace.h: Likewise.
161+
162+2010-11-03 Petr Machata <pmachata@redhat.com>
163+
164+ * testsuite/ltrace.main/parameters.* (func_float): now returns
165+ float to test proper decoding of float return values.
166+ (func_double): new function similar to func_float.
167+
168+2010-11-03 Petr Machata <pmachata@redhat.com>
169+
170+ * configure.ac: Don't assume that libelf comes with a .pc file.
171+
172+2010-11-01 Petr Machata <pmachata@redhat.com>
173+
174+ * configure.ac: ${host_cpu} for PPC64 is "powerpc64".
175+
176+2010-11-01 Petr Machata <pmachata@redhat.com>
177+
178+ * configure.ac: ${host_cpu} for PPC64 is "powerpc64".
179+
180+2010-10-31 Joe Damato <ice799@gmail.com>
181+
182+ * Makefile.am: Add autotool support for libunwind.
183+ * configure.ac: Ditto.
184+ * common.h: New structure fields for libunwind.
185+ * execute_program.c: Initialize libunwind.
186+ * proc.c: Ditto.
187+ * options.c: New command line option (-w).
188+ * options.h: New options parameter for libunwind.
189+ * output.c: Use libunwind to do backtraces.
190+
191+2010-10-27 Petr Machata <pmachata@redhat.com>
192+
193+ * ltrace-elf.c (loaddata): Refactored code for loading Elf_Data.
194+ (inside, maybe_pick_section, get_section_covering, read32be): New
195+ functions.
196+ (get_glink_vma): New function, computes .plt glink_vma address on
197+ PPCs.
198+ (do_init_elf): Load DT_PPC_GOT, .plt on PPC.
199+ Use loaddata to load section data.
200+
201+2010-10-25 Petr Machata <pmachata@redhat.com>
202+
203+ * handle_event.c (handle_breakpoint): Do not assume that we can
204+ find the breakpoint by address.
205+
206+2010-10-25 Petr Machata <pmachata@redhat.com>
207+
208+ * sysdeps/linux-gnu/ppc/ptrace.h (proc_archdep): New structure.
209+ * sysdeps/linux-gnu/ppc/trace.c
210+ (get_arch_dep): Initialize proc->arch_ptr.
211+ (gimme_arg_regset, gimme_retval): New functions.
212+ (gimme_arg): Dispatch to gimme_retval or gimme_arg_regset.
213+ (save_register_args): Fill in the stub.
214+
215+2010-10-18 Petr Machata <pmachata@redhat.com>
216+
217+ * sysdeps/linux-gnu/s390/trace.c: Support 5th argument fetching on s390.
218+ Contributed by Supriya Kannery.
219+ * sysdeps/linux-gnu/s390/arch.h: Add support for fork/exec on 390.
220+ * output.c: Cleanup.
221+
222+2010-10-14 Petr Machata <pmachata@redhat.com>
223+
224+ * ltrace.1: Remove claim that only 32-bit binaries are supported.
225+ * testsuite/ltrace.minor/trace-fork.exp: Make fork test suite more accurate
226+
227+2010-10-08 Edgar E. Iglesias <edgar@axis.com>
228+
229+ * sysdeps/linux-gnu/cris/Makefile: New.
230+ * sysdeps/linux-gnu/cris/arch.h: Ditto.
231+ * sysdeps/linux-gnu/cris/plt.c: Ditto.
232+ * sysdeps/linux-gnu/cris/ptrace.h: Ditto.
233+ * sysdeps/linux-gnu/cris/regs.c: Ditto.
234+ * sysdeps/linux-gnu/cris/signalent.h: Ditto.
235+ * sysdeps/linux-gnu/cris/syscallent.h: Ditto.
236+ * sysdeps/linux-gnu/cris/trace.c: Ditto.
237+
238+2010-10-08 Zach Welch <zwelch@codesourcery.com>
239+
240+ * Ensure Thumb mode gets set correct when updating ARM PC.
241+
242+2010-10-08 Zach Welch <zwelch@codesourcery.com>
243+
244+ * Allow ARM PLT lookups to work when containing Thumb stubs.
245+
246+2010-10-07 Zach Welch <zwelch@codesourcery.com>
247+
248+ * Improve breakpoint insertion to work with Thumb procedures.
249+
250 2010-09-30 Zach Welch <zwelch@codesourcery.com>
251
252 * Improve ARM syscall_p to handle Thumb-2 syscalls.
253
254+2010-02-03 Marc Kleine-Budde <mkl@pengutronix.de>
255+
256+ * .gitignore: added git ignore
257+
258+ * Makefile.in, VERSION, aclocal.m4, configure, mkdist,
259+ sysdeps/linux-gnu/Makefile, sysdeps/linux-gnu/alpha/Makefile,
260+ sysdeps/linux-gnu/arm/Makefile, sysdeps/linux-gnu/i386/Makefile,
261+ sysdeps/linux-gnu/ia64/Makefile, sysdeps/linux-gnu/m68k/Makefile,
262+ sysdeps/linux-gnu/mipsel/Makefile, sysdeps/linux-gnu/ppc/Makefile,
263+ sysdeps/linux-gnu/s390/Makefile, sysdeps/linux-gnu/sparc/Makefile,
264+ sysdeps/linux-gnu/x86_64/Makefile: autotoolization: remove to-be
265+ generated file This patch remove all files that will be
266+ autogenerated by the autoools from the tree.
267+
268+ * Makefile.am, autogen.sh, configure.ac, sysdeps/Makefile.am,
269+ sysdeps/linux-gnu/Makefile.am,
270+ sysdeps/linux-gnu/alpha/Makefile.am,
271+ sysdeps/linux-gnu/arch_syscallent.h,
272+ sysdeps/linux-gnu/arm/Makefile.am,
273+ sysdeps/linux-gnu/i386/Makefile.am,
274+ sysdeps/linux-gnu/ia64/Makefile.am,
275+ sysdeps/linux-gnu/m68k/Makefile.am,
276+ sysdeps/linux-gnu/mipsel/Makefile.am,
277+ sysdeps/linux-gnu/ppc/Makefile.am,
278+ sysdeps/linux-gnu/s390/Makefile.am,
279+ sysdeps/linux-gnu/signalent1.h,
280+ sysdeps/linux-gnu/sparc/Makefile.am,
281+ sysdeps/linux-gnu/syscallent1.h,
282+ sysdeps/linux-gnu/x86_64/Makefile.am, sysdeps/sysdep.h:
283+ autotoolization: add basic autotools infrastructure This patch add
284+ a basic autotools infrastructure to ltrace. Native compilation on
285+ i386, x86_64 and ppc. Cross compilation has been tested against
286+ arm.
287+
288+ * common.h, elf.c, elf.h, ltrace-elf.c, ltrace-elf.h: rename
289+ elf.{c,h} into ltrace-elf.{c,h} This patch renames these files to
290+ avoid a conflict with the header files of the "libelfg0-dev"
291+ package. This avoids the "-iquote" magic.
292+
293+2010-01-08 Arnaud Patard <apatard@mandriva.com>
294+
295+ * sysdeps/linux-gnu/mipsel/mipsel.h: Add floating point register offset.
296+ * sysdeps/linux-gnu/x86_64/{ptrace.h, trace.c}: Save a copy of register vlaues and handle floats.
297+ * sysdeps/linux-gnu/mips: Symlink created.
298+ * sysdeps/linux-gnu/mipsel/trace.c: Handle more argument types.
299+ * sysdeps/linux-gnu/trace.c: Don't use PTRACE_SINGLESTEP for MIPS.
300+ * sysdeps/linux-gnu/arm/trace.c: Fix return value.
301+ * handle_event.c: Fix for MIPS.
302+ * sysdeps/linux-gnu/mipsel/{plt.c, regs.c}: Fix includes.
303+ * sysdeps/linux-gnu/mipsetl/syscallent.h: Cleanup.
304+ * sysdeps/linux-gnu/mipsel/signalent.h: Cleanup.
305+ * sysdeps/linux-gnu/trace.c: Fix umovelong.
306+ * .gitignore: New file.
307+ * handle_event.c: abort() when call nesting too deep.
308+ * testsuite/ltrace.minor/count-record.exp: Fix tests.
309+ * handle_event.c: Handle functions which do not increase stack depth.
310+ * testsuite/ltrace.torture/signals.c: Don't use magic numbers.
311+ * testsuite/ltrace.minor/demangle-lib.cpp: Fix build failure.
312+ * sysdeps/linux-gnu/mksyscallent_mips: New file.
313+ * elf.c: Fix '-l' on MIPS.
314+ * debug.h: Add macro guard.
315+ * breakpoints.c: Fix MIPS breakpoints.
316+
317+2009-10-06 Joe Damato <ice799@gmail.com>
318+
319+ * handle_event.c: Do not print signals when -b is used.
320+ * options.h, options.c: A new option (-b) was added.
321+ * ltrace.1: Documentation for -b was added.
322+
323+2009-09-07 Joe Damato <ice799@gmail.com>
324+
325+ * options.c, options.h: A new option (-g) was added.
326+ * ltrace.1: Documentation for -g was added.
327+ * handle_event.c: Do not print when -g is used.
328+ * elf.c: Ditto.
329+
330 2009-07-25 Juan Cespedes <cespedes@debian.org>
331
332 * New release 0.5.3
333
334=== added file 'Makefile.am'
335--- Makefile.am 1970-01-01 00:00:00 +0000
336+++ Makefile.am 2011-03-15 17:56:13 +0000
337@@ -0,0 +1,106 @@
338+SUBDIRS = \
339+ sysdeps \
340+ . \
341+ testsuite
342+
343+AM_CPPFLAGS += \
344+ $(libelf_CFLAGS) \
345+ -DSYSCONFDIR=\"$(sysconfdir)\"
346+
347+noinst_LTLIBRARIES = \
348+ libltrace.la
349+
350+libltrace_la_SOURCES = \
351+ breakpoints.c \
352+ debug.c \
353+ demangle.c \
354+ dict.c \
355+ display_args.c \
356+ ltrace-elf.c \
357+ execute_program.c \
358+ handle_event.c \
359+ libltrace.c \
360+ options.c \
361+ output.c \
362+ proc.c \
363+ read_config_file.c \
364+ summary.c
365+
366+libltrace_la_LIBADD = \
367+ $(libelf_LIBS) \
368+ $(liberty_LIBS) \
369+ $(libsupcxx_LIBS) \
370+ $(libunwind_LIBS) \
371+ $(libunwind_ptrace_LIBS) \
372+ $(libunwind_arch_LIBS) \
373+ sysdeps/libos.la
374+
375+
376+bin_PROGRAMS = \
377+ ltrace
378+
379+ltrace_SOURCES = \
380+ main.c
381+
382+ltrace_LDADD = \
383+ libltrace.la
384+
385+
386+noinst_HEADERS = \
387+ common.h \
388+ debug.h \
389+ defs.h \
390+ demangle.h \
391+ dict.h \
392+ ltrace-elf.h \
393+ ltrace.h \
394+ options.h \
395+ output.h \
396+ read_config_file.h
397+
398+dist_man1_MANS = \
399+ ltrace.1
400+
401+dist_doc_DATA = \
402+ COPYING \
403+ README \
404+ TODO \
405+ BUGS \
406+ ChangeLog
407+
408+dist_sysconf_DATA = \
409+ etc/ltrace.conf
410+
411+EXTRA_DIST = \
412+ ltrace.spec \
413+ debian/changelog \
414+ debian/compat \
415+ debian/control \
416+ debian/copyright \
417+ debian/rules
418+
419+MAINTAINERCLEANFILES = \
420+ configure \
421+ Makefile.in \
422+ aclocal.m4 \
423+ config.h.in \
424+ config.h.in~ \
425+ config/autoconf/compile \
426+ config/autoconf/config.guess \
427+ config/autoconf/config.sub \
428+ config/autoconf/depcomp \
429+ config/autoconf/install-sh \
430+ config/autoconf/ltmain.sh \
431+ config/autoconf/mdate-sh \
432+ config/autoconf/missing \
433+ config/autoconf/texinfo.tex \
434+ libtool.m4 \
435+ ltoptions.m4 \
436+ ltsugar.m4 \
437+ ltversion.m4 \
438+ lt~obsolete.m4 \
439+ $(DIST_ARCHIVES)
440+
441+maintainer-clean-local:
442+ -chmod -R a+rw $(distdir)
443+ -rm -fr $(distdir)
444
445=== removed file 'Makefile.in'
446--- Makefile.in 2009-07-28 16:44:35 +0000
447+++ Makefile.in 1970-01-01 00:00:00 +0000
448@@ -1,74 +0,0 @@
449-#
450-# ltrace's Makefile.in
451-#
452-
453-#OS := $(shell uname -s)
454-OS := @HOST_OS@
455-
456-TOPDIR = $(shell pwd)
457-
458-prefix = @prefix@
459-sysconfdir = @sysconfdir@
460-bindir = $(prefix)/bin
461-mandir = @mandir@
462-docdir = $(prefix)/share/doc/ltrace
463-
464-CC = @CC@
465-CFLAGS = -Wall @CFLAGS@
466-CPPFLAGS = -iquote $(TOPDIR) -iquote $(TOPDIR)/sysdeps/$(OS) -DSYSCONFDIR=\"$(sysconfdir)\" @CPPFLAGS@
467-LDFLAGS = @LDFLAGS@
468-LIBS = @LIBS@
469-
470-INSTALL = @INSTALL@
471-INSTALL_FILE = $(INSTALL) -p -m 644
472-INSTALL_PROGRAM = $(INSTALL) -p -m 755
473-INSTALL_SCRIPT = $(INSTALL) -p -m 755
474-INSTALL_DIR = $(INSTALL) -p -d -m 755
475-
476-OBJ = libltrace.o options.o elf.o output.o read_config_file.o \
477- execute_program.o handle_event.o display_args.o \
478- breakpoints.o proc.o demangle.o dict.o debug.o summary.o
479-
480-VERSION = @PACKAGE_VERSION@
481-
482-all: ltrace
483-
484-ltrace: main.o libltrace.a
485- $(CC) $(LDFLAGS) $^ $(LIBS) -o $@
486-
487-libltrace.a: sysdeps/sysdep.o $(OBJ)
488- $(AR) rcv $@ $^
489-
490-sysdeps/sysdep.o: dummy
491- $(MAKE) -C sysdeps/$(OS)
492-
493-clean-deja:
494- $(RM) testrun.log testrun.sum
495- cd testsuite; make clean
496-
497-clean: clean-deja
498- $(MAKE) -C sysdeps/$(OS) clean
499- rm -f ltrace main.o libltrace.a $(OBJ)
500- rm -f *~ *.bak a.out core
501-
502-distclean: clean
503- rm -f config.h Makefile
504-
505-realclean: distclean
506-
507-install: ltrace
508- $(INSTALL_DIR) $(DESTDIR)$(bindir) $(DESTDIR)$(docdir) $(DESTDIR)$(mandir)/man1
509- $(INSTALL_DIR) $(DESTDIR)$(sysconfdir)
510- $(INSTALL_PROGRAM) ltrace $(DESTDIR)$(bindir)
511- $(INSTALL_FILE) etc/ltrace.conf $(DESTDIR)$(sysconfdir)
512- $(INSTALL_FILE) COPYING README TODO BUGS ChangeLog $(DESTDIR)$(docdir)
513- $(INSTALL_FILE) ltrace.1 $(DESTDIR)$(mandir)/man1
514-
515-check:
516- cd testsuite;cat /proc/version;uptime;free -m;$(MAKE) check
517-
518-dummy:
519-
520-.PHONY: all clean distclean dist install dummy
521-
522-.EXPORT_ALL_VARIABLES:
523
524=== modified file 'README'
525--- README 2009-07-28 16:44:35 +0000
526+++ README 2011-03-15 17:56:13 +0000
527@@ -37,6 +37,7 @@
528 * Ian Wienand <ianw@gelato.unsw.edu.au> (IA64 port)
529 * Eric Vaitl <evaitl@cisco.com> (mipsel port)
530 * Petr Machata <pmachata@redhat.com> (misc fixes)
531+* Joe Damato <ice799@gmail.com> (libdl support, libunwind support)
532
533 1. Introduction
534 ---------------
535
536=== removed file 'VERSION'
537--- VERSION 2009-07-25 16:24:38 +0000
538+++ VERSION 1970-01-01 00:00:00 +0000
539@@ -1,1 +0,0 @@
540-0.5.3
541
542=== removed file 'aclocal.m4'
543--- aclocal.m4 2008-05-27 10:51:22 +0000
544+++ aclocal.m4 1970-01-01 00:00:00 +0000
545@@ -1,833 +0,0 @@
546-dnl aclocal.m4t generated automatically by aclocal 1.4-p6
547-
548-dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
549-dnl This file is free software; the Free Software Foundation
550-dnl gives unlimited permission to copy and/or distribute it,
551-dnl with or without modifications, as long as this notice is preserved.
552-
553-dnl This program is distributed in the hope that it will be useful,
554-dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
555-dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
556-dnl PARTICULAR PURPOSE.
557-
558-# lib-prefix.m4 serial 3 (gettext-0.13)
559-dnl Copyright (C) 2001-2003 Free Software Foundation, Inc.
560-dnl This file is free software, distributed under the terms of the GNU
561-dnl General Public License. As a special exception to the GNU General
562-dnl Public License, this file may be distributed as part of a program
563-dnl that contains a configuration script generated by Autoconf, under
564-dnl the same distribution terms as the rest of that program.
565-
566-dnl From Bruno Haible.
567-
568-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
569-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
570-dnl require excessive bracketing.
571-ifdef([AC_HELP_STRING],
572-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
573-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
574-
575-dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
576-dnl to access previously installed libraries. The basic assumption is that
577-dnl a user will want packages to use other packages he previously installed
578-dnl with the same --prefix option.
579-dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
580-dnl libraries, but is otherwise very convenient.
581-AC_DEFUN([AC_LIB_PREFIX],
582-[
583- AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
584- AC_REQUIRE([AC_PROG_CC])
585- AC_REQUIRE([AC_CANONICAL_HOST])
586- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
587- dnl By default, look in $includedir and $libdir.
588- use_additional=yes
589- AC_LIB_WITH_FINAL_PREFIX([
590- eval additional_includedir=\"$includedir\"
591- eval additional_libdir=\"$libdir\"
592- ])
593- AC_LIB_ARG_WITH([lib-prefix],
594-[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
595- --without-lib-prefix don't search for libraries in includedir and libdir],
596-[
597- if test "X$withval" = "Xno"; then
598- use_additional=no
599- else
600- if test "X$withval" = "X"; then
601- AC_LIB_WITH_FINAL_PREFIX([
602- eval additional_includedir=\"$includedir\"
603- eval additional_libdir=\"$libdir\"
604- ])
605- else
606- additional_includedir="$withval/include"
607- additional_libdir="$withval/lib"
608- fi
609- fi
610-])
611- if test $use_additional = yes; then
612- dnl Potentially add $additional_includedir to $CPPFLAGS.
613- dnl But don't add it
614- dnl 1. if it's the standard /usr/include,
615- dnl 2. if it's already present in $CPPFLAGS,
616- dnl 3. if it's /usr/local/include and we are using GCC on Linux,
617- dnl 4. if it doesn't exist as a directory.
618- if test "X$additional_includedir" != "X/usr/include"; then
619- haveit=
620- for x in $CPPFLAGS; do
621- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
622- if test "X$x" = "X-I$additional_includedir"; then
623- haveit=yes
624- break
625- fi
626- done
627- if test -z "$haveit"; then
628- if test "X$additional_includedir" = "X/usr/local/include"; then
629- if test -n "$GCC"; then
630- case $host_os in
631- linux*) haveit=yes;;
632- esac
633- fi
634- fi
635- if test -z "$haveit"; then
636- if test -d "$additional_includedir"; then
637- dnl Really add $additional_includedir to $CPPFLAGS.
638- CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
639- fi
640- fi
641- fi
642- fi
643- dnl Potentially add $additional_libdir to $LDFLAGS.
644- dnl But don't add it
645- dnl 1. if it's the standard /usr/lib,
646- dnl 2. if it's already present in $LDFLAGS,
647- dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
648- dnl 4. if it doesn't exist as a directory.
649- if test "X$additional_libdir" != "X/usr/lib"; then
650- haveit=
651- for x in $LDFLAGS; do
652- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
653- if test "X$x" = "X-L$additional_libdir"; then
654- haveit=yes
655- break
656- fi
657- done
658- if test -z "$haveit"; then
659- if test "X$additional_libdir" = "X/usr/local/lib"; then
660- if test -n "$GCC"; then
661- case $host_os in
662- linux*) haveit=yes;;
663- esac
664- fi
665- fi
666- if test -z "$haveit"; then
667- if test -d "$additional_libdir"; then
668- dnl Really add $additional_libdir to $LDFLAGS.
669- LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
670- fi
671- fi
672- fi
673- fi
674- fi
675-])
676-
677-dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
678-dnl acl_final_exec_prefix, containing the values to which $prefix and
679-dnl $exec_prefix will expand at the end of the configure script.
680-AC_DEFUN([AC_LIB_PREPARE_PREFIX],
681-[
682- dnl Unfortunately, prefix and exec_prefix get only finally determined
683- dnl at the end of configure.
684- if test "X$prefix" = "XNONE"; then
685- acl_final_prefix="$ac_default_prefix"
686- else
687- acl_final_prefix="$prefix"
688- fi
689- if test "X$exec_prefix" = "XNONE"; then
690- acl_final_exec_prefix='${prefix}'
691- else
692- acl_final_exec_prefix="$exec_prefix"
693- fi
694- acl_save_prefix="$prefix"
695- prefix="$acl_final_prefix"
696- eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
697- prefix="$acl_save_prefix"
698-])
699-
700-dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
701-dnl variables prefix and exec_prefix bound to the values they will have
702-dnl at the end of the configure script.
703-AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
704-[
705- acl_save_prefix="$prefix"
706- prefix="$acl_final_prefix"
707- acl_save_exec_prefix="$exec_prefix"
708- exec_prefix="$acl_final_exec_prefix"
709- $1
710- exec_prefix="$acl_save_exec_prefix"
711- prefix="$acl_save_prefix"
712-])
713-
714-# lib-link.m4 serial 4 (gettext-0.12)
715-dnl Copyright (C) 2001-2003 Free Software Foundation, Inc.
716-dnl This file is free software, distributed under the terms of the GNU
717-dnl General Public License. As a special exception to the GNU General
718-dnl Public License, this file may be distributed as part of a program
719-dnl that contains a configuration script generated by Autoconf, under
720-dnl the same distribution terms as the rest of that program.
721-
722-dnl From Bruno Haible.
723-
724-dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
725-dnl the libraries corresponding to explicit and implicit dependencies.
726-dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
727-dnl augments the CPPFLAGS variable.
728-AC_DEFUN([AC_LIB_LINKFLAGS],
729-[
730- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
731- AC_REQUIRE([AC_LIB_RPATH])
732- define([Name],[translit([$1],[./-], [___])])
733- define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
734- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
735- AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
736- AC_LIB_LINKFLAGS_BODY([$1], [$2])
737- ac_cv_lib[]Name[]_libs="$LIB[]NAME"
738- ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
739- ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
740- ])
741- LIB[]NAME="$ac_cv_lib[]Name[]_libs"
742- LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
743- INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
744- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
745- AC_SUBST([LIB]NAME)
746- AC_SUBST([LTLIB]NAME)
747- dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
748- dnl results of this search when this library appears as a dependency.
749- HAVE_LIB[]NAME=yes
750- undefine([Name])
751- undefine([NAME])
752-])
753-
754-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
755-dnl searches for libname and the libraries corresponding to explicit and
756-dnl implicit dependencies, together with the specified include files and
757-dnl the ability to compile and link the specified testcode. If found, it
758-dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
759-dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
760-dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
761-dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
762-AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
763-[
764- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
765- AC_REQUIRE([AC_LIB_RPATH])
766- define([Name],[translit([$1],[./-], [___])])
767- define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
768- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
769-
770- dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
771- dnl accordingly.
772- AC_LIB_LINKFLAGS_BODY([$1], [$2])
773-
774- dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
775- dnl because if the user has installed lib[]Name and not disabled its use
776- dnl via --without-lib[]Name-prefix, he wants to use it.
777- ac_save_CPPFLAGS="$CPPFLAGS"
778- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
779-
780- AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
781- ac_save_LIBS="$LIBS"
782- LIBS="$LIBS $LIB[]NAME"
783- AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
784- LIBS="$ac_save_LIBS"
785- ])
786- if test "$ac_cv_lib[]Name" = yes; then
787- HAVE_LIB[]NAME=yes
788- AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
789- AC_MSG_CHECKING([how to link with lib[]$1])
790- AC_MSG_RESULT([$LIB[]NAME])
791- else
792- HAVE_LIB[]NAME=no
793- dnl If $LIB[]NAME didn't lead to a usable library, we don't need
794- dnl $INC[]NAME either.
795- CPPFLAGS="$ac_save_CPPFLAGS"
796- LIB[]NAME=
797- LTLIB[]NAME=
798- fi
799- AC_SUBST([HAVE_LIB]NAME)
800- AC_SUBST([LIB]NAME)
801- AC_SUBST([LTLIB]NAME)
802- undefine([Name])
803- undefine([NAME])
804-])
805-
806-dnl Determine the platform dependent parameters needed to use rpath:
807-dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator,
808-dnl hardcode_direct, hardcode_minus_L.
809-AC_DEFUN([AC_LIB_RPATH],
810-[
811- AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
812- AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
813- AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
814- AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
815- AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
816- CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
817- ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
818- . ./conftest.sh
819- rm -f ./conftest.sh
820- acl_cv_rpath=done
821- ])
822- wl="$acl_cv_wl"
823- libext="$acl_cv_libext"
824- shlibext="$acl_cv_shlibext"
825- hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
826- hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
827- hardcode_direct="$acl_cv_hardcode_direct"
828- hardcode_minus_L="$acl_cv_hardcode_minus_L"
829- dnl Determine whether the user wants rpath handling at all.
830- AC_ARG_ENABLE(rpath,
831- [ --disable-rpath do not hardcode runtime library paths],
832- :, enable_rpath=yes)
833-])
834-
835-dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
836-dnl the libraries corresponding to explicit and implicit dependencies.
837-dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
838-AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
839-[
840- define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
841- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
842- dnl By default, look in $includedir and $libdir.
843- use_additional=yes
844- AC_LIB_WITH_FINAL_PREFIX([
845- eval additional_includedir=\"$includedir\"
846- eval additional_libdir=\"$libdir\"
847- ])
848- AC_LIB_ARG_WITH([lib$1-prefix],
849-[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
850- --without-lib$1-prefix don't search for lib$1 in includedir and libdir],
851-[
852- if test "X$withval" = "Xno"; then
853- use_additional=no
854- else
855- if test "X$withval" = "X"; then
856- AC_LIB_WITH_FINAL_PREFIX([
857- eval additional_includedir=\"$includedir\"
858- eval additional_libdir=\"$libdir\"
859- ])
860- else
861- additional_includedir="$withval/include"
862- additional_libdir="$withval/lib"
863- fi
864- fi
865-])
866- dnl Search the library and its dependencies in $additional_libdir and
867- dnl $LDFLAGS. Using breadth-first-seach.
868- LIB[]NAME=
869- LTLIB[]NAME=
870- INC[]NAME=
871- rpathdirs=
872- ltrpathdirs=
873- names_already_handled=
874- names_next_round='$1 $2'
875- while test -n "$names_next_round"; do
876- names_this_round="$names_next_round"
877- names_next_round=
878- for name in $names_this_round; do
879- already_handled=
880- for n in $names_already_handled; do
881- if test "$n" = "$name"; then
882- already_handled=yes
883- break
884- fi
885- done
886- if test -z "$already_handled"; then
887- names_already_handled="$names_already_handled $name"
888- dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
889- dnl or AC_LIB_HAVE_LINKFLAGS call.
890- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
891- eval value=\"\$HAVE_LIB$uppername\"
892- if test -n "$value"; then
893- if test "$value" = yes; then
894- eval value=\"\$LIB$uppername\"
895- test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
896- eval value=\"\$LTLIB$uppername\"
897- test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
898- else
899- dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
900- dnl that this library doesn't exist. So just drop it.
901- :
902- fi
903- else
904- dnl Search the library lib$name in $additional_libdir and $LDFLAGS
905- dnl and the already constructed $LIBNAME/$LTLIBNAME.
906- found_dir=
907- found_la=
908- found_so=
909- found_a=
910- if test $use_additional = yes; then
911- if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
912- found_dir="$additional_libdir"
913- found_so="$additional_libdir/lib$name.$shlibext"
914- if test -f "$additional_libdir/lib$name.la"; then
915- found_la="$additional_libdir/lib$name.la"
916- fi
917- else
918- if test -f "$additional_libdir/lib$name.$libext"; then
919- found_dir="$additional_libdir"
920- found_a="$additional_libdir/lib$name.$libext"
921- if test -f "$additional_libdir/lib$name.la"; then
922- found_la="$additional_libdir/lib$name.la"
923- fi
924- fi
925- fi
926- fi
927- if test "X$found_dir" = "X"; then
928- for x in $LDFLAGS $LTLIB[]NAME; do
929- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
930- case "$x" in
931- -L*)
932- dir=`echo "X$x" | sed -e 's/^X-L//'`
933- if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
934- found_dir="$dir"
935- found_so="$dir/lib$name.$shlibext"
936- if test -f "$dir/lib$name.la"; then
937- found_la="$dir/lib$name.la"
938- fi
939- else
940- if test -f "$dir/lib$name.$libext"; then
941- found_dir="$dir"
942- found_a="$dir/lib$name.$libext"
943- if test -f "$dir/lib$name.la"; then
944- found_la="$dir/lib$name.la"
945- fi
946- fi
947- fi
948- ;;
949- esac
950- if test "X$found_dir" != "X"; then
951- break
952- fi
953- done
954- fi
955- if test "X$found_dir" != "X"; then
956- dnl Found the library.
957- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
958- if test "X$found_so" != "X"; then
959- dnl Linking with a shared library. We attempt to hardcode its
960- dnl directory into the executable's runpath, unless it's the
961- dnl standard /usr/lib.
962- if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
963- dnl No hardcoding is needed.
964- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
965- else
966- dnl Use an explicit option to hardcode DIR into the resulting
967- dnl binary.
968- dnl Potentially add DIR to ltrpathdirs.
969- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
970- haveit=
971- for x in $ltrpathdirs; do
972- if test "X$x" = "X$found_dir"; then
973- haveit=yes
974- break
975- fi
976- done
977- if test -z "$haveit"; then
978- ltrpathdirs="$ltrpathdirs $found_dir"
979- fi
980- dnl The hardcoding into $LIBNAME is system dependent.
981- if test "$hardcode_direct" = yes; then
982- dnl Using DIR/libNAME.so during linking hardcodes DIR into the
983- dnl resulting binary.
984- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
985- else
986- if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
987- dnl Use an explicit option to hardcode DIR into the resulting
988- dnl binary.
989- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
990- dnl Potentially add DIR to rpathdirs.
991- dnl The rpathdirs will be appended to $LIBNAME at the end.
992- haveit=
993- for x in $rpathdirs; do
994- if test "X$x" = "X$found_dir"; then
995- haveit=yes
996- break
997- fi
998- done
999- if test -z "$haveit"; then
1000- rpathdirs="$rpathdirs $found_dir"
1001- fi
1002- else
1003- dnl Rely on "-L$found_dir".
1004- dnl But don't add it if it's already contained in the LDFLAGS
1005- dnl or the already constructed $LIBNAME
1006- haveit=
1007- for x in $LDFLAGS $LIB[]NAME; do
1008- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
1009- if test "X$x" = "X-L$found_dir"; then
1010- haveit=yes
1011- break
1012- fi
1013- done
1014- if test -z "$haveit"; then
1015- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
1016- fi
1017- if test "$hardcode_minus_L" != no; then
1018- dnl FIXME: Not sure whether we should use
1019- dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
1020- dnl here.
1021- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
1022- else
1023- dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH
1024- dnl here, because this doesn't fit in flags passed to the
1025- dnl compiler. So give up. No hardcoding. This affects only
1026- dnl very old systems.
1027- dnl FIXME: Not sure whether we should use
1028- dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
1029- dnl here.
1030- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
1031- fi
1032- fi
1033- fi
1034- fi
1035- else
1036- if test "X$found_a" != "X"; then
1037- dnl Linking with a static library.
1038- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
1039- else
1040- dnl We shouldn't come here, but anyway it's good to have a
1041- dnl fallback.
1042- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
1043- fi
1044- fi
1045- dnl Assume the include files are nearby.
1046- additional_includedir=
1047- case "$found_dir" in
1048- */lib | */lib/)
1049- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
1050- additional_includedir="$basedir/include"
1051- ;;
1052- esac
1053- if test "X$additional_includedir" != "X"; then
1054- dnl Potentially add $additional_includedir to $INCNAME.
1055- dnl But don't add it
1056- dnl 1. if it's the standard /usr/include,
1057- dnl 2. if it's /usr/local/include and we are using GCC on Linux,
1058- dnl 3. if it's already present in $CPPFLAGS or the already
1059- dnl constructed $INCNAME,
1060- dnl 4. if it doesn't exist as a directory.
1061- if test "X$additional_includedir" != "X/usr/include"; then
1062- haveit=
1063- if test "X$additional_includedir" = "X/usr/local/include"; then
1064- if test -n "$GCC"; then
1065- case $host_os in
1066- linux*) haveit=yes;;
1067- esac
1068- fi
1069- fi
1070- if test -z "$haveit"; then
1071- for x in $CPPFLAGS $INC[]NAME; do
1072- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
1073- if test "X$x" = "X-I$additional_includedir"; then
1074- haveit=yes
1075- break
1076- fi
1077- done
1078- if test -z "$haveit"; then
1079- if test -d "$additional_includedir"; then
1080- dnl Really add $additional_includedir to $INCNAME.
1081- INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
1082- fi
1083- fi
1084- fi
1085- fi
1086- fi
1087- dnl Look for dependencies.
1088- if test -n "$found_la"; then
1089- dnl Read the .la file. It defines the variables
1090- dnl dlname, library_names, old_library, dependency_libs, current,
1091- dnl age, revision, installed, dlopen, dlpreopen, libdir.
1092- save_libdir="$libdir"
1093- case "$found_la" in
1094- */* | *\\*) . "$found_la" ;;
1095- *) . "./$found_la" ;;
1096- esac
1097- libdir="$save_libdir"
1098- dnl We use only dependency_libs.
1099- for dep in $dependency_libs; do
1100- case "$dep" in
1101- -L*)
1102- additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
1103- dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
1104- dnl But don't add it
1105- dnl 1. if it's the standard /usr/lib,
1106- dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
1107- dnl 3. if it's already present in $LDFLAGS or the already
1108- dnl constructed $LIBNAME,
1109- dnl 4. if it doesn't exist as a directory.
1110- if test "X$additional_libdir" != "X/usr/lib"; then
1111- haveit=
1112- if test "X$additional_libdir" = "X/usr/local/lib"; then
1113- if test -n "$GCC"; then
1114- case $host_os in
1115- linux*) haveit=yes;;
1116- esac
1117- fi
1118- fi
1119- if test -z "$haveit"; then
1120- haveit=
1121- for x in $LDFLAGS $LIB[]NAME; do
1122- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
1123- if test "X$x" = "X-L$additional_libdir"; then
1124- haveit=yes
1125- break
1126- fi
1127- done
1128- if test -z "$haveit"; then
1129- if test -d "$additional_libdir"; then
1130- dnl Really add $additional_libdir to $LIBNAME.
1131- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
1132- fi
1133- fi
1134- haveit=
1135- for x in $LDFLAGS $LTLIB[]NAME; do
1136- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
1137- if test "X$x" = "X-L$additional_libdir"; then
1138- haveit=yes
1139- break
1140- fi
1141- done
1142- if test -z "$haveit"; then
1143- if test -d "$additional_libdir"; then
1144- dnl Really add $additional_libdir to $LTLIBNAME.
1145- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
1146- fi
1147- fi
1148- fi
1149- fi
1150- ;;
1151- -R*)
1152- dir=`echo "X$dep" | sed -e 's/^X-R//'`
1153- if test "$enable_rpath" != no; then
1154- dnl Potentially add DIR to rpathdirs.
1155- dnl The rpathdirs will be appended to $LIBNAME at the end.
1156- haveit=
1157- for x in $rpathdirs; do
1158- if test "X$x" = "X$dir"; then
1159- haveit=yes
1160- break
1161- fi
1162- done
1163- if test -z "$haveit"; then
1164- rpathdirs="$rpathdirs $dir"
1165- fi
1166- dnl Potentially add DIR to ltrpathdirs.
1167- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
1168- haveit=
1169- for x in $ltrpathdirs; do
1170- if test "X$x" = "X$dir"; then
1171- haveit=yes
1172- break
1173- fi
1174- done
1175- if test -z "$haveit"; then
1176- ltrpathdirs="$ltrpathdirs $dir"
1177- fi
1178- fi
1179- ;;
1180- -l*)
1181- dnl Handle this in the next round.
1182- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
1183- ;;
1184- *.la)
1185- dnl Handle this in the next round. Throw away the .la's
1186- dnl directory; it is already contained in a preceding -L
1187- dnl option.
1188- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
1189- ;;
1190- *)
1191- dnl Most likely an immediate library name.
1192- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
1193- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
1194- ;;
1195- esac
1196- done
1197- fi
1198- else
1199- dnl Didn't find the library; assume it is in the system directories
1200- dnl known to the linker and runtime loader. (All the system
1201- dnl directories known to the linker should also be known to the
1202- dnl runtime loader, otherwise the system is severely misconfigured.)
1203- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
1204- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
1205- fi
1206- fi
1207- fi
1208- done
1209- done
1210- if test "X$rpathdirs" != "X"; then
1211- if test -n "$hardcode_libdir_separator"; then
1212- dnl Weird platform: only the last -rpath option counts, the user must
1213- dnl pass all path elements in one option. We can arrange that for a
1214- dnl single library, but not when more than one $LIBNAMEs are used.
1215- alldirs=
1216- for found_dir in $rpathdirs; do
1217- alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
1218- done
1219- dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl.
1220- acl_save_libdir="$libdir"
1221- libdir="$alldirs"
1222- eval flag=\"$hardcode_libdir_flag_spec\"
1223- libdir="$acl_save_libdir"
1224- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
1225- else
1226- dnl The -rpath options are cumulative.
1227- for found_dir in $rpathdirs; do
1228- acl_save_libdir="$libdir"
1229- libdir="$found_dir"
1230- eval flag=\"$hardcode_libdir_flag_spec\"
1231- libdir="$acl_save_libdir"
1232- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
1233- done
1234- fi
1235- fi
1236- if test "X$ltrpathdirs" != "X"; then
1237- dnl When using libtool, the option that works for both libraries and
1238- dnl executables is -R. The -R options are cumulative.
1239- for found_dir in $ltrpathdirs; do
1240- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
1241- done
1242- fi
1243-])
1244-
1245-dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
1246-dnl unless already present in VAR.
1247-dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
1248-dnl contains two or three consecutive elements that belong together.
1249-AC_DEFUN([AC_LIB_APPENDTOVAR],
1250-[
1251- for element in [$2]; do
1252- haveit=
1253- for x in $[$1]; do
1254- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
1255- if test "X$x" = "X$element"; then
1256- haveit=yes
1257- break
1258- fi
1259- done
1260- if test -z "$haveit"; then
1261- [$1]="${[$1]}${[$1]:+ }$element"
1262- fi
1263- done
1264-])
1265-
1266-# lib-ld.m4 serial 3 (gettext-0.13)
1267-dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
1268-dnl This file is free software, distributed under the terms of the GNU
1269-dnl General Public License. As a special exception to the GNU General
1270-dnl Public License, this file may be distributed as part of a program
1271-dnl that contains a configuration script generated by Autoconf, under
1272-dnl the same distribution terms as the rest of that program.
1273-
1274-dnl Subroutines of libtool.m4,
1275-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
1276-dnl with libtool.m4.
1277-
1278-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
1279-AC_DEFUN([AC_LIB_PROG_LD_GNU],
1280-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
1281-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
1282-case `$LD -v 2>&1 </dev/null` in
1283-*GNU* | *'with BFD'*)
1284- acl_cv_prog_gnu_ld=yes ;;
1285-*)
1286- acl_cv_prog_gnu_ld=no ;;
1287-esac])
1288-with_gnu_ld=$acl_cv_prog_gnu_ld
1289-])
1290-
1291-dnl From libtool-1.4. Sets the variable LD.
1292-AC_DEFUN([AC_LIB_PROG_LD],
1293-[AC_ARG_WITH(gnu-ld,
1294-[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
1295-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
1296-AC_REQUIRE([AC_PROG_CC])dnl
1297-AC_REQUIRE([AC_CANONICAL_HOST])dnl
1298-# Prepare PATH_SEPARATOR.
1299-# The user is always right.
1300-if test "${PATH_SEPARATOR+set}" != set; then
1301- echo "#! /bin/sh" >conf$$.sh
1302- echo "exit 0" >>conf$$.sh
1303- chmod +x conf$$.sh
1304- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
1305- PATH_SEPARATOR=';'
1306- else
1307- PATH_SEPARATOR=:
1308- fi
1309- rm -f conf$$.sh
1310-fi
1311-ac_prog=ld
1312-if test "$GCC" = yes; then
1313- # Check if gcc -print-prog-name=ld gives a path.
1314- AC_MSG_CHECKING([for ld used by GCC])
1315- case $host in
1316- *-*-mingw*)
1317- # gcc leaves a trailing carriage return which upsets mingw
1318- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
1319- *)
1320- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
1321- esac
1322- case $ac_prog in
1323- # Accept absolute paths.
1324- [[\\/]* | [A-Za-z]:[\\/]*)]
1325- [re_direlt='/[^/][^/]*/\.\./']
1326- # Canonicalize the path of ld
1327- ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
1328- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
1329- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
1330- done
1331- test -z "$LD" && LD="$ac_prog"
1332- ;;
1333- "")
1334- # If it fails, then pretend we aren't using GCC.
1335- ac_prog=ld
1336- ;;
1337- *)
1338- # If it is relative, then search for the first ld in PATH.
1339- with_gnu_ld=unknown
1340- ;;
1341- esac
1342-elif test "$with_gnu_ld" = yes; then
1343- AC_MSG_CHECKING([for GNU ld])
1344-else
1345- AC_MSG_CHECKING([for non-GNU ld])
1346-fi
1347-AC_CACHE_VAL(acl_cv_path_LD,
1348-[if test -z "$LD"; then
1349- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
1350- for ac_dir in $PATH; do
1351- test -z "$ac_dir" && ac_dir=.
1352- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
1353- acl_cv_path_LD="$ac_dir/$ac_prog"
1354- # Check to see if the program is GNU ld. I'd rather use --version,
1355- # but apparently some GNU ld's only accept -v.
1356- # Break only if it was the GNU/non-GNU ld that we prefer.
1357- case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
1358- *GNU* | *'with BFD'*)
1359- test "$with_gnu_ld" != no && break ;;
1360- *)
1361- test "$with_gnu_ld" != yes && break ;;
1362- esac
1363- fi
1364- done
1365- IFS="$ac_save_ifs"
1366-else
1367- acl_cv_path_LD="$LD" # Let the user override the test with a path.
1368-fi])
1369-LD="$acl_cv_path_LD"
1370-if test -n "$LD"; then
1371- AC_MSG_RESULT($LD)
1372-else
1373- AC_MSG_RESULT(no)
1374-fi
1375-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
1376-AC_LIB_PROG_LD_GNU
1377-])
1378-
1379
1380=== added file 'autogen.sh'
1381--- autogen.sh 1970-01-01 00:00:00 +0000
1382+++ autogen.sh 2011-03-15 17:56:13 +0000
1383@@ -0,0 +1,25 @@
1384+#!/bin/bash
1385+
1386+set -e
1387+
1388+#
1389+# usage:
1390+#
1391+# banner <target name>
1392+#
1393+banner() {
1394+ echo
1395+ TG=`echo $1 | sed -e "s,/.*/,,g"`
1396+ LINE=`echo $TG |sed -e "s/./-/g"`
1397+ echo $LINE
1398+ echo $TG
1399+ echo $LINE
1400+ echo
1401+}
1402+
1403+banner "autoreconf"
1404+
1405+mkdir -p config/autoconf config/m4
1406+autoreconf --force --install --symlink -Wall || exit $?
1407+
1408+banner "Finished"
1409
1410=== modified file 'breakpoints.c'
1411--- breakpoints.c 2009-07-28 16:44:35 +0000
1412+++ breakpoints.c 2011-03-15 17:56:13 +0000
1413@@ -23,6 +23,12 @@
1414 struct library_symbol *libsym) {
1415 Breakpoint *sbp;
1416
1417+#ifdef __arm__
1418+ int thumb_mode = (int)addr & 1;
1419+ if (thumb_mode)
1420+ addr = (void *)((int)addr & ~1);
1421+#endif
1422+
1423 debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL");
1424 debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr);
1425
1426@@ -43,7 +49,7 @@
1427 sbp->libsym = libsym;
1428 }
1429 #ifdef __arm__
1430- sbp->thumb_mode = proc->thumb_mode;
1431+ sbp->thumb_mode = thumb_mode | proc->thumb_mode;
1432 proc->thumb_mode = 0;
1433 #endif
1434 sbp->enabled++;
1435@@ -123,8 +129,8 @@
1436 continue;
1437 }
1438 debug(2,"inserting bp %p %s",addr,sym->name);
1439- new_sym=malloc(sizeof(*new_sym));
1440- memcpy(new_sym,sym,sizeof(*new_sym));
1441+ new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
1442+ memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
1443 new_sym->next=proc->list_of_symbols;
1444 proc->list_of_symbols=new_sym;
1445 insert_breakpoint(proc, addr, new_sym);
1446
1447=== modified file 'common.h'
1448--- common.h 2009-07-25 16:24:38 +0000
1449+++ common.h 2011-03-15 17:56:13 +0000
1450@@ -1,3 +1,7 @@
1451+#if defined(HAVE_LIBUNWIND)
1452+#include <libunwind.h>
1453+#endif /* defined(HAVE_LIBUNWIND) */
1454+
1455 #include <sys/types.h>
1456 #include <sys/time.h>
1457 #include <stdio.h>
1458@@ -7,7 +11,7 @@
1459 #include "dict.h"
1460 #include "sysdep.h"
1461 #include "debug.h"
1462-#include "elf.h"
1463+#include "ltrace-elf.h"
1464 #include "read_config_file.h"
1465
1466 #if defined HAVE_LIBIBERTY || defined HAVE_LIBSUPC__
1467@@ -145,6 +149,7 @@
1468 int is_syscall;
1469 void * return_addr;
1470 struct timeval time_spent;
1471+ void * arch_ptr;
1472 };
1473
1474 #define MAX_CALLDEPTH 64
1475@@ -171,7 +176,10 @@
1476 struct callstack_element callstack[MAX_CALLDEPTH];
1477 struct library_symbol * list_of_symbols;
1478
1479+ int libdl_hooked;
1480 /* Arch-dependent: */
1481+ void * debug; /* arch-dep process debug struct */
1482+ long debug_state; /* arch-dep debug state */
1483 void * instruction_pointer;
1484 void * stack_pointer; /* To get return addr, args... */
1485 void * return_addr;
1486@@ -186,6 +194,12 @@
1487 /* output: */
1488 enum tof type_being_displayed;
1489
1490+#if defined(HAVE_LIBUNWIND)
1491+ /* libunwind address space */
1492+ unw_addr_space_t unwind_as;
1493+ void *unwind_priv;
1494+#endif /* defined(HAVE_LIBUNWIND) */
1495+
1496 Process * next;
1497 };
1498
1499@@ -222,6 +236,14 @@
1500 extern void show_summary(void);
1501 extern arg_type_info * lookup_prototype(enum arg_type at);
1502
1503+extern void do_init_elf(struct ltelf *lte, const char *filename);
1504+extern void do_close_elf(struct ltelf *lte);
1505+extern int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
1506+extern struct library_symbol *library_symbols;
1507+extern void add_library_symbol(GElf_Addr addr, const char *name,
1508+ struct library_symbol **library_symbolspp,
1509+ enum toplt type_of_plt, int is_weak);
1510+
1511 /* Arch-dependent stuff: */
1512 extern char * pid2name(pid_t pid);
1513 extern void trace_set_options(Process * proc, pid_t pid);
1514@@ -245,9 +267,10 @@
1515 extern void save_register_args(enum tof type, Process * proc);
1516 extern int umovestr(Process * proc, void * addr, int len, void * laddr);
1517 extern int umovelong (Process * proc, void * addr, long * result, arg_type_info * info);
1518+extern size_t umovebytes (Process *proc, void * addr, void * laddr, size_t count);
1519 extern int ffcheck(void * maddr);
1520 extern void * sym2addr(Process *, struct library_symbol *);
1521+extern int linkmap_init(Process *, struct ltelf *);
1522+extern void arch_check_dbg(Process *proc);
1523
1524-#if 0 /* not yet */
1525-extern int umoven(Process * proc, void * addr, int len, void * laddr);
1526-#endif
1527+extern struct ltelf main_lte;
1528
1529=== removed file 'configure'
1530--- configure 2009-07-28 16:44:35 +0000
1531+++ configure 1970-01-01 00:00:00 +0000
1532@@ -1,157 +0,0 @@
1533-#!/bin/sh
1534-
1535-if [ ! -f libltrace.c ]
1536-then
1537- echo "configure: error: cannot find sources (libltrace.c)" 1>&2
1538- exit 1
1539-fi
1540-
1541-echo -n "checking package name... "
1542-PACKAGE_NAME='ltrace'
1543-echo $PACKAGE_NAME
1544-
1545-echo -n "checking $PACKAGE_NAME version... "
1546-PACKAGE_VERSION=$( cat VERSION )
1547-echo $PACKAGE_VERSION
1548-
1549-echo -n "checking HOST_OS... "
1550-HOST_OS=$( uname -s )
1551-if [ "$HOST_OS" = "Linux" ]
1552-then
1553- HOST_OS="linux-gnu"
1554-fi
1555-echo $HOST_OS
1556-
1557-# HAVE_LIBIBERTY
1558-echo -n "checking for cplus_demangle in -liberty... "
1559-cat > conftest.c << EOF
1560-char cplus_demangle();
1561-int main () {
1562- return cplus_demangle();
1563-}
1564-EOF
1565-if gcc conftest.c -liberty 2>/dev/null
1566-then
1567- HAVE_LIBIBERTY=1
1568- echo "yes"
1569-else
1570- unset HAVE_LIBIBERTY
1571- echo "no"
1572-fi
1573-rm -f conftest.c a.out
1574-
1575-# HAVE_LIBSUPC__
1576-echo -n "checking for __cxa_demangle in -lsupc++... "
1577-cat > conftest.c << EOF
1578-char __cxa_demangle();
1579-int main () {
1580- return __cxa_demangle();
1581-}
1582-EOF
1583-if gcc conftest.c -lsupc++ 2>/dev/null
1584-then
1585- HAVE_LIBSUPC__=1
1586- echo "yes"
1587-else
1588- unset HAVE_LIBSUPC__
1589- echo "no"
1590-fi
1591-rm -f conftest.c a.out
1592-
1593-# HAVE_ELF_C_READ_MMAP
1594-echo -n "checking whether elf_begin accepts ELF_C_READ_MMAP... "
1595-cat > conftest.c << EOF
1596-#include <gelf.h>
1597-int main () {
1598- Elf *elf = elf_begin (4, ELF_C_READ_MMAP, 0);
1599- return 0;
1600-}
1601-EOF
1602-if gcc conftest.c 2>/dev/null
1603-then
1604- HAVE_ELF_C_READ_MMAP=1
1605- echo "yes"
1606-else
1607- unset HAVE_ELF_C_READ_MMAP
1608- echo "no"
1609-fi
1610-rm -f conftest.c a.out
1611-
1612-CC=gcc
1613-CPPFLAGS=' -I /usr/include/libelf'
1614-CFLAGS='-g -O2'
1615-LIBS='-lelf -lsupc++ -liberty '
1616-INSTALL='/usr/bin/install -c'
1617-iquote='-iquote '
1618-iquoteend=''
1619-
1620-prefix=/usr/local
1621-sysconfdir='${prefix}/etc'
1622-bindir='${prefix}/bin'
1623-mandir='${prefix}/share/man'
1624-docdir='${prefix}/share/doc/ltrace'
1625-for x_option
1626-do
1627- if test -n "$x_prev"; then
1628- eval $x_prev=\$x_option
1629- x_prev=
1630- continue
1631- fi
1632- case $x_option in
1633- --*=* | *=*)
1634- x_var=`echo $x_option | sed 's/^--//' | sed 's/=.*//'`
1635- x_val=`echo $x_option | sed 's/^.*=//'`
1636- eval $x_var=$x_val
1637- ;;
1638- --*)
1639- x_prev=`echo $x_option | sed 's/^--//'`
1640- ;;
1641- esac
1642-done
1643-
1644-echo "configure: creating Makefile"
1645-#
1646-# Makefile.in -> Makefile
1647-#
1648-x_subst_vars='PACKAGE_VERSION HOST_OS INSTALL CC CPPFLAGS CFLAGS LDFLAGS LIBS iquote iquoteend prefix sysconfdir mandir docdir'
1649-
1650-for i in $x_subst_vars
1651-do
1652- x_val=`eval echo \\"\\$$i\\"`
1653- x_sed="$x_sed
1654-s&@$i@&$x_val&g"
1655-done
1656-
1657-sed "$x_sed" Makefile.in > Makefile
1658-
1659-echo "configure: creating config.h"
1660-#
1661-# config.h
1662-#
1663-exec > config.h
1664-
1665-echo '#define PACKAGE_NAME "ltrace"'
1666-echo '#define PACKAGE_VERSION "'$PACKAGE_VERSION'"'
1667-
1668-if [ "$HAVE_LIBIBERTY" ]
1669-then
1670- echo '#define HAVE_LIBIBERTY 1'
1671-else
1672- echo '#undef HAVE_LIBIBERTY'
1673-fi
1674-
1675-if [ "$HAVE_LIBSUPC__" ]
1676-then
1677- echo '#define HAVE_LIBSUPC__ 1'
1678-else
1679- echo '#undef HAVE_LIBSUPC__'
1680-fi
1681-
1682-if [ "$HAVE_ELF_C_READ_MMAP" ]
1683-then
1684- echo '#define HAVE_ELF_C_READ_MMAP 1'
1685-else
1686- echo '#undef HAVE_ELF_C_READ_MMAP'
1687-fi
1688-
1689-exit 0
1690
1691=== added file 'configure.ac'
1692--- configure.ac 1970-01-01 00:00:00 +0000
1693+++ configure.ac 2011-03-15 17:56:13 +0000
1694@@ -0,0 +1,272 @@
1695+# -*- Autoconf -*-
1696+# Process this file with autoconf to produce a configure script.
1697+AC_PREREQ(2.59)
1698+
1699+AC_INIT([ltrace],[0.6.0],[ltrace-devel@lists.alioth.debian.org])
1700+AC_CONFIG_HEADERS([config.h])
1701+AC_CONFIG_SRCDIR(libltrace.c)
1702+#AC_CONFIG_MACRO_DIR([config/m4])
1703+AC_CONFIG_AUX_DIR([config/autoconf])
1704+AC_CANONICAL_BUILD
1705+AC_CANONICAL_HOST
1706+
1707+case "${host_os}" in
1708+ linux-gnu*) HOST_OS="linux-gnu" ;;
1709+ *) AC_MSG_ERROR([unkown host-os ${host_osx}]) ;;
1710+esac
1711+AC_SUBST(HOST_OS)
1712+
1713+case "${host_cpu}" in
1714+ arm*|sa110) HOST_CPU="arm" ;;
1715+ i?86) HOST_CPU="i386" ;;
1716+ powerpc|powerpc64) HOST_CPU="ppc" ;;
1717+ sun4u|sparc64) HOST_CPU="sparc" ;;
1718+ s390x) HOST_CPU="s390" ;;
1719+ *) HOST_CPU="${host_cpu}" ;;
1720+esac
1721+AC_SUBST(HOST_CPU)
1722+
1723+# Checks for programs.
1724+AC_PROG_CC
1725+AC_PROG_LIBTOOL
1726+# libtool-2: LT_INIT()
1727+AM_INIT_AUTOMAKE([foreign no-exeext dist-bzip2])
1728+AM_MAINTAINER_MODE
1729+
1730+AC_ARG_WITH([libelf],
1731+ AS_HELP_STRING([--with-libelf], [Prefix of libelf headers/library]),
1732+ [case "${withval}" in
1733+ (no)
1734+ AC_MSG_ERROR([*** libelf is a required dependency])
1735+ ;;
1736+ (yes)
1737+ AC_MSG_ERROR([*** --with-libelf requires you to specify a path])
1738+ ;;
1739+ (*)
1740+ AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include"
1741+ AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib"
1742+ libelf_LD_LIBRARY_PATH="${withval}/lib"
1743+ ;;
1744+esac],[])
1745+
1746+# Checks for libraries.
1747+
1748+saved_CPPFLAGS="${CPPFLAGS}"
1749+saved_LDFLAGS="${LDFLAGS}"
1750+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
1751+LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
1752+# libelf
1753+AC_CHECK_HEADERS([elf.h gelf.h],,
1754+ [AC_MSG_ERROR([*** libelf.h or gelf.h not found on your system])]
1755+)
1756+AC_CHECK_LIB([elf], [elf_begin],,
1757+ [AC_MSG_ERROR([*** libelf not found on your system])]
1758+)
1759+CPPFLAGS="${saved_CPPFLAGS}"
1760+LDFLAGS="${saved_LDFLAGS}"
1761+
1762+
1763+# HAVE_LIBIBERTY
1764+AC_CHECK_LIB([iberty], [cplus_demangle], [
1765+ AC_DEFINE([HAVE_LIBIBERTY], [1], [we have libiberty])
1766+ liberty_LIBS="-liberty"], [
1767+ liberty_LIBS=""])
1768+AC_SUBST(liberty_LIBS)
1769+
1770+
1771+# HAVE_LIBSUPC__
1772+AC_CHECK_LIB([supc++], [__cxa_demangle], [
1773+ AC_DEFINE([HAVE_LIBSUPC__], [1], [we have libsupc++])
1774+ libsupcxx_LIBS="-lsupc++"], [
1775+ libsupcxx_LIBS=""])
1776+AC_SUBST(libsupcxx_LIBS)
1777+
1778+
1779+# HAVE_LIBUNWIND
1780+AC_ARG_WITH(libunwind,
1781+ AS_HELP_STRING([--with-libunwind], [Use libunwind frame unwinding support]),
1782+ [case "${withval}" in
1783+ (yes|no) enable_libunwind=$withval;;
1784+ (*) enable_libunwind=yes
1785+ AM_CPPFLAGS="${AM_CPPFLAGS} -I${withval}/include"
1786+ AM_LDFLAGS="${AM_LDFLAGS} -L${withval}/lib"
1787+ libunwind_LD_LIBRARY_PATH="${withval}/lib"
1788+ ;;
1789+esac],[enable_libunwind=maybe])
1790+
1791+saved_CPPFLAGS="${CPPFLAGS}"
1792+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
1793+AC_CHECK_HEADERS([libunwind.h], [have_libunwind_h=yes])
1794+AC_CHECK_HEADERS([libunwind-ptrace.h], [have_libunwind_ptrace_h=yes])
1795+CPPFLAGS="${saved_CPPFLAGS}"
1796+
1797+AC_MSG_CHECKING([whether to use libunwind support])
1798+case "${enable_libunwind}" in
1799+(yes|maybe)
1800+ if test x$have_libunwind_h = xyes -o x$have_libunwind_ptrace_h = xyes; then
1801+ enable_libunwind=yes
1802+ elif test $enable_libunwind = maybe; then
1803+ enable_libunwind=no
1804+ else
1805+ AC_MSG_RESULT([$enable_libunwind])
1806+ AC_MSG_ERROR([libunwind.h or libunwind-ptrace.h cannot be found])
1807+ fi
1808+ ;;
1809+(*) ;;
1810+esac
1811+AC_MSG_RESULT([$enable_libunwind])
1812+
1813+if test x"$enable_libunwind" = xyes; then
1814+ saved_LDFLAGS="${LDFLAGS}"
1815+ LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
1816+ AC_CHECK_LIB(unwind, backtrace, libunwind_LIBS=-lunwind, libunwind_LIBS=)
1817+ AC_SUBST(libunwind_LIBS)
1818+ AC_CHECK_LIB(unwind-ptrace, _UPT_create, libunwind_ptrace_LIBS=-lunwind-ptrace, libunwind_ptrace_LIBS=)
1819+ AC_SUBST(libunwind_ptrace_LIBS)
1820+
1821+ case "${host_cpu}" in
1822+ arm*|sa110) UNWIND_ARCH="arm" ;;
1823+ i?86) UNWIND_ARCH="x86" ;;
1824+ powerpc) UNWIND_ARCH="ppc32" ;;
1825+ ppc64) UNWIND_ARCH="ppc64" ;;
1826+ mips*) UNWIND_ARCH="mips" ;;
1827+ *) UNWIND_ARCH="${host_cpu}" ;;
1828+ esac
1829+
1830+ AC_CHECK_LIB(unwind-${UNWIND_ARCH}, _U${UNWIND_ARCH}_init_remote, libunwind_arch_LIBS=-lunwind-${UNWIND_ARCH}, libunwind_arch_LIBS=)
1831+ AC_SUBST(libunwind_arch_LIBS)
1832+ AC_DEFINE([HAVE_LIBUNWIND], [1], [we have libunwind])
1833+ LDFLAGS="${saved_LDFLAGS}"
1834+fi
1835+
1836+
1837+saved_CPPFLAGS="${CPPFLAGS}"
1838+saved_LDFLAGS="${LDFLAGS}"
1839+CPPFLAGS="${CPPFLAGS} ${AM_CPPFLAGS}"
1840+LDFLAGS="${LDFLAGS} ${AM_LDFLAGS}"
1841+# HAVE_ELF_C_READ_MMAP
1842+AC_MSG_CHECKING([whether elf_begin accepts ELF_C_READ_MMAP])
1843+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <gelf.h>]], [[
1844+int main () {
1845+ Elf *elf = elf_begin(4, ELF_C_READ_MMAP, 0);
1846+ return 0;
1847+}
1848+ ]])],[
1849+ AC_DEFINE([HAVE_ELF_C_READ_MMAP], [1], [we have read mmap support])
1850+ AC_MSG_RESULT([yes])],[
1851+ AC_MSG_RESULT([no])])
1852+
1853+saved_CFLAGS="${CFLAGS}"
1854+CFLAGS="${CFLAGS} -Wall -Werror"
1855+AC_MSG_CHECKING([whether elf_hash takes a signed char string])
1856+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <libelf.h>]], [[
1857+ (void) elf_hash("name");
1858+ ]])],
1859+ [AC_DEFINE([ELF_HASH_TAKES_SIGNED_CHAR], [1],
1860+ [elf_hash() takes signed char])
1861+ AC_MSG_RESULT([yes])],
1862+ [AC_MSG_RESULT([no])])
1863+CFLAGS="${saved_CFLAGS}"
1864+CPPFLAGS="${saved_CPPFLAGS}"
1865+LDFLAGS="${saved_LDFLAGS}"
1866+
1867+AM_CPPFLAGS=" \
1868+ ${AM_CPPFLAGS} \
1869+ -I\$(top_srcdir)/sysdeps/${HOST_OS}/${HOST_CPU} \
1870+ -I\$(top_srcdir)/sysdeps/${HOST_OS} \
1871+ -I\$(top_srcdir)/sysdeps \
1872+ -I\$(top_srcdir) \
1873+"
1874+
1875+# Checks for header files.
1876+AC_CHECK_HEADERS([ \
1877+ fcntl.h \
1878+ limits.h \
1879+ stddef.h \
1880+ stdint.h \
1881+ stdlib.h \
1882+ string.h \
1883+ sys/ioctl.h \
1884+ sys/param.h \
1885+ sys/time.h \
1886+ unistd.h \
1887+])
1888+
1889+# Checks for typedefs, structures, and compiler characteristics.
1890+AC_TYPE_UID_T
1891+AC_C_INLINE
1892+AC_TYPE_PID_T
1893+AC_TYPE_SIZE_T
1894+AC_CHECK_SIZEOF([long])
1895+
1896+
1897+# Checks for library functions.
1898+AC_FUNC_ERROR_AT_LINE
1899+AC_FUNC_FORK
1900+AC_CHECK_FUNCS([ \
1901+ alarm \
1902+ atexit \
1903+ getcwd \
1904+ gettimeofday \
1905+ memset \
1906+ mkdir \
1907+ rmdir \
1908+ strchr \
1909+ strdup \
1910+ strerror \
1911+ strtol \
1912+ strtoul \
1913+])
1914+
1915+
1916+#
1917+# Debugging
1918+#
1919+AC_MSG_CHECKING([whether to enable debugging])
1920+AC_ARG_ENABLE(debug,
1921+ AS_HELP_STRING([--enable-debug], [enable debugging @<:@default=no@:>@]),
1922+ [case "$enableval" in
1923+ y | yes) CONFIG_DEBUG=yes ;;
1924+ *) CONFIG_DEBUG=no ;;
1925+ esac],
1926+ [CONFIG_DEBUG=no])
1927+AC_MSG_RESULT([${CONFIG_DEBUG}])
1928+if test "${CONFIG_DEBUG}" = "yes"; then
1929+ AC_DEFINE(DEBUG, 1, [debugging])
1930+fi
1931+
1932+# Ignore the compiler's warnings at your own risk.
1933+AM_CFLAGS="${AM_CFLAGS} -Wall -Wsign-compare -Wfloat-equal -Wformat-security"
1934+AC_ARG_ENABLE([werror],
1935+ AS_HELP_STRING([--disable-werror], [disable use of -Werror]),
1936+ [enable_werror=$enableval], [enable_werror=yes])
1937+if test x$enable_werror = xyes; then
1938+ AM_CFLAGS="${AM_CFLAGS} -Werror"
1939+fi
1940+
1941+AC_SUBST(AM_CPPFLAGS)
1942+AC_SUBST(AM_CFLAGS)
1943+AC_SUBST(AM_LDFLAGS)
1944+AC_SUBST(libelf_LD_LIBRARY_PATH)
1945+AC_SUBST(libunwind_LD_LIBRARY_PATH)
1946+
1947+AC_CONFIG_FILES([
1948+ Makefile
1949+ sysdeps/Makefile
1950+ sysdeps/linux-gnu/Makefile
1951+ sysdeps/linux-gnu/alpha/Makefile
1952+ sysdeps/linux-gnu/arm/Makefile
1953+ sysdeps/linux-gnu/i386/Makefile
1954+ sysdeps/linux-gnu/ia64/Makefile
1955+ sysdeps/linux-gnu/m68k/Makefile
1956+ sysdeps/linux-gnu/mipsel/Makefile
1957+ sysdeps/linux-gnu/ppc/Makefile
1958+ sysdeps/linux-gnu/s390/Makefile
1959+ sysdeps/linux-gnu/sparc/Makefile
1960+ sysdeps/linux-gnu/x86_64/Makefile
1961+ testsuite/Makefile
1962+ testsuite/ltrace.main/Makefile
1963+ testsuite/ltrace.minor/Makefile
1964+ testsuite/ltrace.torture/Makefile
1965+])
1966+AC_OUTPUT
1967
1968=== modified file 'debian/changelog'
1969--- debian/changelog 2010-11-24 17:58:11 +0000
1970+++ debian/changelog 2011-03-15 17:56:13 +0000
1971@@ -1,3 +1,18 @@
1972+ltrace (0.6-1ubuntu1) natty; urgency=low
1973+
1974+ * Add memmove prototype to etc/ltrace.con
1975+
1976+ -- Avik Sil <avik.sil@linaro.org> Tue, 15 Mar 2011 17:48:04 +0530
1977+
1978+ltrace (0.6-1) unstable; urgency=low
1979+
1980+ * New upstream release
1981+ * Support for cris added
1982+ * Numerous bugfixes for MIPS, ARM, and PPC
1983+ * Support for libunwind and libdl
1984+
1985+ -- Joe Damato <ice799@gmail.com> Fri, 10 Dec 2010 00:41:20 -0800
1986+
1987 ltrace (0.5.3-2.1ubuntu1) natty; urgency=low
1988
1989 * Merge with Debian; remaining changes:
1990
1991=== modified file 'debian/control'
1992--- debian/control 2010-11-24 17:58:11 +0000
1993+++ debian/control 2011-03-15 17:56:13 +0000
1994@@ -1,13 +1,12 @@
1995 Source: ltrace
1996 Section: utils
1997 Priority: optional
1998-Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
1999-XSBC-Original-Maintainer: Juan Cespedes <cespedes@debian.org>
2000+Maintainer: Juan Cespedes <cespedes@debian.org>
2001 Standards-Version: 3.8.2
2002-Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 5), binutils-dev, libelf-dev
2003+Build-Depends: cdbs, debhelper (>= 7), dh-autoreconf, binutils-dev, libelfg0-dev, libunwind7-dev [i386 amd64 ia64]
2004
2005 Package: ltrace
2006-Architecture: i386 arm armeb armel m68k s390 powerpc sparc alpha amd64 ia64 ppc64
2007+Architecture: i386 arm armeb armel s390 powerpc sparc alpha amd64 ia64 ppc64
2008 Depends: ${shlibs:Depends}, ${misc:Depends}
2009 Description: Tracks runtime library calls in dynamically linked programs
2010 ltrace is a debugging program which runs a specified command until it
2011
2012=== removed file 'debian/control.in'
2013--- debian/control.in 2010-11-24 17:58:11 +0000
2014+++ debian/control.in 1970-01-01 00:00:00 +0000
2015@@ -1,25 +0,0 @@
2016-Source: ltrace
2017-Section: utils
2018-Priority: optional
2019-Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
2020-XSBC-Original-Maintainer: Juan Cespedes <cespedes@debian.org>
2021-Maintainer: Juan Cespedes <cespedes@debian.org>
2022-Standards-Version: 3.8.2
2023-Build-Depends: @cdbs@, binutils-dev, libelf-dev
2024-
2025-Package: ltrace
2026-Architecture: i386 arm armeb armel m68k s390 powerpc sparc alpha amd64 ia64 ppc64
2027-Depends: ${shlibs:Depends}, ${misc:Depends}
2028-Description: Tracks runtime library calls in dynamically linked programs
2029- ltrace is a debugging program which runs a specified command until it
2030- exits. While the command is executing, ltrace intercepts and records
2031- the dynamic library calls which are called by
2032- the executed process and the signals received by that process.
2033- It can also intercept and print the system calls executed by the program.
2034- .
2035- The program to be traced need not be recompiled for this, so you can
2036- use it on binaries for which you don't have the source handy.
2037- .
2038- You should install ltrace if you need a sysadmin tool for tracking the
2039- execution of processes.
2040-
2041
2042=== modified file 'debian/rules'
2043--- debian/rules 2009-01-06 17:46:28 +0000
2044+++ debian/rules 2011-03-15 17:56:13 +0000
2045@@ -6,6 +6,7 @@
2046
2047 include /usr/share/cdbs/1/rules/debhelper.mk
2048 include /usr/share/cdbs/1/class/autotools.mk
2049+include /usr/share/cdbs/1/rules/autoreconf.mk
2050
2051 install/ltrace::
2052 rm -f debian/ltrace/usr/share/doc/ltrace/*
2053
2054=== modified file 'debug.h'
2055--- debug.h 2009-07-28 16:44:35 +0000
2056+++ debug.h 2011-03-15 17:56:13 +0000
2057@@ -1,3 +1,6 @@
2058+#ifndef _DEBUG_H
2059+#define _DEBUG_H
2060+
2061 #include <features.h>
2062
2063 /* debug levels:
2064@@ -15,3 +18,4 @@
2065
2066 # define debug(level, expr...) debug_(level, __FILE__, __LINE__, expr)
2067
2068+#endif
2069
2070=== modified file 'defs.h'
2071--- defs.h 2009-07-28 16:44:35 +0000
2072+++ defs.h 2011-03-15 17:56:13 +0000
2073@@ -15,4 +15,4 @@
2074 #define DEFAULT_ARRAYLEN 4 /* default maximum # array elements */
2075 #endif /* (-A switch) */
2076
2077-#define MAX_LIBRARIES 30
2078+#define MAX_LIBRARIES 200
2079
2080=== modified file 'display_args.c'
2081--- display_args.c 2009-07-28 16:44:35 +0000
2082+++ display_args.c 2011-03-15 17:56:13 +0000
2083@@ -15,8 +15,8 @@
2084 static int display_unknown(enum tof type, Process *proc, long value);
2085 static int display_format(enum tof type, Process *proc, int arg_num);
2086
2087-static int string_maxlength = INT_MAX;
2088-static int array_maxlength = INT_MAX;
2089+static size_t string_maxlength = INT_MAX;
2090+static size_t array_maxlength = INT_MAX;
2091
2092 static long
2093 get_length(enum tof type, Process *proc, int len_spec,
2094@@ -59,8 +59,8 @@
2095 void *addr, arg_type_info * info,
2096 void *st, arg_type_info* st_info) {
2097 int len = 0;
2098- int i;
2099- int array_len;
2100+ size_t i;
2101+ size_t array_len;
2102
2103 if (addr == NULL)
2104 return fprintf(options.output, "NULL");
2105@@ -143,7 +143,7 @@
2106 static int
2107 display_enum(enum tof type, Process *proc,
2108 arg_type_info* info, long value) {
2109- int ii;
2110+ size_t ii;
2111 for (ii = 0; ii < info->u.enum_info.entries; ++ii) {
2112 if (info->u.enum_info.values[ii] == value)
2113 return fprintf(options.output, "%s", info->u.enum_info.keys[ii]);
2114@@ -281,7 +281,7 @@
2115 display_string(enum tof type, Process *proc, void *addr,
2116 size_t maxlength) {
2117 unsigned char *str1;
2118- int i;
2119+ size_t i;
2120 int len = 0;
2121
2122 if (!addr) {
2123@@ -328,7 +328,7 @@
2124 void *addr;
2125 unsigned char *str1;
2126 int i;
2127- int len = 0;
2128+ size_t len = 0;
2129 arg_type_info info;
2130
2131 info.type = ARGTYPE_POINTER;
2132
2133=== removed file 'elf.c'
2134--- elf.c 2009-07-28 16:44:35 +0000
2135+++ elf.c 1970-01-01 00:00:00 +0000
2136@@ -1,619 +0,0 @@
2137-# include "config.h"
2138-
2139-#include <endian.h>
2140-#include <errno.h>
2141-#include <error.h>
2142-#include <fcntl.h>
2143-#include <gelf.h>
2144-#include <stdint.h>
2145-#include <stdlib.h>
2146-#include <string.h>
2147-#include <unistd.h>
2148-
2149-#include "common.h"
2150-
2151-static void do_init_elf(struct ltelf *lte, const char *filename);
2152-static void do_close_elf(struct ltelf *lte);
2153-static void add_library_symbol(GElf_Addr addr, const char *name,
2154- struct library_symbol **library_symbolspp,
2155- enum toplt type_of_plt, int is_weak);
2156-static int in_load_libraries(const char *name, struct ltelf *lte);
2157-static GElf_Addr opd2addr(struct ltelf *ltc, GElf_Addr addr);
2158-
2159-#ifdef PLT_REINITALISATION_BP
2160-extern char *PLTs_initialized_by_here;
2161-#endif
2162-
2163-static void
2164-do_init_elf(struct ltelf *lte, const char *filename) {
2165- int i;
2166- GElf_Addr relplt_addr = 0;
2167- size_t relplt_size = 0;
2168-
2169- debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename);
2170- debug(1, "Reading ELF from %s...", filename);
2171-
2172- memset(lte, 0, sizeof(*lte));
2173- lte->fd = open(filename, O_RDONLY);
2174- if (lte->fd == -1)
2175- error(EXIT_FAILURE, errno, "Can't open \"%s\"", filename);
2176-
2177-#ifdef HAVE_ELF_C_READ_MMAP
2178- lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL);
2179-#else
2180- lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL);
2181-#endif
2182-
2183- if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF)
2184- error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename);
2185-
2186- if (gelf_getehdr(lte->elf, &lte->ehdr) == NULL)
2187- error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"",
2188- filename);
2189-
2190- if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN)
2191- error(EXIT_FAILURE, 0,
2192- "\"%s\" is not an ELF executable nor shared library",
2193- filename);
2194-
2195- if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS
2196- || lte->ehdr.e_machine != LT_ELF_MACHINE)
2197-#ifdef LT_ELF_MACHINE2
2198- && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2
2199- || lte->ehdr.e_machine != LT_ELF_MACHINE2)
2200-#endif
2201-#ifdef LT_ELF_MACHINE3
2202- && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3
2203- || lte->ehdr.e_machine != LT_ELF_MACHINE3)
2204-#endif
2205- )
2206- error(EXIT_FAILURE, 0,
2207- "\"%s\" is ELF from incompatible architecture", filename);
2208-
2209- for (i = 1; i < lte->ehdr.e_shnum; ++i) {
2210- Elf_Scn *scn;
2211- GElf_Shdr shdr;
2212- const char *name;
2213-
2214- scn = elf_getscn(lte->elf, i);
2215- if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
2216- error(EXIT_FAILURE, 0,
2217- "Couldn't get section header from \"%s\"",
2218- filename);
2219-
2220- name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name);
2221- if (name == NULL)
2222- error(EXIT_FAILURE, 0,
2223- "Couldn't get section header from \"%s\"",
2224- filename);
2225-
2226- if (shdr.sh_type == SHT_SYMTAB) {
2227- Elf_Data *data;
2228-
2229- lte->symtab = elf_getdata(scn, NULL);
2230- lte->symtab_count = shdr.sh_size / shdr.sh_entsize;
2231- if ((lte->symtab == NULL
2232- || elf_getdata(scn, lte->symtab) != NULL)
2233- && opt_x != NULL)
2234- error(EXIT_FAILURE, 0,
2235- "Couldn't get .symtab data from \"%s\"",
2236- filename);
2237-
2238- scn = elf_getscn(lte->elf, shdr.sh_link);
2239- if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
2240- error(EXIT_FAILURE, 0,
2241- "Couldn't get section header from \"%s\"",
2242- filename);
2243-
2244- data = elf_getdata(scn, NULL);
2245- if (data == NULL || elf_getdata(scn, data) != NULL
2246- || shdr.sh_size != data->d_size || data->d_off)
2247- error(EXIT_FAILURE, 0,
2248- "Couldn't get .strtab data from \"%s\"",
2249- filename);
2250-
2251- lte->strtab = data->d_buf;
2252- } else if (shdr.sh_type == SHT_DYNSYM) {
2253- Elf_Data *data;
2254-
2255- lte->dynsym = elf_getdata(scn, NULL);
2256- lte->dynsym_count = shdr.sh_size / shdr.sh_entsize;
2257- if (lte->dynsym == NULL
2258- || elf_getdata(scn, lte->dynsym) != NULL)
2259- error(EXIT_FAILURE, 0,
2260- "Couldn't get .dynsym data from \"%s\"",
2261- filename);
2262-
2263- scn = elf_getscn(lte->elf, shdr.sh_link);
2264- if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
2265- error(EXIT_FAILURE, 0,
2266- "Couldn't get section header from \"%s\"",
2267- filename);
2268-
2269- data = elf_getdata(scn, NULL);
2270- if (data == NULL || elf_getdata(scn, data) != NULL
2271- || shdr.sh_size != data->d_size || data->d_off)
2272- error(EXIT_FAILURE, 0,
2273- "Couldn't get .dynstr data from \"%s\"",
2274- filename);
2275-
2276- lte->dynstr = data->d_buf;
2277- } else if (shdr.sh_type == SHT_DYNAMIC) {
2278- Elf_Data *data;
2279- size_t j;
2280-
2281- data = elf_getdata(scn, NULL);
2282- if (data == NULL || elf_getdata(scn, data) != NULL)
2283- error(EXIT_FAILURE, 0,
2284- "Couldn't get .dynamic data from \"%s\"",
2285- filename);
2286-
2287- for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
2288- GElf_Dyn dyn;
2289-
2290- if (gelf_getdyn(data, j, &dyn) == NULL)
2291- error(EXIT_FAILURE, 0,
2292- "Couldn't get .dynamic data from \"%s\"",
2293- filename);
2294-#ifdef __mips__
2295-/**
2296- MIPS ABI Supplement:
2297-
2298- DT_PLTGOT This member holds the address of the .got section.
2299-
2300- DT_MIPS_SYMTABNO This member holds the number of entries in the
2301- .dynsym section.
2302-
2303- DT_MIPS_LOCAL_GOTNO This member holds the number of local global
2304- offset table entries.
2305-
2306- DT_MIPS_GOTSYM This member holds the index of the first dyamic
2307- symbol table entry that corresponds to an entry in the gobal offset
2308- table.
2309-
2310- */
2311- if(dyn.d_tag==DT_PLTGOT){
2312- lte->pltgot_addr=dyn.d_un.d_ptr;
2313- }
2314- if(dyn.d_tag==DT_MIPS_LOCAL_GOTNO){
2315- lte->mips_local_gotno=dyn.d_un.d_val;
2316- }
2317- if(dyn.d_tag==DT_MIPS_GOTSYM){
2318- lte->mips_gotsym=dyn.d_un.d_val;
2319- }
2320-#endif // __mips__
2321- if (dyn.d_tag == DT_JMPREL)
2322- relplt_addr = dyn.d_un.d_ptr;
2323- else if (dyn.d_tag == DT_PLTRELSZ)
2324- relplt_size = dyn.d_un.d_val;
2325- }
2326- } else if (shdr.sh_type == SHT_HASH) {
2327- Elf_Data *data;
2328- size_t j;
2329-
2330- lte->hash_type = SHT_HASH;
2331-
2332- data = elf_getdata(scn, NULL);
2333- if (data == NULL || elf_getdata(scn, data) != NULL
2334- || data->d_off || data->d_size != shdr.sh_size)
2335- error(EXIT_FAILURE, 0,
2336- "Couldn't get .hash data from \"%s\"",
2337- filename);
2338-
2339- if (shdr.sh_entsize == 4) {
2340- /* Standard conforming ELF. */
2341- if (data->d_type != ELF_T_WORD)
2342- error(EXIT_FAILURE, 0,
2343- "Couldn't get .hash data from \"%s\"",
2344- filename);
2345- lte->hash = (Elf32_Word *) data->d_buf;
2346- } else if (shdr.sh_entsize == 8) {
2347- /* Alpha or s390x. */
2348- Elf32_Word *dst, *src;
2349- size_t hash_count = data->d_size / 8;
2350-
2351- lte->hash = (Elf32_Word *)
2352- malloc(hash_count * sizeof(Elf32_Word));
2353- if (lte->hash == NULL)
2354- error(EXIT_FAILURE, 0,
2355- "Couldn't convert .hash section from \"%s\"",
2356- filename);
2357- lte->lte_flags |= LTE_HASH_MALLOCED;
2358- dst = lte->hash;
2359- src = (Elf32_Word *) data->d_buf;
2360- if ((data->d_type == ELF_T_WORD
2361- && __BYTE_ORDER == __BIG_ENDIAN)
2362- || (data->d_type == ELF_T_XWORD
2363- && lte->ehdr.e_ident[EI_DATA] ==
2364- ELFDATA2MSB))
2365- ++src;
2366- for (j = 0; j < hash_count; ++j, src += 2)
2367- *dst++ = *src;
2368- } else
2369- error(EXIT_FAILURE, 0,
2370- "Unknown .hash sh_entsize in \"%s\"",
2371- filename);
2372- } else if (shdr.sh_type == SHT_GNU_HASH
2373- && lte->hash == NULL) {
2374- Elf_Data *data;
2375-
2376- lte->hash_type = SHT_GNU_HASH;
2377-
2378- if (shdr.sh_entsize != 0
2379- && shdr.sh_entsize != 4) {
2380- error(EXIT_FAILURE, 0,
2381- ".gnu.hash sh_entsize in \"%s\" should be 4, but is %llu",
2382- filename, shdr.sh_entsize);
2383- }
2384-
2385- data = elf_getdata(scn, NULL);
2386- if (data == NULL || elf_getdata(scn, data) != NULL
2387- || data->d_off || data->d_size != shdr.sh_size)
2388- error(EXIT_FAILURE, 0,
2389- "Couldn't get .gnu.hash data from \"%s\"",
2390- filename);
2391-
2392- lte->hash = (Elf32_Word *) data->d_buf;
2393- } else if (shdr.sh_type == SHT_PROGBITS
2394- || shdr.sh_type == SHT_NOBITS) {
2395- if (strcmp(name, ".plt") == 0) {
2396- lte->plt_addr = shdr.sh_addr;
2397- lte->plt_size = shdr.sh_size;
2398- if (shdr.sh_flags & SHF_EXECINSTR) {
2399- lte->lte_flags |= LTE_PLT_EXECUTABLE;
2400- }
2401- }
2402-#ifdef ARCH_SUPPORTS_OPD
2403- else if (strcmp(name, ".opd") == 0) {
2404- lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
2405- lte->opd_size = shdr.sh_size;
2406- lte->opd = elf_rawdata(scn, NULL);
2407- }
2408-#endif
2409- }
2410- }
2411-
2412- if (lte->dynsym == NULL || lte->dynstr == NULL)
2413- error(EXIT_FAILURE, 0,
2414- "Couldn't find .dynsym or .dynstr in \"%s\"", filename);
2415-
2416- if (!relplt_addr || !lte->plt_addr) {
2417- debug(1, "%s has no PLT relocations", filename);
2418- lte->relplt = NULL;
2419- lte->relplt_count = 0;
2420- } else {
2421- for (i = 1; i < lte->ehdr.e_shnum; ++i) {
2422- Elf_Scn *scn;
2423- GElf_Shdr shdr;
2424-
2425- scn = elf_getscn(lte->elf, i);
2426- if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
2427- error(EXIT_FAILURE, 0,
2428- "Couldn't get section header from \"%s\"",
2429- filename);
2430- if (shdr.sh_addr == relplt_addr
2431- && shdr.sh_size == relplt_size) {
2432- lte->relplt = elf_getdata(scn, NULL);
2433- lte->relplt_count =
2434- shdr.sh_size / shdr.sh_entsize;
2435- if (lte->relplt == NULL
2436- || elf_getdata(scn, lte->relplt) != NULL)
2437- error(EXIT_FAILURE, 0,
2438- "Couldn't get .rel*.plt data from \"%s\"",
2439- filename);
2440- break;
2441- }
2442- }
2443-
2444- if (i == lte->ehdr.e_shnum)
2445- error(EXIT_FAILURE, 0,
2446- "Couldn't find .rel*.plt section in \"%s\"",
2447- filename);
2448-
2449- debug(1, "%s %zd PLT relocations", filename, lte->relplt_count);
2450- }
2451-}
2452-
2453-static void
2454-do_close_elf(struct ltelf *lte) {
2455- debug(DEBUG_FUNCTION, "do_close_elf()");
2456- if (lte->lte_flags & LTE_HASH_MALLOCED)
2457- free((char *)lte->hash);
2458- elf_end(lte->elf);
2459- close(lte->fd);
2460-}
2461-
2462-static void
2463-add_library_symbol(GElf_Addr addr, const char *name,
2464- struct library_symbol **library_symbolspp,
2465- enum toplt type_of_plt, int is_weak) {
2466- struct library_symbol *s;
2467-
2468- debug(DEBUG_FUNCTION, "add_library_symbol()");
2469-
2470- s = malloc(sizeof(struct library_symbol) + strlen(name) + 1);
2471- if (s == NULL)
2472- error(EXIT_FAILURE, errno, "add_library_symbol failed");
2473-
2474- s->needs_init = 1;
2475- s->is_weak = is_weak;
2476- s->plt_type = type_of_plt;
2477- s->next = *library_symbolspp;
2478- s->enter_addr = (void *)(uintptr_t) addr;
2479- s->name = (char *)(s + 1);
2480- strcpy(s->name, name);
2481- *library_symbolspp = s;
2482-
2483- debug(2, "addr: %p, symbol: \"%s\"", (void *)(uintptr_t) addr, name);
2484-}
2485-
2486-/* stolen from elfutils-0.123 */
2487-static unsigned long
2488-private_elf_gnu_hash(const char *name) {
2489- unsigned long h = 5381;
2490- const unsigned char *string = (const unsigned char *)name;
2491- unsigned char c;
2492- for (c = *string; c; c = *++string)
2493- h = h * 33 + c;
2494- return h & 0xffffffff;
2495-}
2496-
2497-static int
2498-in_load_libraries(const char *name, struct ltelf *lte) {
2499- size_t i;
2500- unsigned long hash;
2501- unsigned long gnu_hash;
2502-
2503- if (!library_num)
2504- return 1;
2505-
2506- hash = elf_hash((const unsigned char *)name);
2507- gnu_hash = private_elf_gnu_hash(name);
2508- for (i = 1; i <= library_num; ++i) {
2509- if (lte[i].hash == NULL)
2510- continue;
2511-
2512- if (lte[i].hash_type == SHT_GNU_HASH) {
2513- Elf32_Word * hashbase = lte[i].hash;
2514- Elf32_Word nbuckets = *hashbase++;
2515- Elf32_Word symbias = *hashbase++;
2516- Elf32_Word bitmask_nwords = *hashbase++;
2517- Elf32_Word * buckets;
2518- Elf32_Word * chain_zero;
2519- Elf32_Word bucket;
2520-
2521- // +1 for skipped `shift'
2522- hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords + 1;
2523- buckets = hashbase;
2524- hashbase += nbuckets;
2525- chain_zero = hashbase - symbias;
2526- bucket = buckets[gnu_hash % nbuckets];
2527-
2528- if (bucket != 0) {
2529- const Elf32_Word *hasharr = &chain_zero[bucket];
2530- do
2531- if ((*hasharr & ~1u) == (gnu_hash & ~1u)) {
2532- int symidx = hasharr - chain_zero;
2533- GElf_Sym sym;
2534-
2535- if (gelf_getsym(lte[i].dynsym, symidx, &sym) == NULL)
2536- error(EXIT_FAILURE, 0,
2537- "Couldn't get symbol from .dynsym");
2538-
2539- if (sym.st_value != 0
2540- && sym.st_shndx != SHN_UNDEF
2541- && strcmp(name, lte[i].dynstr + sym.st_name) == 0)
2542- return 1;
2543- }
2544- while ((*hasharr++ & 1u) == 0);
2545- }
2546- } else {
2547- Elf32_Word nbuckets, symndx;
2548- Elf32_Word *buckets, *chain;
2549- nbuckets = lte[i].hash[0];
2550- buckets = &lte[i].hash[2];
2551- chain = &lte[i].hash[2 + nbuckets];
2552-
2553- for (symndx = buckets[hash % nbuckets];
2554- symndx != STN_UNDEF; symndx = chain[symndx]) {
2555- GElf_Sym sym;
2556-
2557- if (gelf_getsym(lte[i].dynsym, symndx, &sym) == NULL)
2558- error(EXIT_FAILURE, 0,
2559- "Couldn't get symbol from .dynsym");
2560-
2561- if (sym.st_value != 0
2562- && sym.st_shndx != SHN_UNDEF
2563- && strcmp(name, lte[i].dynstr + sym.st_name) == 0)
2564- return 1;
2565- }
2566- }
2567- }
2568- return 0;
2569-}
2570-
2571-static GElf_Addr
2572-opd2addr(struct ltelf *lte, GElf_Addr addr) {
2573-#ifdef ARCH_SUPPORTS_OPD
2574- unsigned long base, offset;
2575-
2576- if (!lte->opd)
2577- return addr;
2578-
2579- base = (unsigned long)lte->opd->d_buf;
2580- offset = (unsigned long)addr - (unsigned long)lte->opd_addr;
2581- if (offset > lte->opd_size)
2582- error(EXIT_FAILURE, 0, "static plt not in .opd");
2583-
2584- return *(GElf_Addr*)(base + offset);
2585-#else //!ARCH_SUPPORTS_OPD
2586- return addr;
2587-#endif
2588-}
2589-
2590-struct library_symbol *
2591-read_elf(Process *proc) {
2592- struct library_symbol *library_symbols = NULL;
2593- struct ltelf lte[MAX_LIBRARIES + 1];
2594- size_t i;
2595- struct opt_x_t *xptr;
2596- struct library_symbol **lib_tail = NULL;
2597- int exit_out = 0;
2598-
2599- debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename);
2600-
2601- elf_version(EV_CURRENT);
2602-
2603- do_init_elf(lte, proc->filename);
2604- proc->e_machine = lte->ehdr.e_machine;
2605- for (i = 0; i < library_num; ++i)
2606- do_init_elf(&lte[i + 1], library[i]);
2607-#ifdef __mips__
2608- // MIPS doesn't use the PLT and the GOT entries get changed
2609- // on startup.
2610- proc->need_to_reinitialize_breakpoints = 1;
2611- for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){
2612- GElf_Sym sym;
2613- const char *name;
2614- GElf_Addr addr = arch_plt_sym_val(lte, i, 0);
2615- if (gelf_getsym(lte->dynsym, i, &sym) == NULL){
2616- error(EXIT_FAILURE, 0,
2617- "Couldn't get relocation from \"%s\"",
2618- proc->filename);
2619- }
2620- name=lte->dynstr+sym.st_name;
2621- if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){
2622- debug(2,"sym %s not a function",name);
2623- continue;
2624- }
2625- add_library_symbol(addr, name, &library_symbols, 0,
2626- ELF64_ST_BIND(sym.st_info) != 0);
2627- if (!lib_tail)
2628- lib_tail = &(library_symbols->next);
2629- }
2630-#else
2631- for (i = 0; i < lte->relplt_count; ++i) {
2632- GElf_Rel rel;
2633- GElf_Rela rela;
2634- GElf_Sym sym;
2635- GElf_Addr addr;
2636- void *ret;
2637- const char *name;
2638-
2639- if (lte->relplt->d_type == ELF_T_REL) {
2640- ret = gelf_getrel(lte->relplt, i, &rel);
2641- rela.r_offset = rel.r_offset;
2642- rela.r_info = rel.r_info;
2643- rela.r_addend = 0;
2644- } else
2645- ret = gelf_getrela(lte->relplt, i, &rela);
2646-
2647- if (ret == NULL
2648- || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
2649- || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
2650- &sym) == NULL)
2651- error(EXIT_FAILURE, 0,
2652- "Couldn't get relocation from \"%s\"",
2653- proc->filename);
2654-
2655-#ifdef PLT_REINITALISATION_BP
2656- if (!sym.st_value && PLTs_initialized_by_here)
2657- proc->need_to_reinitialize_breakpoints = 1;
2658-#endif
2659-
2660- name = lte->dynstr + sym.st_name;
2661- if (in_load_libraries(name, lte)) {
2662- addr = arch_plt_sym_val(lte, i, &rela);
2663- add_library_symbol(addr, name, &library_symbols,
2664- (PLTS_ARE_EXECUTABLE(lte)
2665- ? LS_TOPLT_EXEC : LS_TOPLT_POINT),
2666- ELF64_ST_BIND(sym.st_info) == STB_WEAK);
2667- if (!lib_tail)
2668- lib_tail = &(library_symbols->next);
2669- }
2670- }
2671-#endif // !__mips__
2672-#ifdef PLT_REINITALISATION_BP
2673- struct opt_x_t *main_cheat;
2674-
2675- if (proc->need_to_reinitialize_breakpoints) {
2676- /* Add "PLTs_initialized_by_here" to opt_x list, if not
2677- already there. */
2678- main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t));
2679- if (main_cheat == NULL)
2680- error(EXIT_FAILURE, 0, "Couldn't allocate memory");
2681- main_cheat->next = opt_x;
2682- main_cheat->found = 0;
2683- main_cheat->name = PLTs_initialized_by_here;
2684-
2685- for (xptr = opt_x; xptr; xptr = xptr->next)
2686- if (strcmp(xptr->name, PLTs_initialized_by_here) == 0
2687- && main_cheat) {
2688- free(main_cheat);
2689- main_cheat = NULL;
2690- break;
2691- }
2692- if (main_cheat)
2693- opt_x = main_cheat;
2694- }
2695-#endif
2696-
2697- for (i = 0; i < lte->symtab_count; ++i) {
2698- GElf_Sym sym;
2699- GElf_Addr addr;
2700- const char *name;
2701-
2702- if (gelf_getsym(lte->symtab, i, &sym) == NULL)
2703- error(EXIT_FAILURE, 0,
2704- "Couldn't get symbol from \"%s\"",
2705- proc->filename);
2706-
2707- name = lte->strtab + sym.st_name;
2708- addr = sym.st_value;
2709- if (!addr)
2710- continue;
2711-
2712- for (xptr = opt_x; xptr; xptr = xptr->next)
2713- if (xptr->name && strcmp(xptr->name, name) == 0) {
2714- /* FIXME: Should be able to use &library_symbols as above. But
2715- when you do, none of the real library symbols cause breaks. */
2716- add_library_symbol(opd2addr(lte, addr),
2717- name, lib_tail, LS_TOPLT_NONE, 0);
2718- xptr->found = 1;
2719- break;
2720- }
2721- }
2722- for (xptr = opt_x; xptr; xptr = xptr->next)
2723- if ( ! xptr->found) {
2724- char *badthing = "WARNING";
2725-#ifdef PLT_REINITALISATION_BP
2726- if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
2727- if (lte->ehdr.e_entry) {
2728- add_library_symbol (
2729- opd2addr (lte, lte->ehdr.e_entry),
2730- PLTs_initialized_by_here,
2731- lib_tail, 1, 0);
2732- fprintf (stderr, "WARNING: Using e_ent"
2733- "ry from elf header (%p) for "
2734- "address of \"%s\"\n", (void*)
2735- (long) lte->ehdr.e_entry,
2736- PLTs_initialized_by_here);
2737- continue;
2738- }
2739- badthing = "ERROR";
2740- exit_out = 1;
2741- }
2742-#endif
2743- fprintf (stderr,
2744- "%s: Couldn't find symbol \"%s\" in file \"%s"
2745- "\"\n", badthing, xptr->name, proc->filename);
2746- }
2747- if (exit_out) {
2748- exit (1);
2749- }
2750-
2751- for (i = 0; i < library_num + 1; ++i)
2752- do_close_elf(&lte[i]);
2753-
2754- return library_symbols;
2755-}
2756
2757=== removed file 'elf.h'
2758--- elf.h 2009-07-28 16:44:35 +0000
2759+++ elf.h 1970-01-01 00:00:00 +0000
2760@@ -1,49 +0,0 @@
2761-#ifndef LTRACE_ELF_H
2762-#define LTRACE_ELF_H
2763-
2764-#include <gelf.h>
2765-#include <stdlib.h>
2766-
2767-struct ltelf {
2768- int fd;
2769- Elf *elf;
2770- GElf_Ehdr ehdr;
2771- Elf_Data *dynsym;
2772- size_t dynsym_count;
2773- const char *dynstr;
2774- GElf_Addr plt_addr;
2775- size_t plt_size;
2776- Elf_Data *relplt;
2777- size_t relplt_count;
2778- Elf_Data *symtab;
2779- const char *strtab;
2780- size_t symtab_count;
2781- Elf_Data *opd;
2782- GElf_Addr *opd_addr;
2783- size_t opd_size;
2784- Elf32_Word *hash;
2785- int hash_type;
2786- int lte_flags;
2787-#ifdef __mips__
2788- size_t pltgot_addr;
2789- size_t mips_local_gotno;
2790- size_t mips_gotsym;
2791-#endif // __mips__
2792-};
2793-
2794-#define LTE_HASH_MALLOCED 1
2795-#define LTE_PLT_EXECUTABLE 2
2796-
2797-#define PLTS_ARE_EXECUTABLE(lte) ((lte->lte_flags & LTE_PLT_EXECUTABLE) != 0)
2798-
2799-extern int library_num;
2800-extern char *library[MAX_LIBRARIES];
2801-
2802-extern struct library_symbol *read_elf(Process *);
2803-
2804-extern GElf_Addr arch_plt_sym_val(struct ltelf *, size_t, GElf_Rela *);
2805-
2806-#ifndef SHT_GNU_HASH
2807-#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
2808-#endif
2809-#endif
2810
2811=== modified file 'etc/ltrace.conf'
2812--- etc/ltrace.conf 2009-01-06 17:46:28 +0000
2813+++ etc/ltrace.conf 2011-03-15 17:56:13 +0000
2814@@ -317,6 +317,7 @@
2815 string index(string,char);
2816 addr memchr(string,char,ulong);
2817 addr memcpy(addr,string3,ulong);
2818+addr memmove(addr,string3,ulong);
2819 addr memset(addr,char,long);
2820 string rindex(string,char);
2821 addr stpcpy(addr,string);
2822
2823=== modified file 'execute_program.c'
2824--- execute_program.c 2009-07-28 16:44:35 +0000
2825+++ execute_program.c 2011-03-15 17:56:13 +0000
2826@@ -1,5 +1,9 @@
2827 #include "config.h"
2828
2829+#if defined(HAVE_LIBUNWIND)
2830+#include <libunwind-ptrace.h>
2831+#endif /* defined(HAVE_LIBUNWIND) */
2832+
2833 #include <stdio.h>
2834 #include <stdlib.h>
2835 #include <sys/types.h>
2836@@ -87,5 +91,9 @@
2837
2838 sp->pid = pid;
2839
2840+#if defined(HAVE_LIBUNWIND)
2841+ sp->unwind_priv = _UPT_create(pid);
2842+#endif /* defined(HAVE_LIBUNWIND) */
2843+
2844 return;
2845 }
2846
2847=== modified file 'handle_event.c'
2848--- handle_event.c 2009-07-25 16:24:38 +0000
2849+++ handle_event.c 2011-03-15 17:56:13 +0000
2850@@ -330,7 +330,7 @@
2851 remove_proc(event->proc);
2852 return;
2853 }
2854- if (event->proc->state != STATE_IGNORED) {
2855+ if (event->proc->state != STATE_IGNORED && !options.no_signals) {
2856 output_line(event->proc, "--- %s (%s) ---",
2857 shortsignal(event->proc, event->e_un.signum),
2858 strsignal(event->e_un.signum));
2859@@ -386,14 +386,14 @@
2860 handle_syscall(Event *event) {
2861 debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
2862 if (event->proc->state != STATE_IGNORED) {
2863- if (options.syscalls) {
2864- output_left(LT_TOF_SYSCALL, event->proc,
2865- sysname(event->proc, event->e_un.sysnum));
2866- }
2867- if (event->proc->breakpoints_enabled == 0) {
2868- enable_all_breakpoints(event->proc);
2869- }
2870 callstack_push_syscall(event->proc, event->e_un.sysnum);
2871+ if (options.syscalls) {
2872+ output_left(LT_TOF_SYSCALL, event->proc,
2873+ sysname(event->proc, event->e_un.sysnum));
2874+ }
2875+ if (event->proc->breakpoints_enabled == 0) {
2876+ enable_all_breakpoints(event->proc);
2877+ }
2878 }
2879 continue_process(event->proc->pid);
2880 }
2881@@ -427,14 +427,14 @@
2882 handle_arch_syscall(Event *event) {
2883 debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
2884 if (event->proc->state != STATE_IGNORED) {
2885- if (options.syscalls) {
2886- output_left(LT_TOF_SYSCALL, event->proc,
2887- arch_sysname(event->proc, event->e_un.sysnum));
2888- }
2889- if (event->proc->breakpoints_enabled == 0) {
2890- enable_all_breakpoints(event->proc);
2891- }
2892 callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
2893+ if (options.syscalls) {
2894+ output_left(LT_TOF_SYSCALL, event->proc,
2895+ arch_sysname(event->proc, event->e_un.sysnum));
2896+ }
2897+ if (event->proc->breakpoints_enabled == 0) {
2898+ enable_all_breakpoints(event->proc);
2899+ }
2900 }
2901 continue_process(event->proc->pid);
2902 }
2903@@ -470,11 +470,11 @@
2904 if (opt_T || options.summary) {
2905 calc_time_spent(event->proc);
2906 }
2907- callstack_pop(event->proc);
2908 if (options.syscalls) {
2909 output_right(LT_TOF_SYSCALLR, event->proc,
2910 sysname(event->proc, event->e_un.sysnum));
2911 }
2912+ callstack_pop(event->proc);
2913 }
2914 continue_process(event->proc->pid);
2915 }
2916@@ -486,15 +486,19 @@
2917 if (opt_T || options.summary) {
2918 calc_time_spent(event->proc);
2919 }
2920- callstack_pop(event->proc);
2921 if (options.syscalls) {
2922 output_right(LT_TOF_SYSCALLR, event->proc,
2923 arch_sysname(event->proc, event->e_un.sysnum));
2924 }
2925+ callstack_pop(event->proc);
2926 }
2927 continue_process(event->proc->pid);
2928 }
2929
2930+#ifdef __powerpc__
2931+void *get_count_register (Process *proc);
2932+#endif
2933+
2934 static void
2935 handle_breakpoint(Event *event) {
2936 int i, j;
2937@@ -561,25 +565,31 @@
2938 libsym);
2939 }
2940 } else {
2941- sbp = dict_find_entry(event->proc->breakpoints, sym2addr(event->proc, libsym));
2942- assert(sbp);
2943- if (addr != sbp->addr) {
2944+ sbp = dict_find_entry(event->proc->breakpoints, addr);
2945+ /* On powerpc, the breakpoint address
2946+ may end up being actual entry point
2947+ of the library symbol, not the PLT
2948+ address we computed. In that case,
2949+ sbp is NULL. */
2950+ if (sbp == NULL || addr != sbp->addr) {
2951 insert_breakpoint(event->proc, addr,
2952 libsym);
2953 }
2954 }
2955 #elif defined(__mips__)
2956- void *addr;
2957- void *old_addr;
2958+ void *addr = NULL;
2959 struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
2960+ struct library_symbol *new_sym;
2961 assert(sym);
2962- old_addr = dict_find_entry(event->proc->breakpoints, sym2addr(event->proc, sym))->addr;
2963 addr=sym2addr(event->proc,sym);
2964- assert(old_addr !=0 && addr !=0);
2965- if(addr != old_addr){
2966- struct library_symbol *new_sym;
2967- new_sym=malloc(sizeof(*new_sym));
2968- memcpy(new_sym,sym,sizeof(*new_sym));
2969+ sbp = dict_find_entry(event->proc->breakpoints, addr);
2970+ if (sbp) {
2971+ if (addr != sbp->addr) {
2972+ insert_breakpoint(event->proc, addr, sym);
2973+ }
2974+ } else {
2975+ new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
2976+ memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
2977 new_sym->next=event->proc->list_of_symbols;
2978 event->proc->list_of_symbols=new_sym;
2979 insert_breakpoint(event->proc, addr, new_sym);
2980@@ -593,12 +603,12 @@
2981 calc_time_spent(event->proc);
2982 }
2983 }
2984- callstack_pop(event->proc);
2985 event->proc->return_addr = event->e_un.brk_addr;
2986 if (event->proc->state != STATE_IGNORED) {
2987 output_right(LT_TOF_FUNCTIONR, event->proc,
2988 event->proc->callstack[i].c_un.libfunc->name);
2989 }
2990+ callstack_pop(event->proc);
2991 continue_after_breakpoint(event->proc,
2992 address2bpstruct(event->proc,
2993 event->e_un.brk_addr));
2994@@ -607,12 +617,16 @@
2995 }
2996
2997 if ((sbp = address2bpstruct(event->proc, event->e_un.brk_addr))) {
2998+ if (strcmp(sbp->libsym->name, "") == 0) {
2999+ debug(2, "Hit _dl_debug_state breakpoint!\n");
3000+ arch_check_dbg(event->proc);
3001+ }
3002 if (event->proc->state != STATE_IGNORED) {
3003 event->proc->stack_pointer = get_stack_pointer(event->proc);
3004 event->proc->return_addr =
3005 get_return_addr(event->proc, event->proc->stack_pointer);
3006+ callstack_push_symfunc(event->proc, sbp->libsym);
3007 output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym->name);
3008- callstack_push_symfunc(event->proc, sbp->libsym);
3009 }
3010 #ifdef PLT_REINITALISATION_BP
3011 if (event->proc->need_to_reinitialize_breakpoints
3012@@ -625,7 +639,7 @@
3013 return;
3014 }
3015
3016- if (event->proc->state != STATE_IGNORED) {
3017+ if (event->proc->state != STATE_IGNORED && !options.no_plt) {
3018 output_line(event->proc, "unexpected breakpoint at %p",
3019 (void *)event->e_un.brk_addr);
3020 }
3021@@ -639,7 +653,8 @@
3022 debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum);
3023 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
3024 if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
3025- fprintf(stderr, "Error: call nesting too deep!\n");
3026+ fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
3027+ abort();
3028 return;
3029 }
3030
3031@@ -657,15 +672,17 @@
3032
3033 static void
3034 callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
3035- struct callstack_element *elem;
3036+ struct callstack_element *elem, *prev;
3037
3038 debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
3039 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
3040 if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
3041- fprintf(stderr, "Error: call nesting too deep!\n");
3042+ fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
3043+ abort();
3044 return;
3045 }
3046
3047+ prev = &proc->callstack[proc->callstack_depth-1];
3048 elem = &proc->callstack[proc->callstack_depth];
3049 elem->is_syscall = 0;
3050 elem->c_un.libfunc = sym;
3051@@ -675,7 +692,9 @@
3052 insert_breakpoint(proc, elem->return_addr, 0);
3053 }
3054
3055- proc->callstack_depth++;
3056+ /* handle functions like atexit() on mips which have no return */
3057+ if (elem->return_addr != prev->return_addr)
3058+ proc->callstack_depth++;
3059 if (opt_T || options.summary) {
3060 struct timezone tz;
3061 gettimeofday(&elem->time_spent, &tz);
3062@@ -692,5 +711,9 @@
3063 if (!elem->is_syscall && elem->return_addr) {
3064 delete_breakpoint(proc, elem->return_addr);
3065 }
3066+ if (elem->arch_ptr != NULL) {
3067+ free(elem->arch_ptr);
3068+ elem->arch_ptr = NULL;
3069+ }
3070 proc->callstack_depth--;
3071 }
3072
3073=== added file 'ltrace-elf.c'
3074--- ltrace-elf.c 1970-01-01 00:00:00 +0000
3075+++ ltrace-elf.c 2011-03-15 17:56:13 +0000
3076@@ -0,0 +1,827 @@
3077+#include "config.h"
3078+
3079+#include <endian.h>
3080+#include <errno.h>
3081+#include <error.h>
3082+#include <fcntl.h>
3083+#include <gelf.h>
3084+#include <inttypes.h>
3085+#include <stdint.h>
3086+#include <stdlib.h>
3087+#include <string.h>
3088+#include <unistd.h>
3089+#include <assert.h>
3090+
3091+#include "common.h"
3092+
3093+void do_init_elf(struct ltelf *lte, const char *filename);
3094+void do_close_elf(struct ltelf *lte);
3095+void add_library_symbol(GElf_Addr addr, const char *name,
3096+ struct library_symbol **library_symbolspp,
3097+ enum toplt type_of_plt, int is_weak);
3098+int in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym);
3099+static GElf_Addr opd2addr(struct ltelf *ltc, GElf_Addr addr);
3100+
3101+struct library_symbol *library_symbols = NULL;
3102+struct ltelf main_lte;
3103+
3104+#ifdef PLT_REINITALISATION_BP
3105+extern char *PLTs_initialized_by_here;
3106+#endif
3107+
3108+#ifndef DT_PPC_GOT
3109+# define DT_PPC_GOT (DT_LOPROC + 0)
3110+#endif
3111+
3112+#define PPC_PLT_STUB_SIZE 16
3113+
3114+static Elf_Data *loaddata(Elf_Scn *scn, GElf_Shdr *shdr)
3115+{
3116+ Elf_Data *data = elf_getdata(scn, NULL);
3117+ if (data == NULL || elf_getdata(scn, data) != NULL
3118+ || data->d_off || data->d_size != shdr->sh_size)
3119+ return NULL;
3120+ return data;
3121+}
3122+
3123+static int inside(GElf_Addr addr, GElf_Shdr *shdr)
3124+{
3125+ return addr >= shdr->sh_addr
3126+ && addr < shdr->sh_addr + shdr->sh_size;
3127+}
3128+
3129+static int maybe_pick_section(GElf_Addr addr,
3130+ Elf_Scn *in_sec, GElf_Shdr *in_shdr,
3131+ Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
3132+{
3133+ if (inside (addr, in_shdr)) {
3134+ *tgt_sec = in_sec;
3135+ *tgt_shdr = *in_shdr;
3136+ return 1;
3137+ }
3138+ return 0;
3139+}
3140+
3141+static int get_section_covering(struct ltelf *lte, GElf_Addr addr,
3142+ Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr)
3143+{
3144+ int i;
3145+ for (i = 1; i < lte->ehdr.e_shnum; ++i) {
3146+ Elf_Scn *scn;
3147+ GElf_Shdr shdr;
3148+
3149+ scn = elf_getscn(lte->elf, i);
3150+ if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) {
3151+ debug(1, "Couldn't read section or header.");
3152+ return 0;
3153+ }
3154+
3155+ if (maybe_pick_section(addr, scn, &shdr, tgt_sec, tgt_shdr))
3156+ return 1;
3157+ }
3158+
3159+ return 0;
3160+}
3161+
3162+static GElf_Addr read32be(Elf_Data *data, size_t offset)
3163+{
3164+ if (data->d_size < offset + 4) {
3165+ debug(1, "Not enough data to read 32bit value at offset %zd.",
3166+ offset);
3167+ return 0;
3168+ }
3169+
3170+ unsigned char const *buf = data->d_buf + offset;
3171+ return ((Elf32_Word)buf[0] << 24)
3172+ | ((Elf32_Word)buf[1] << 16)
3173+ | ((Elf32_Word)buf[2] << 8)
3174+ | ((Elf32_Word)buf[3]);
3175+}
3176+
3177+static GElf_Addr get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot,
3178+ Elf_Data *plt_data)
3179+{
3180+ Elf_Scn *ppcgot_sec = NULL;
3181+ GElf_Shdr ppcgot_shdr;
3182+ if (ppcgot != 0
3183+ && !get_section_covering(lte, ppcgot, &ppcgot_sec, &ppcgot_shdr))
3184+ // xxx should be the log out
3185+ fprintf(stderr,
3186+ "DT_PPC_GOT=%#" PRIx64 ", but no such section found.\n",
3187+ ppcgot);
3188+
3189+ if (ppcgot_sec != NULL) {
3190+ Elf_Data *data = loaddata(ppcgot_sec, &ppcgot_shdr);
3191+ if (data == NULL
3192+ || data->d_size < 8 )
3193+ debug(1, "Couldn't read GOT data.");
3194+ else {
3195+ // where PPCGOT begins in .got
3196+ size_t offset = ppcgot - ppcgot_shdr.sh_addr;
3197+ GElf_Addr glink_vma = read32be(data, offset + 4);
3198+ if (glink_vma != 0) {
3199+ debug(1, "PPC GOT glink_vma address: %#" PRIx64,
3200+ glink_vma);
3201+ return glink_vma;
3202+ }
3203+ }
3204+ }
3205+
3206+ if (plt_data != NULL) {
3207+ GElf_Addr glink_vma = read32be(plt_data, 0);
3208+ debug(1, ".plt glink_vma address: %#" PRIx64, glink_vma);
3209+ return glink_vma;
3210+ }
3211+
3212+ return 0;
3213+}
3214+
3215+void
3216+do_init_elf(struct ltelf *lte, const char *filename) {
3217+ int i;
3218+ GElf_Addr relplt_addr = 0;
3219+ size_t relplt_size = 0;
3220+
3221+ debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename);
3222+ debug(1, "Reading ELF from %s...", filename);
3223+
3224+ lte->fd = open(filename, O_RDONLY);
3225+ if (lte->fd == -1)
3226+ error(EXIT_FAILURE, errno, "Can't open \"%s\"", filename);
3227+
3228+#ifdef HAVE_ELF_C_READ_MMAP
3229+ lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL);
3230+#else
3231+ lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL);
3232+#endif
3233+
3234+ if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF)
3235+ error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename);
3236+
3237+ if (gelf_getehdr(lte->elf, &lte->ehdr) == NULL)
3238+ error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"",
3239+ filename);
3240+
3241+ if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN)
3242+ error(EXIT_FAILURE, 0,
3243+ "\"%s\" is not an ELF executable nor shared library",
3244+ filename);
3245+
3246+ if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS
3247+ || lte->ehdr.e_machine != LT_ELF_MACHINE)
3248+#ifdef LT_ELF_MACHINE2
3249+ && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2
3250+ || lte->ehdr.e_machine != LT_ELF_MACHINE2)
3251+#endif
3252+#ifdef LT_ELF_MACHINE3
3253+ && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3
3254+ || lte->ehdr.e_machine != LT_ELF_MACHINE3)
3255+#endif
3256+ )
3257+ error(EXIT_FAILURE, 0,
3258+ "\"%s\" is ELF from incompatible architecture", filename);
3259+
3260+ Elf_Data *plt_data = NULL;
3261+ GElf_Addr ppcgot = 0;
3262+
3263+ for (i = 1; i < lte->ehdr.e_shnum; ++i) {
3264+ Elf_Scn *scn;
3265+ GElf_Shdr shdr;
3266+ const char *name;
3267+
3268+ scn = elf_getscn(lte->elf, i);
3269+ if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
3270+ error(EXIT_FAILURE, 0,
3271+ "Couldn't get section header from \"%s\"",
3272+ filename);
3273+
3274+ name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name);
3275+ if (name == NULL)
3276+ error(EXIT_FAILURE, 0,
3277+ "Couldn't get section header from \"%s\"",
3278+ filename);
3279+
3280+ if (shdr.sh_type == SHT_SYMTAB) {
3281+ Elf_Data *data;
3282+
3283+ lte->symtab = elf_getdata(scn, NULL);
3284+ lte->symtab_count = shdr.sh_size / shdr.sh_entsize;
3285+ if ((lte->symtab == NULL
3286+ || elf_getdata(scn, lte->symtab) != NULL)
3287+ && opt_x != NULL)
3288+ error(EXIT_FAILURE, 0,
3289+ "Couldn't get .symtab data from \"%s\"",
3290+ filename);
3291+
3292+ scn = elf_getscn(lte->elf, shdr.sh_link);
3293+ if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
3294+ error(EXIT_FAILURE, 0,
3295+ "Couldn't get section header from \"%s\"",
3296+ filename);
3297+
3298+ data = elf_getdata(scn, NULL);
3299+ if (data == NULL || elf_getdata(scn, data) != NULL
3300+ || shdr.sh_size != data->d_size || data->d_off)
3301+ error(EXIT_FAILURE, 0,
3302+ "Couldn't get .strtab data from \"%s\"",
3303+ filename);
3304+
3305+ lte->strtab = data->d_buf;
3306+ } else if (shdr.sh_type == SHT_DYNSYM) {
3307+ Elf_Data *data;
3308+
3309+ lte->dynsym = elf_getdata(scn, NULL);
3310+ lte->dynsym_count = shdr.sh_size / shdr.sh_entsize;
3311+ if (lte->dynsym == NULL
3312+ || elf_getdata(scn, lte->dynsym) != NULL)
3313+ error(EXIT_FAILURE, 0,
3314+ "Couldn't get .dynsym data from \"%s\"",
3315+ filename);
3316+
3317+ scn = elf_getscn(lte->elf, shdr.sh_link);
3318+ if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
3319+ error(EXIT_FAILURE, 0,
3320+ "Couldn't get section header from \"%s\"",
3321+ filename);
3322+
3323+ data = elf_getdata(scn, NULL);
3324+ if (data == NULL || elf_getdata(scn, data) != NULL
3325+ || shdr.sh_size != data->d_size || data->d_off)
3326+ error(EXIT_FAILURE, 0,
3327+ "Couldn't get .dynstr data from \"%s\"",
3328+ filename);
3329+
3330+ lte->dynstr = data->d_buf;
3331+ } else if (shdr.sh_type == SHT_DYNAMIC) {
3332+ Elf_Data *data;
3333+ size_t j;
3334+
3335+ lte->dyn_addr = shdr.sh_addr;
3336+ lte->dyn_sz = shdr.sh_size;
3337+
3338+ data = elf_getdata(scn, NULL);
3339+ if (data == NULL || elf_getdata(scn, data) != NULL)
3340+ error(EXIT_FAILURE, 0,
3341+ "Couldn't get .dynamic data from \"%s\"",
3342+ filename);
3343+
3344+ for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
3345+ GElf_Dyn dyn;
3346+
3347+ if (gelf_getdyn(data, j, &dyn) == NULL)
3348+ error(EXIT_FAILURE, 0,
3349+ "Couldn't get .dynamic data from \"%s\"",
3350+ filename);
3351+#ifdef __mips__
3352+/**
3353+ MIPS ABI Supplement:
3354+
3355+ DT_PLTGOT This member holds the address of the .got section.
3356+
3357+ DT_MIPS_SYMTABNO This member holds the number of entries in the
3358+ .dynsym section.
3359+
3360+ DT_MIPS_LOCAL_GOTNO This member holds the number of local global
3361+ offset table entries.
3362+
3363+ DT_MIPS_GOTSYM This member holds the index of the first dyamic
3364+ symbol table entry that corresponds to an entry in the gobal offset
3365+ table.
3366+
3367+ */
3368+ if(dyn.d_tag==DT_PLTGOT){
3369+ lte->pltgot_addr=dyn.d_un.d_ptr;
3370+ }
3371+ if(dyn.d_tag==DT_MIPS_LOCAL_GOTNO){
3372+ lte->mips_local_gotno=dyn.d_un.d_val;
3373+ }
3374+ if(dyn.d_tag==DT_MIPS_GOTSYM){
3375+ lte->mips_gotsym=dyn.d_un.d_val;
3376+ }
3377+#endif // __mips__
3378+ if (dyn.d_tag == DT_JMPREL)
3379+ relplt_addr = dyn.d_un.d_ptr;
3380+ else if (dyn.d_tag == DT_PLTRELSZ)
3381+ relplt_size = dyn.d_un.d_val;
3382+ else if (dyn.d_tag == DT_PPC_GOT) {
3383+ ppcgot = dyn.d_un.d_val;
3384+ debug(1, "ppcgot %#" PRIx64, ppcgot);
3385+ }
3386+ }
3387+ } else if (shdr.sh_type == SHT_HASH) {
3388+ Elf_Data *data;
3389+ size_t j;
3390+
3391+ lte->hash_type = SHT_HASH;
3392+
3393+ data = elf_getdata(scn, NULL);
3394+ if (data == NULL || elf_getdata(scn, data) != NULL
3395+ || data->d_off || data->d_size != shdr.sh_size)
3396+ error(EXIT_FAILURE, 0,
3397+ "Couldn't get .hash data from \"%s\"",
3398+ filename);
3399+
3400+ if (shdr.sh_entsize == 4) {
3401+ /* Standard conforming ELF. */
3402+ if (data->d_type != ELF_T_WORD)
3403+ error(EXIT_FAILURE, 0,
3404+ "Couldn't get .hash data from \"%s\"",
3405+ filename);
3406+ lte->hash = (Elf32_Word *) data->d_buf;
3407+ } else if (shdr.sh_entsize == 8) {
3408+ /* Alpha or s390x. */
3409+ Elf32_Word *dst, *src;
3410+ size_t hash_count = data->d_size / 8;
3411+
3412+ lte->hash = (Elf32_Word *)
3413+ malloc(hash_count * sizeof(Elf32_Word));
3414+ if (lte->hash == NULL)
3415+ error(EXIT_FAILURE, 0,
3416+ "Couldn't convert .hash section from \"%s\"",
3417+ filename);
3418+ lte->lte_flags |= LTE_HASH_MALLOCED;
3419+ dst = lte->hash;
3420+ src = (Elf32_Word *) data->d_buf;
3421+ if ((data->d_type == ELF_T_WORD
3422+ && __BYTE_ORDER == __BIG_ENDIAN)
3423+ || (data->d_type == ELF_T_XWORD
3424+ && lte->ehdr.e_ident[EI_DATA] ==
3425+ ELFDATA2MSB))
3426+ ++src;
3427+ for (j = 0; j < hash_count; ++j, src += 2)
3428+ *dst++ = *src;
3429+ } else
3430+ error(EXIT_FAILURE, 0,
3431+ "Unknown .hash sh_entsize in \"%s\"",
3432+ filename);
3433+ } else if (shdr.sh_type == SHT_GNU_HASH
3434+ && lte->hash == NULL) {
3435+ Elf_Data *data;
3436+
3437+ lte->hash_type = SHT_GNU_HASH;
3438+
3439+ if (shdr.sh_entsize != 0
3440+ && shdr.sh_entsize != 4) {
3441+ error(EXIT_FAILURE, 0,
3442+ ".gnu.hash sh_entsize in \"%s\" "
3443+ "should be 4, but is %#" PRIx64,
3444+ filename, shdr.sh_entsize);
3445+ }
3446+
3447+ data = loaddata(scn, &shdr);
3448+ if (data == NULL)
3449+ error(EXIT_FAILURE, 0,
3450+ "Couldn't get .gnu.hash data from \"%s\"",
3451+ filename);
3452+
3453+ lte->hash = (Elf32_Word *) data->d_buf;
3454+ } else if (shdr.sh_type == SHT_PROGBITS
3455+ || shdr.sh_type == SHT_NOBITS) {
3456+ if (strcmp(name, ".plt") == 0) {
3457+ lte->plt_addr = shdr.sh_addr;
3458+ lte->plt_size = shdr.sh_size;
3459+ if (shdr.sh_flags & SHF_EXECINSTR) {
3460+ lte->lte_flags |= LTE_PLT_EXECUTABLE;
3461+ }
3462+ if (lte->ehdr.e_machine == EM_PPC) {
3463+ plt_data = loaddata(scn, &shdr);
3464+ if (plt_data == NULL)
3465+ fprintf(stderr,
3466+ "Can't load .plt data\n");
3467+ }
3468+ }
3469+#ifdef ARCH_SUPPORTS_OPD
3470+ else if (strcmp(name, ".opd") == 0) {
3471+ lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr;
3472+ lte->opd_size = shdr.sh_size;
3473+ lte->opd = elf_rawdata(scn, NULL);
3474+ }
3475+#endif
3476+ }
3477+ }
3478+
3479+ if (lte->dynsym == NULL || lte->dynstr == NULL)
3480+ error(EXIT_FAILURE, 0,
3481+ "Couldn't find .dynsym or .dynstr in \"%s\"", filename);
3482+
3483+ if (!relplt_addr || !lte->plt_addr) {
3484+ debug(1, "%s has no PLT relocations", filename);
3485+ lte->relplt = NULL;
3486+ lte->relplt_count = 0;
3487+ } else if (relplt_size == 0) {
3488+ debug(1, "%s has unknown PLT size", filename);
3489+ lte->relplt = NULL;
3490+ lte->relplt_count = 0;
3491+ } else {
3492+ if (lte->ehdr.e_machine == EM_PPC) {
3493+ GElf_Addr glink_vma
3494+ = get_glink_vma(lte, ppcgot, plt_data);
3495+
3496+ assert (relplt_size % 12 == 0);
3497+ size_t count = relplt_size / 12; // size of RELA entry
3498+ lte->plt_stub_vma = glink_vma
3499+ - (GElf_Addr)count * PPC_PLT_STUB_SIZE;
3500+ debug(1, "stub_vma is %#" PRIx64, lte->plt_stub_vma);
3501+ }
3502+
3503+ for (i = 1; i < lte->ehdr.e_shnum; ++i) {
3504+ Elf_Scn *scn;
3505+ GElf_Shdr shdr;
3506+
3507+ scn = elf_getscn(lte->elf, i);
3508+ if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL)
3509+ error(EXIT_FAILURE, 0,
3510+ "Couldn't get section header from \"%s\"",
3511+ filename);
3512+ if (shdr.sh_addr == relplt_addr
3513+ && shdr.sh_size == relplt_size) {
3514+ lte->relplt = elf_getdata(scn, NULL);
3515+ lte->relplt_count =
3516+ shdr.sh_size / shdr.sh_entsize;
3517+ if (lte->relplt == NULL
3518+ || elf_getdata(scn, lte->relplt) != NULL)
3519+ error(EXIT_FAILURE, 0,
3520+ "Couldn't get .rel*.plt data from \"%s\"",
3521+ filename);
3522+ break;
3523+ }
3524+ }
3525+
3526+ if (i == lte->ehdr.e_shnum)
3527+ error(EXIT_FAILURE, 0,
3528+ "Couldn't find .rel*.plt section in \"%s\"",
3529+ filename);
3530+
3531+ debug(1, "%s %zd PLT relocations", filename, lte->relplt_count);
3532+ }
3533+}
3534+
3535+void
3536+do_close_elf(struct ltelf *lte) {
3537+ debug(DEBUG_FUNCTION, "do_close_elf()");
3538+ if (lte->lte_flags & LTE_HASH_MALLOCED)
3539+ free((char *)lte->hash);
3540+ elf_end(lte->elf);
3541+ close(lte->fd);
3542+}
3543+
3544+void
3545+add_library_symbol(GElf_Addr addr, const char *name,
3546+ struct library_symbol **library_symbolspp,
3547+ enum toplt type_of_plt, int is_weak) {
3548+ struct library_symbol *s;
3549+
3550+ debug(DEBUG_FUNCTION, "add_library_symbol()");
3551+
3552+ s = malloc(sizeof(struct library_symbol) + strlen(name) + 1);
3553+ if (s == NULL)
3554+ error(EXIT_FAILURE, errno, "add_library_symbol failed");
3555+
3556+ s->needs_init = 1;
3557+ s->is_weak = is_weak;
3558+ s->plt_type = type_of_plt;
3559+ s->next = *library_symbolspp;
3560+ s->enter_addr = (void *)(uintptr_t) addr;
3561+ s->name = (char *)(s + 1);
3562+ strcpy(s->name, name);
3563+ *library_symbolspp = s;
3564+
3565+ debug(2, "addr: %p, symbol: \"%s\"", (void *)(uintptr_t) addr, name);
3566+}
3567+
3568+/* stolen from elfutils-0.123 */
3569+static unsigned long
3570+private_elf_gnu_hash(const char *name) {
3571+ unsigned long h = 5381;
3572+ const unsigned char *string = (const unsigned char *)name;
3573+ unsigned char c;
3574+ for (c = *string; c; c = *++string)
3575+ h = h * 33 + c;
3576+ return h & 0xffffffff;
3577+}
3578+
3579+static int
3580+symbol_matches(struct ltelf *lte, size_t lte_i, GElf_Sym *sym,
3581+ size_t symidx, const char *name)
3582+{
3583+ GElf_Sym tmp_sym;
3584+ GElf_Sym *tmp;
3585+
3586+ tmp = (sym) ? (sym) : (&tmp_sym);
3587+
3588+ if (gelf_getsym(lte[lte_i].dynsym, symidx, tmp) == NULL)
3589+ error(EXIT_FAILURE, 0, "Couldn't get symbol from .dynsym");
3590+ else {
3591+ tmp->st_value += lte[lte_i].base_addr;
3592+ debug(2, "symbol found: %s, %zd, %#" PRIx64,
3593+ name, lte_i, tmp->st_value);
3594+ }
3595+ return tmp->st_value != 0
3596+ && tmp->st_shndx != SHN_UNDEF
3597+ && strcmp(name, lte[lte_i].dynstr + tmp->st_name) == 0;
3598+}
3599+
3600+int
3601+in_load_libraries(const char *name, struct ltelf *lte, size_t count, GElf_Sym *sym) {
3602+ size_t i;
3603+ unsigned long hash;
3604+ unsigned long gnu_hash;
3605+
3606+ if (!count)
3607+ return 1;
3608+
3609+#ifdef ELF_HASH_TAKES_SIGNED_CHAR
3610+ hash = elf_hash(name);
3611+#else
3612+ hash = elf_hash((const unsigned char *)name);
3613+#endif
3614+ gnu_hash = private_elf_gnu_hash(name);
3615+
3616+ for (i = 0; i < count; ++i) {
3617+ if (lte[i].hash == NULL)
3618+ continue;
3619+
3620+ if (lte[i].hash_type == SHT_GNU_HASH) {
3621+ Elf32_Word * hashbase = lte[i].hash;
3622+ Elf32_Word nbuckets = *hashbase++;
3623+ Elf32_Word symbias = *hashbase++;
3624+ Elf32_Word bitmask_nwords = *hashbase++;
3625+ Elf32_Word * buckets;
3626+ Elf32_Word * chain_zero;
3627+ Elf32_Word bucket;
3628+
3629+ // +1 for skipped `shift'
3630+ hashbase += lte[i].ehdr.e_ident[EI_CLASS] * bitmask_nwords + 1;
3631+ buckets = hashbase;
3632+ hashbase += nbuckets;
3633+ chain_zero = hashbase - symbias;
3634+ bucket = buckets[gnu_hash % nbuckets];
3635+
3636+ if (bucket != 0) {
3637+ const Elf32_Word *hasharr = &chain_zero[bucket];
3638+ do
3639+ if ((*hasharr & ~1u) == (gnu_hash & ~1u)) {
3640+ int symidx = hasharr - chain_zero;
3641+ if (symbol_matches(lte, i,
3642+ sym, symidx,
3643+ name))
3644+ return 1;
3645+ }
3646+ while ((*hasharr++ & 1u) == 0);
3647+ }
3648+ } else {
3649+ Elf32_Word nbuckets, symndx;
3650+ Elf32_Word *buckets, *chain;
3651+ nbuckets = lte[i].hash[0];
3652+ buckets = &lte[i].hash[2];
3653+ chain = &lte[i].hash[2 + nbuckets];
3654+
3655+ for (symndx = buckets[hash % nbuckets];
3656+ symndx != STN_UNDEF; symndx = chain[symndx])
3657+ if (symbol_matches(lte, i, sym, symndx, name))
3658+ return 1;
3659+ }
3660+ }
3661+ return 0;
3662+}
3663+
3664+static GElf_Addr
3665+opd2addr(struct ltelf *lte, GElf_Addr addr) {
3666+#ifdef ARCH_SUPPORTS_OPD
3667+ unsigned long base, offset;
3668+
3669+ if (!lte->opd)
3670+ return addr;
3671+
3672+ base = (unsigned long)lte->opd->d_buf;
3673+ offset = (unsigned long)addr - (unsigned long)lte->opd_addr;
3674+ if (offset > lte->opd_size)
3675+ error(EXIT_FAILURE, 0, "static plt not in .opd");
3676+
3677+ return *(GElf_Addr*)(base + offset);
3678+#else //!ARCH_SUPPORTS_OPD
3679+ return addr;
3680+#endif
3681+}
3682+
3683+struct library_symbol *
3684+read_elf(Process *proc) {
3685+ struct ltelf lte[MAX_LIBRARIES + 1];
3686+ size_t i;
3687+ struct opt_x_t *xptr;
3688+ struct library_symbol **lib_tail = NULL;
3689+ int exit_out = 0;
3690+ int count = 0;
3691+
3692+ debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename);
3693+
3694+ memset(lte, 0, sizeof(*lte));
3695+ library_symbols = NULL;
3696+ library_num = 0;
3697+ proc->libdl_hooked = 0;
3698+
3699+ elf_version(EV_CURRENT);
3700+
3701+ do_init_elf(lte, proc->filename);
3702+
3703+ memcpy(&main_lte, lte, sizeof(struct ltelf));
3704+
3705+ if (opt_p && opt_p->pid > 0) {
3706+ linkmap_init(proc, lte);
3707+ proc->libdl_hooked = 1;
3708+ }
3709+
3710+ proc->e_machine = lte->ehdr.e_machine;
3711+
3712+ for (i = 0; i < library_num; ++i) {
3713+ do_init_elf(&lte[i + 1], library[i]);
3714+ }
3715+
3716+ if (!options.no_plt) {
3717+#ifdef __mips__
3718+ // MIPS doesn't use the PLT and the GOT entries get changed
3719+ // on startup.
3720+ proc->need_to_reinitialize_breakpoints = 1;
3721+ for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){
3722+ GElf_Sym sym;
3723+ const char *name;
3724+ GElf_Addr addr = arch_plt_sym_val(lte, i, 0);
3725+ if (gelf_getsym(lte->dynsym, i, &sym) == NULL){
3726+ error(EXIT_FAILURE, 0,
3727+ "Couldn't get relocation from \"%s\"",
3728+ proc->filename);
3729+ }
3730+ name=lte->dynstr+sym.st_name;
3731+ if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){
3732+ debug(2,"sym %s not a function",name);
3733+ continue;
3734+ }
3735+ add_library_symbol(addr, name, &library_symbols, 0,
3736+ ELF64_ST_BIND(sym.st_info) != 0);
3737+ if (!lib_tail)
3738+ lib_tail = &(library_symbols->next);
3739+ }
3740+#else
3741+ for (i = 0; i < lte->relplt_count; ++i) {
3742+ GElf_Rel rel;
3743+ GElf_Rela rela;
3744+ GElf_Sym sym;
3745+ GElf_Addr addr;
3746+ void *ret;
3747+ const char *name;
3748+
3749+ if (lte->relplt->d_type == ELF_T_REL) {
3750+ ret = gelf_getrel(lte->relplt, i, &rel);
3751+ rela.r_offset = rel.r_offset;
3752+ rela.r_info = rel.r_info;
3753+ rela.r_addend = 0;
3754+ } else
3755+ ret = gelf_getrela(lte->relplt, i, &rela);
3756+
3757+ if (ret == NULL
3758+ || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
3759+ || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
3760+ &sym) == NULL)
3761+ error(EXIT_FAILURE, 0,
3762+ "Couldn't get relocation from \"%s\"",
3763+ proc->filename);
3764+
3765+#ifdef PLT_REINITALISATION_BP
3766+ if (!sym.st_value && PLTs_initialized_by_here)
3767+ proc->need_to_reinitialize_breakpoints = 1;
3768+#endif
3769+
3770+ name = lte->dynstr + sym.st_name;
3771+ count = library_num ? library_num+1 : 0;
3772+
3773+ if (in_load_libraries(name, lte, count, NULL)) {
3774+ enum toplt pltt;
3775+ if (sym.st_value == 0 && lte->plt_stub_vma != 0) {
3776+ pltt = LS_TOPLT_EXEC;
3777+ addr = lte->plt_stub_vma + PPC_PLT_STUB_SIZE * i;
3778+ }
3779+ else {
3780+ pltt = PLTS_ARE_EXECUTABLE(lte)
3781+ ? LS_TOPLT_EXEC : LS_TOPLT_POINT;
3782+ addr = arch_plt_sym_val(lte, i, &rela);
3783+ }
3784+
3785+ add_library_symbol(addr, name, &library_symbols, pltt,
3786+ ELF64_ST_BIND(sym.st_info) == STB_WEAK);
3787+ if (!lib_tail)
3788+ lib_tail = &(library_symbols->next);
3789+ }
3790+ }
3791+#endif // !__mips__
3792+#ifdef PLT_REINITALISATION_BP
3793+ struct opt_x_t *main_cheat;
3794+
3795+ if (proc->need_to_reinitialize_breakpoints) {
3796+ /* Add "PLTs_initialized_by_here" to opt_x list, if not
3797+ already there. */
3798+ main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t));
3799+ if (main_cheat == NULL)
3800+ error(EXIT_FAILURE, 0, "Couldn't allocate memory");
3801+ main_cheat->next = opt_x;
3802+ main_cheat->found = 0;
3803+ main_cheat->name = PLTs_initialized_by_here;
3804+
3805+ for (xptr = opt_x; xptr; xptr = xptr->next)
3806+ if (strcmp(xptr->name, PLTs_initialized_by_here) == 0
3807+ && main_cheat) {
3808+ free(main_cheat);
3809+ main_cheat = NULL;
3810+ break;
3811+ }
3812+ if (main_cheat)
3813+ opt_x = main_cheat;
3814+ }
3815+#endif
3816+ } else {
3817+ lib_tail = &library_symbols;
3818+ }
3819+
3820+ for (i = 0; i < lte->symtab_count; ++i) {
3821+ GElf_Sym sym;
3822+ GElf_Addr addr;
3823+ const char *name;
3824+
3825+ if (gelf_getsym(lte->symtab, i, &sym) == NULL)
3826+ error(EXIT_FAILURE, 0,
3827+ "Couldn't get symbol from \"%s\"",
3828+ proc->filename);
3829+
3830+ name = lte->strtab + sym.st_name;
3831+ addr = sym.st_value;
3832+ if (!addr)
3833+ continue;
3834+
3835+ for (xptr = opt_x; xptr; xptr = xptr->next)
3836+ if (xptr->name && strcmp(xptr->name, name) == 0) {
3837+ /* FIXME: Should be able to use &library_symbols as above. But
3838+ when you do, none of the real library symbols cause breaks. */
3839+ add_library_symbol(opd2addr(lte, addr),
3840+ name, lib_tail, LS_TOPLT_NONE, 0);
3841+ xptr->found = 1;
3842+ break;
3843+ }
3844+ }
3845+
3846+ unsigned found_count = 0;
3847+
3848+ for (xptr = opt_x; xptr; xptr = xptr->next) {
3849+ if (xptr->found)
3850+ continue;
3851+
3852+ GElf_Sym sym;
3853+ GElf_Addr addr;
3854+ if (in_load_libraries(xptr->name, lte, library_num+1, &sym)) {
3855+ debug(2, "found symbol %s @ %#" PRIx64 ", adding it.",
3856+ xptr->name, sym.st_value);
3857+ addr = sym.st_value;
3858+ if (ELF32_ST_TYPE (sym.st_info) == STT_FUNC) {
3859+ add_library_symbol(addr, xptr->name, lib_tail, LS_TOPLT_NONE, 0);
3860+ xptr->found = 1;
3861+ found_count++;
3862+ }
3863+ }
3864+ if (found_count == opt_x_cnt){
3865+ debug(2, "done, found everything: %d\n", found_count);
3866+ break;
3867+ }
3868+ }
3869+
3870+ for (xptr = opt_x; xptr; xptr = xptr->next)
3871+ if ( ! xptr->found) {
3872+ char *badthing = "WARNING";
3873+#ifdef PLT_REINITALISATION_BP
3874+ if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
3875+ if (lte->ehdr.e_entry) {
3876+ add_library_symbol (
3877+ opd2addr (lte, lte->ehdr.e_entry),
3878+ PLTs_initialized_by_here,
3879+ lib_tail, 1, 0);
3880+ fprintf (stderr, "WARNING: Using e_ent"
3881+ "ry from elf header (%p) for "
3882+ "address of \"%s\"\n", (void*)
3883+ (long) lte->ehdr.e_entry,
3884+ PLTs_initialized_by_here);
3885+ continue;
3886+ }
3887+ badthing = "ERROR";
3888+ exit_out = 1;
3889+ }
3890+#endif
3891+ fprintf (stderr,
3892+ "%s: Couldn't find symbol \"%s\" in file \"%s\" assuming it will be loaded by libdl!"
3893+ "\n", badthing, xptr->name, proc->filename);
3894+ }
3895+ if (exit_out) {
3896+ exit (1);
3897+ }
3898+
3899+ for (i = 0; i < library_num + 1; ++i)
3900+ do_close_elf(&lte[i]);
3901+
3902+ return library_symbols;
3903+}
3904
3905=== added file 'ltrace-elf.h'
3906--- ltrace-elf.h 1970-01-01 00:00:00 +0000
3907+++ ltrace-elf.h 2011-03-15 17:56:13 +0000
3908@@ -0,0 +1,63 @@
3909+#ifndef LTRACE_ELF_H
3910+#define LTRACE_ELF_H
3911+
3912+#include <gelf.h>
3913+#include <stdlib.h>
3914+
3915+struct ltelf {
3916+ int fd;
3917+ Elf *elf;
3918+ GElf_Ehdr ehdr;
3919+ Elf_Data *dynsym;
3920+ size_t dynsym_count;
3921+ const char *dynstr;
3922+ GElf_Addr plt_addr;
3923+ size_t plt_size;
3924+ Elf_Data *relplt;
3925+ size_t relplt_count;
3926+ Elf_Data *symtab;
3927+ const char *strtab;
3928+ size_t symtab_count;
3929+ Elf_Data *opd;
3930+ GElf_Addr *opd_addr;
3931+ size_t opd_size;
3932+ Elf32_Word *hash;
3933+ int hash_type;
3934+ int lte_flags;
3935+ GElf_Addr dyn_addr;
3936+ size_t dyn_sz;
3937+ GElf_Addr base_addr;
3938+#ifdef __mips__
3939+ size_t pltgot_addr;
3940+ size_t mips_local_gotno;
3941+ size_t mips_gotsym;
3942+#endif // __mips__
3943+ GElf_Addr plt_stub_vma;
3944+};
3945+
3946+#define ELF_MAX_SEGMENTS 50
3947+#define LTE_HASH_MALLOCED 1
3948+#define LTE_PLT_EXECUTABLE 2
3949+
3950+#define PLTS_ARE_EXECUTABLE(lte) ((lte->lte_flags & LTE_PLT_EXECUTABLE) != 0)
3951+
3952+extern size_t library_num;
3953+extern char *library[MAX_LIBRARIES];
3954+
3955+extern struct library_symbol *read_elf(Process *);
3956+
3957+extern GElf_Addr arch_plt_sym_val(struct ltelf *, size_t, GElf_Rela *);
3958+
3959+#ifndef SHT_GNU_HASH
3960+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
3961+#endif
3962+
3963+#if __WORDSIZE == 32
3964+#define PRI_ELF_ADDR PRIx32
3965+#define GELF_ADDR_CAST(x) (void *)(uint32_t)(x)
3966+#else
3967+#define PRI_ELF_ADDR PRIx64
3968+#define GELF_ADDR_CAST(x) (void *)(x)
3969+#endif
3970+
3971+#endif
3972
3973=== modified file 'ltrace.1'
3974--- ltrace.1 2009-07-28 16:44:35 +0000
3975+++ ltrace.1 2011-03-15 17:56:13 +0000
3976@@ -6,7 +6,7 @@
3977
3978 .SH SYNOPSIS
3979 .B ltrace
3980-.I "[-CfhiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-X extern] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--output=filename] [--version] [command [arg ...]]"
3981+.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-X extern] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]"
3982
3983 .SH DESCRIPTION
3984 .B ltrace
3985@@ -23,11 +23,16 @@
3986 .SH OPTIONS
3987 .TP
3988 .I \-a, \-\-align column
3989-Align return values in a specific column (default column is 5/8 of screen width).
3990+Align return values in a specific
3991+.IR column
3992+(default column is 5/8 of screen width).
3993 .TP
3994 .I \-A maxelts
3995 Maximum number of array elements to print before suppressing the rest with an ellipsis ("...")
3996 .TP
3997+.I \-b, \-\-no-signals
3998+Disable printing of signals recieved by the traced process.
3999+.TP
4000 .I \-c
4001 Count time and calls for each library call and report a summary on program exit.
4002 .TP
4003@@ -82,6 +87,11 @@
4004 or clone(2) system calls.
4005 The new process is attached immediately.
4006 .TP
4007+.I \-g
4008+Do not place breakpoints on PLT entries. This option reduces
4009+the output of ltrace. This is commonly used to avoid tracing
4010+libc functions.
4011+.TP
4012 .I \-F
4013 Load an alternate config file. Normally, /etc/ltrace.conf and
4014 ~/.ltrace.conf will be read (the latter only if it exists).
4015@@ -153,6 +163,10 @@
4016 This option is only useful when running as root and enables the
4017 correct execution of setuid and/or setgid binaries.
4018 .TP
4019+.I \-w, --where NR
4020+Show backtrace of NR stack frames for each traced function. This option enabled
4021+only if libunwind support was enabled at compile time.
4022+.TP
4023 .I \-X extern
4024 Some architectures need to know where to set a breakpoint that will be hit
4025 after the dynamic linker has run. If this flag is used, then the breakpoint
4026@@ -164,6 +178,8 @@
4027 .I \-x extern
4028 Trace the external function
4029 .IR extern .
4030+This option will search the symbol table and lib-dl loaded libraries when
4031+attempting to match the given symbol name.
4032 This option may be repeated.
4033 .TP
4034 .I \-V, \-\-version
4035@@ -179,9 +195,6 @@
4036 .LP
4037 It only works on Linux and in a small subset of architectures.
4038 .LP
4039-Only ELF32 binaries are supported.
4040-.LP
4041-Calls to dlopen()ed libraries will not be traced.
4042 .PP
4043 If you would like to report a bug, send a message to the mailing list
4044 (ltrace-devel@lists.alioth.debian.org), or use the
4045
4046=== removed file 'mkdist'
4047--- mkdist 2009-07-25 16:24:38 +0000
4048+++ mkdist 1970-01-01 00:00:00 +0000
4049@@ -1,19 +0,0 @@
4050-#!/bin/sh -e
4051-
4052-# Create ltrace-${version}.tar.gz from a GIT repository
4053-
4054-if [ ! -d .git -o ! -f libltrace.c ]
4055-then
4056- echo "This must be called inside a ltrace GIT repository" 1>&2
4057- exit 1
4058-fi
4059-
4060-VERSION=$( cat VERSION )
4061-
4062-echo Building ltrace-$VERSION.tar.gz ...
4063-rm -rf ltrace-$VERSION
4064-git clone ./ ltrace-$VERSION >/dev/null
4065-GZIP=-9 tar --exclude .git -zcf ltrace-$VERSION.tar.gz ltrace-$VERSION
4066-rm -rf ltrace-$VERSION
4067-echo Done.
4068-
4069
4070=== modified file 'options.c'
4071--- options.c 2009-07-28 16:44:35 +0000
4072+++ options.c 2011-03-15 17:56:13 +0000
4073@@ -37,7 +37,7 @@
4074 };
4075
4076 char *library[MAX_LIBRARIES];
4077-int library_num = 0;
4078+size_t library_num = 0;
4079 static char *progname; /* Program name (`ltrace') */
4080 int opt_i = 0; /* instruction pointer */
4081 int opt_r = 0; /* print relative timestamp */
4082@@ -53,6 +53,7 @@
4083
4084 /* List of global function names given to -x: */
4085 struct opt_x_t *opt_x = NULL;
4086+unsigned int opt_x_cnt = 0;
4087
4088 /* List of filenames give to option -F: */
4089 struct opt_F_t *opt_F = NULL; /* alternate configuration file(s) */
4090@@ -75,6 +76,7 @@
4091 "Trace library calls of a given program.\n\n"
4092 " -a, --align=COLUMN align return values in a secific column.\n"
4093 " -A ARRAYLEN maximum number of array elements to print.\n"
4094+ " -b, --no-signals don't print signals.\n"
4095 " -c count time and calls, and report a summary on exit.\n"
4096 # ifdef USE_DEMANGLE
4097 " -C, --demangle decode low-level symbol names into user-level names.\n"
4098@@ -84,6 +86,7 @@
4099 " -e expr modify which events to trace.\n"
4100 " -f trace children (fork() and clone()).\n"
4101 " -F, --config=FILE load alternate configuration file (may be repeated).\n"
4102+ " -g, --no-plt disable breakpoints on PLT entries.\n"
4103 " -h, --help display this help and exit.\n"
4104 " -i print instruction pointer at time of library call.\n"
4105 " -l, --library=FILE print library calls from this library only.\n"
4106@@ -98,6 +101,9 @@
4107 " -T show the time spent inside each call.\n"
4108 " -u USERNAME run command with the userid, groupid of username.\n"
4109 " -V, --version output version information and exit.\n"
4110+#if defined(HAVE_LIBUNWIND)
4111+ " -w=NR, --where=NR print backtrace showing NR stack frames at most.\n"
4112+#endif /* defined(HAVE_LIBUNWIND) */
4113 " -x NAME treat the global NAME like a library subroutine.\n"
4114 #ifdef PLT_REINITALISATION_BP
4115 " -X NAME same as -x; and PLT's will be initialized by here.\n"
4116@@ -179,6 +185,11 @@
4117 process_options(int argc, char **argv) {
4118 progname = argv[0];
4119 options.output = stderr;
4120+ options.no_plt = 0;
4121+ options.no_signals = 0;
4122+#if defined(HAVE_LIBUNWIND)
4123+ options.bt_depth = -1;
4124+#endif /* defined(HAVE_LIBUNWIND) */
4125
4126 guess_cols();
4127
4128@@ -198,13 +209,22 @@
4129 {"library", 1, 0, 'l'},
4130 {"output", 1, 0, 'o'},
4131 {"version", 0, 0, 'V'},
4132+ {"no-plt", 0, 0, 'g'},
4133+ {"no-signals", 0, 0, 'b'},
4134+#if defined(HAVE_LIBUNWIND)
4135+ {"where", 1, 0, 'w'},
4136+#endif /* defined(HAVE_LIBUNWIND) */
4137 {0, 0, 0, 0}
4138 };
4139- c = getopt_long(argc, argv, "+cfhiLrStTV"
4140+ c = getopt_long(argc, argv, "+cfhiLrStTVgb"
4141 # ifdef USE_DEMANGLE
4142 "C"
4143 # endif
4144+#if defined(HAVE_LIBUNWIND)
4145+ "a:A:D:e:F:l:n:o:p:s:u:x:X:w:", long_options,
4146+#else /* !defined(HAVE_LIBUNWIND) */
4147 "a:A:D:e:F:l:n:o:p:s:u:x:X:", long_options,
4148+#endif
4149 &option_index);
4150 if (c == -1) {
4151 break;
4152@@ -216,6 +236,9 @@
4153 case 'A':
4154 options.arraylen = atoi(optarg);
4155 break;
4156+ case 'b':
4157+ options.no_signals = 1;
4158+ break;
4159 case 'c':
4160 options.summary++;
4161 break;
4162@@ -283,6 +306,9 @@
4163 opt_F = tmp;
4164 break;
4165 }
4166+ case 'g':
4167+ options.no_plt = 1;
4168+ break;
4169 case 'h':
4170 usage();
4171 exit(0);
4172@@ -351,6 +377,12 @@
4173 "This is free software; see the GNU General Public Licence\n"
4174 "version 2 or later for copying conditions. There is NO warranty.\n");
4175 exit(0);
4176+ break;
4177+#if defined(HAVE_LIBUNWIND)
4178+ case 'w':
4179+ options.bt_depth = atoi(optarg);
4180+ break;
4181+#endif /* defined(HAVE_LIBUNWIND) */
4182 case 'X':
4183 #ifdef PLT_REINITALISATION_BP
4184 PLTs_initialized_by_here = optarg;
4185@@ -378,9 +410,11 @@
4186 perror("ltrace: malloc");
4187 exit(1);
4188 }
4189+ opt_x_cnt++;
4190 p->name = optarg;
4191 p->found = 0;
4192 p->next = opt_x;
4193+ p->hash = ~(0UL);
4194 opt_x = p;
4195 break;
4196 }
4197
4198=== modified file 'options.h'
4199--- options.h 2009-07-28 16:44:35 +0000
4200+++ options.h 2011-03-15 17:56:13 +0000
4201@@ -2,18 +2,23 @@
4202 #include <sys/types.h>
4203
4204 struct options_t {
4205- int align; /* -a: default alignment column for results */
4206- char * user; /* -u: username to run command as */
4207- int syscalls; /* -S: display system calls */
4208- int libcalls; /* -L: display library calls */
4209- int demangle; /* -C: demangle low-level names into user-level names */
4210- int indent; /* -n: indent trace output according to program flow */
4211- FILE *output; /* output to a specific file */
4212- int summary; /* count time, calls, and report a summary on program exit */
4213- int debug; /* debug */
4214- int arraylen; /* default maximum # of array elements printed */
4215- int strlen; /* default maximum # of bytes printed in strings */
4216- int follow; /* trace child processes */
4217+ int align; /* -a: default alignment column for results */
4218+ char * user; /* -u: username to run command as */
4219+ int syscalls; /* -S: display system calls */
4220+ int libcalls; /* -L: display library calls */
4221+ int demangle; /* -C: demangle low-level names into user-level names */
4222+ int indent; /* -n: indent trace output according to program flow */
4223+ FILE *output; /* output to a specific file */
4224+ int summary; /* count time, calls, and report a summary on program exit */
4225+ int debug; /* debug */
4226+ size_t arraylen; /* default maximum # of array elements printed */
4227+ size_t strlen; /* default maximum # of bytes printed in strings */
4228+ int follow; /* trace child processes */
4229+ int no_plt; /* set bps on PLT entries */
4230+ int no_signals; /* don't print signals */
4231+#if defined(HAVE_LIBUNWIND)
4232+ int bt_depth; /* how may levels of stack frames to show */
4233+#endif /* defined(HAVE_LIBUNWIND) */
4234 };
4235 extern struct options_t options;
4236
4237@@ -40,6 +45,7 @@
4238 struct opt_x_t {
4239 char *name;
4240 int found;
4241+ unsigned long hash;
4242 struct opt_x_t *next;
4243 };
4244
4245@@ -51,5 +57,6 @@
4246 extern struct opt_F_t *opt_F; /* alternate configuration file(s) */
4247
4248 extern struct opt_x_t *opt_x; /* list of functions to break at */
4249+extern unsigned int opt_x_cnt;
4250
4251 extern char **process_options(int argc, char **argv);
4252
4253=== modified file 'output.c'
4254--- output.c 2009-07-28 16:44:35 +0000
4255+++ output.c 2011-03-15 17:56:13 +0000
4256@@ -164,7 +164,6 @@
4257 }
4258 if (current_proc) {
4259 fprintf(options.output, " <unfinished ...>\n");
4260- current_proc = 0;
4261 current_column = 0;
4262 }
4263 current_proc = proc;
4264@@ -298,6 +297,28 @@
4265 (int)current_time_spent.tv_usec);
4266 }
4267 fprintf(options.output, "\n");
4268+
4269+#if defined(HAVE_LIBUNWIND)
4270+ if (options.bt_depth > 0) {
4271+ unw_cursor_t cursor;
4272+ unw_word_t ip, sp;
4273+ int unwind_depth = options.bt_depth;
4274+ char fn_name[100];
4275+
4276+ unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
4277+ while (unwind_depth) {
4278+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
4279+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
4280+ unw_get_proc_name(&cursor, fn_name, 100, NULL);
4281+ fprintf(options.output, "\t\t\t%s (ip = 0x%lx)\n", fn_name, (long) ip);
4282+ if (unw_step(&cursor) <= 0)
4283+ break;
4284+ unwind_depth--;
4285+ }
4286+ fprintf(options.output, "\n");
4287+ }
4288+#endif /* defined(HAVE_LIBUNWIND) */
4289+
4290 current_proc = 0;
4291 current_column = 0;
4292 }
4293
4294=== modified file 'proc.c'
4295--- proc.c 2009-07-28 16:44:35 +0000
4296+++ proc.c 2011-03-15 17:56:13 +0000
4297@@ -1,3 +1,10 @@
4298+#include "config.h"
4299+
4300+#if defined(HAVE_LIBUNWIND)
4301+#include <libunwind.h>
4302+#include <libunwind-ptrace.h>
4303+#endif /* defined(HAVE_LIBUNWIND) */
4304+
4305 #include <sys/types.h>
4306 #include <string.h>
4307 #include <stdio.h>
4308@@ -18,11 +25,21 @@
4309 proc->breakpoints_enabled = -1;
4310 if (pid) {
4311 proc->pid = pid;
4312+#if defined(HAVE_LIBUNWIND)
4313+ proc->unwind_priv = _UPT_create(pid);
4314+ } else {
4315+ proc->unwind_priv = NULL;
4316+#endif /* defined(HAVE_LIBUNWIND) */
4317 }
4318+
4319 breakpoints_init(proc);
4320
4321 proc->next = list_of_processes;
4322 list_of_processes = proc;
4323+
4324+#if defined(HAVE_LIBUNWIND)
4325+ proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0);
4326+#endif /* defined(HAVE_LIBUNWIND) */
4327 return proc;
4328 }
4329
4330
4331=== added file 'sysdeps/Makefile.am'
4332--- sysdeps/Makefile.am 1970-01-01 00:00:00 +0000
4333+++ sysdeps/Makefile.am 2011-03-15 17:56:13 +0000
4334@@ -0,0 +1,11 @@
4335+DIST_SUBDIRS = \
4336+ linux-gnu
4337+
4338+SUBDIRS = \
4339+ $(HOST_OS)
4340+
4341+noinst_HEADERS = \
4342+ sysdep.h
4343+
4344+MAINTAINERCLEANFILES = \
4345+ Makefile.in
4346
4347=== modified file 'sysdeps/README'
4348--- sysdeps/README 2009-07-28 16:44:35 +0000
4349+++ sysdeps/README 2011-03-15 17:56:13 +0000
4350@@ -30,3 +30,4 @@
4351 void trace_me(void);
4352 int trace_pid(pid_t pid);
4353 void untrace_pid(pid_t pid);
4354+void linkmap_init(Process *, struct ltelf *);
4355
4356=== removed file 'sysdeps/linux-gnu/Makefile'
4357--- sysdeps/linux-gnu/Makefile 2009-07-28 16:44:35 +0000
4358+++ sysdeps/linux-gnu/Makefile 1970-01-01 00:00:00 +0000
4359@@ -1,60 +0,0 @@
4360-ARCH := $(shell uname -m | sed \
4361- -e s/i.86/i386/ \
4362- -e s/sun4u/sparc64/ \
4363- -e s/sparc64/sparc/ \
4364- -e s/arm.*/arm/ \
4365- -e s/sa110/arm/ \
4366- -e s/ppc64/ppc/ \
4367- -e s/s390x/s390/ \
4368- )
4369-
4370-CPPFLAGS += -I$(TOPDIR)/sysdeps/linux-gnu/$(ARCH)
4371-
4372-OBJ = events.o trace.o proc.o breakpoint.o
4373-
4374-all: sysdep.h signalent.h syscallent.h arch_syscallent.h signalent1.h syscallent1.h ../sysdep.o
4375-
4376-sysdep.h: $(ARCH)/arch.h
4377- cat $(ARCH)/arch.h > sysdep.h
4378-
4379-signalent.h:
4380- cp $(ARCH)/signalent.h signalent.h
4381-signalent1.h:
4382- if [ -f $(ARCH)/signalent1.h ]; then \
4383- cp $(ARCH)/signalent1.h signalent1.h; \
4384- else \
4385- > signalent1.h; \
4386- fi
4387-
4388-syscallent.h:
4389- cp $(ARCH)/syscallent.h syscallent.h
4390-
4391-syscallent1.h:
4392- if [ -f $(ARCH)/syscallent1.h ]; then \
4393- cp $(ARCH)/syscallent1.h syscallent1.h; \
4394- else \
4395- > syscallent1.h; \
4396- fi
4397-
4398-arch_syscallent.h:
4399- if [ -f $(ARCH)/arch_syscallent.h ]; then \
4400- cp $(ARCH)/arch_syscallent.h arch_syscallent.h; \
4401- else \
4402- > arch_syscallent.h; \
4403- fi
4404-
4405-../sysdep.o: os.o $(ARCH)/arch.o
4406- $(CC) -nostdlib -r -o ../sysdep.o os.o $(ARCH)/arch.o
4407-
4408-os.o: $(OBJ)
4409- $(CC) -nostdlib -r -o os.o $(OBJ)
4410-
4411-$(ARCH)/arch.o: dummy
4412- $(MAKE) -C $(ARCH)
4413-
4414-clean:
4415- $(MAKE) -C $(ARCH) clean
4416- rm -f $(OBJ) sysdep.h signalent.h signalent1.h syscallent.h arch_syscallent.h
4417- rm -f syscallent1.h os.o sysdep.o ../sysdep.o
4418-
4419-dummy:
4420
4421=== added file 'sysdeps/linux-gnu/Makefile.am'
4422--- sysdeps/linux-gnu/Makefile.am 1970-01-01 00:00:00 +0000
4423+++ sysdeps/linux-gnu/Makefile.am 2011-03-15 17:56:13 +0000
4424@@ -0,0 +1,40 @@
4425+DIST_SUBDIRS = \
4426+ alpha \
4427+ arm \
4428+ i386 \
4429+ ia64 \
4430+ m68k \
4431+ mipsel \
4432+ ppc \
4433+ s390 \
4434+ sparc \
4435+ x86_64
4436+
4437+SUBDIRS = \
4438+ $(HOST_CPU)
4439+
4440+noinst_LTLIBRARIES = \
4441+ ../libos.la
4442+
4443+___libos_la_SOURCES = \
4444+ events.c \
4445+ trace.c \
4446+ proc.c \
4447+ breakpoint.c
4448+
4449+___libos_la_LIBADD = \
4450+ libcpu.la
4451+
4452+noinst_HEADERS = \
4453+ arch_syscallent.h \
4454+ signalent1.h \
4455+ syscallent1.h
4456+
4457+EXTRA_DIST = \
4458+ arch_mksyscallent \
4459+ mksignalent \
4460+ mksyscallent \
4461+ mksyscallent_s390
4462+
4463+MAINTAINERCLEANFILES = \
4464+ Makefile.in
4465
4466=== removed file 'sysdeps/linux-gnu/alpha/Makefile'
4467--- sysdeps/linux-gnu/alpha/Makefile 2008-05-27 10:51:22 +0000
4468+++ sysdeps/linux-gnu/alpha/Makefile 1970-01-01 00:00:00 +0000
4469@@ -1,10 +0,0 @@
4470-OBJ = trace.o regs.o plt.o
4471-
4472-all: arch.o
4473-
4474-arch.o: $(OBJ)
4475- $(CC) -nostdlib -r -o arch.o $(OBJ)
4476-
4477-clean:
4478- $(RM) $(OBJ) arch.o
4479-
4480
4481=== added file 'sysdeps/linux-gnu/alpha/Makefile.am'
4482--- sysdeps/linux-gnu/alpha/Makefile.am 1970-01-01 00:00:00 +0000
4483+++ sysdeps/linux-gnu/alpha/Makefile.am 2011-03-15 17:56:13 +0000
4484@@ -0,0 +1,16 @@
4485+noinst_LTLIBRARIES = \
4486+ ../libcpu.la
4487+
4488+___libcpu_la_SOURCES = \
4489+ plt.c \
4490+ regs.c \
4491+ trace.c
4492+
4493+noinst_HEADERS = \
4494+ arch.h \
4495+ ptrace.h \
4496+ signalent.h \
4497+ syscallent.h
4498+
4499+MAINTAINERCLEANFILES = \
4500+ Makefile.in
4501
4502=== added file 'sysdeps/linux-gnu/arch_syscallent.h'
4503--- sysdeps/linux-gnu/arch_syscallent.h 1970-01-01 00:00:00 +0000
4504+++ sysdeps/linux-gnu/arch_syscallent.h 2011-03-15 17:56:13 +0000
4505@@ -0,0 +1,1 @@
4506+/* This file is intentionally left blank */
4507
4508=== removed file 'sysdeps/linux-gnu/arm/Makefile'
4509--- sysdeps/linux-gnu/arm/Makefile 2009-01-06 17:46:28 +0000
4510+++ sysdeps/linux-gnu/arm/Makefile 1970-01-01 00:00:00 +0000
4511@@ -1,10 +0,0 @@
4512-OBJ = trace.o regs.o plt.o breakpoint.o
4513-
4514-all: arch.o
4515-
4516-arch.o: $(OBJ) arch.h
4517- $(CC) -nostdlib -r -o arch.o $(OBJ)
4518-
4519-clean:
4520- $(RM) $(OBJ) arch.o
4521-
4522
4523=== added file 'sysdeps/linux-gnu/arm/Makefile.am'
4524--- sysdeps/linux-gnu/arm/Makefile.am 1970-01-01 00:00:00 +0000
4525+++ sysdeps/linux-gnu/arm/Makefile.am 2011-03-15 17:56:13 +0000
4526@@ -0,0 +1,18 @@
4527+noinst_LTLIBRARIES = \
4528+ ../libcpu.la
4529+
4530+___libcpu_la_SOURCES = \
4531+ breakpoint.c \
4532+ plt.c \
4533+ regs.c \
4534+ trace.c
4535+
4536+noinst_HEADERS = \
4537+ arch.h \
4538+ arch_syscallent.h \
4539+ ptrace.h \
4540+ signalent.h \
4541+ syscallent.h
4542+
4543+MAINTAINERCLEANFILES = \
4544+ Makefile.in
4545
4546=== modified file 'sysdeps/linux-gnu/arm/plt.c'
4547--- sysdeps/linux-gnu/arm/plt.c 2009-07-28 16:44:35 +0000
4548+++ sysdeps/linux-gnu/arm/plt.c 2011-03-15 17:56:13 +0000
4549@@ -1,9 +1,21 @@
4550 #include <gelf.h>
4551 #include "common.h"
4552
4553+static int
4554+arch_plt_entry_has_stub(struct ltelf *lte, size_t off) {
4555+ uint16_t op = *(uint16_t *)((char *)lte->relplt->d_buf + off);
4556+ return op == 0x4778;
4557+}
4558+
4559 GElf_Addr
4560 arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) {
4561- return lte->plt_addr + 20 + ndx * 12;
4562+ size_t start = lte->relplt->d_size + 12;
4563+ size_t off = start + 20, i;
4564+ for (i = 0; i < ndx; i++)
4565+ off += arch_plt_entry_has_stub(lte, off) ? 16 : 12;
4566+ if (arch_plt_entry_has_stub(lte, off))
4567+ off += 4;
4568+ return lte->plt_addr + off - start;
4569 }
4570
4571 void *
4572
4573=== modified file 'sysdeps/linux-gnu/arm/regs.c'
4574--- sysdeps/linux-gnu/arm/regs.c 2009-07-28 16:44:35 +0000
4575+++ sysdeps/linux-gnu/arm/regs.c 2011-03-15 17:56:13 +0000
4576@@ -47,5 +47,6 @@
4577
4578 void
4579 set_return_addr(Process *proc, void *addr) {
4580- ptrace(PTRACE_POKEUSER, proc->pid, off_lr, addr);
4581+ long iaddr = (int)addr | proc->thumb_mode;
4582+ ptrace(PTRACE_POKEUSER, proc->pid, off_lr, (void *)iaddr);
4583 }
4584
4585=== modified file 'sysdeps/linux-gnu/arm/trace.c'
4586--- sysdeps/linux-gnu/arm/trace.c 2010-10-01 16:06:14 +0000
4587+++ sysdeps/linux-gnu/arm/trace.c 2011-03-15 17:56:13 +0000
4588@@ -46,7 +46,7 @@
4589 /* get the user's pc (plus 8) */
4590 int pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0);
4591 /* fetch the SWI instruction */
4592- int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
4593+ unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
4594 int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0);
4595
4596 if (insn == 0xef000000 || insn == 0x0f000000
4597@@ -63,7 +63,7 @@
4598 * PC does not point to the instruction just after the
4599 * "swi" one. */
4600 output_line(proc, "unexpected instruction 0x%x at %p", insn, pc - 4);
4601- return -1;
4602+ return 0;
4603 }
4604 if ((*sysnum & 0xf0000) == 0xf0000) {
4605 /* arch-specific syscall */
4606
4607=== added directory 'sysdeps/linux-gnu/cris'
4608=== added file 'sysdeps/linux-gnu/cris/Makefile'
4609--- sysdeps/linux-gnu/cris/Makefile 1970-01-01 00:00:00 +0000
4610+++ sysdeps/linux-gnu/cris/Makefile 2011-03-15 17:56:13 +0000
4611@@ -0,0 +1,10 @@
4612+OBJ = trace.o regs.o plt.o
4613+
4614+all: arch.o
4615+
4616+arch.o: $(OBJ)
4617+ $(CC) -nostdlib -r -o arch.o $(OBJ)
4618+
4619+clean:
4620+ $(RM) $(OBJ) arch.o
4621+
4622
4623=== added file 'sysdeps/linux-gnu/cris/arch.h'
4624--- sysdeps/linux-gnu/cris/arch.h 1970-01-01 00:00:00 +0000
4625+++ sysdeps/linux-gnu/cris/arch.h 2011-03-15 17:56:13 +0000
4626@@ -0,0 +1,6 @@
4627+#define BREAKPOINT_VALUE { 0x38, 0xe9 }
4628+#define BREAKPOINT_LENGTH 2
4629+#define DECR_PC_AFTER_BREAK 0
4630+
4631+#define LT_ELFCLASS ELFCLASS32
4632+#define LT_ELF_MACHINE EM_CRIS
4633
4634=== added file 'sysdeps/linux-gnu/cris/plt.c'
4635--- sysdeps/linux-gnu/cris/plt.c 1970-01-01 00:00:00 +0000
4636+++ sysdeps/linux-gnu/cris/plt.c 2011-03-15 17:56:13 +0000
4637@@ -0,0 +1,12 @@
4638+#include <gelf.h>
4639+#include "common.h"
4640+
4641+GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
4642+{
4643+ return lte->plt_addr + 0x20 + (ndx * 26);
4644+}
4645+
4646+void *sym2addr(Process *proc, struct library_symbol *sym)
4647+{
4648+ return sym->enter_addr;
4649+}
4650
4651=== added file 'sysdeps/linux-gnu/cris/ptrace.h'
4652--- sysdeps/linux-gnu/cris/ptrace.h 1970-01-01 00:00:00 +0000
4653+++ sysdeps/linux-gnu/cris/ptrace.h 2011-03-15 17:56:13 +0000
4654@@ -0,0 +1,1 @@
4655+#include <sys/ptrace.h>
4656
4657=== added file 'sysdeps/linux-gnu/cris/regs.c'
4658--- sysdeps/linux-gnu/cris/regs.c 1970-01-01 00:00:00 +0000
4659+++ sysdeps/linux-gnu/cris/regs.c 2011-03-15 17:56:13 +0000
4660@@ -0,0 +1,37 @@
4661+#if HAVE_CONFIG_H
4662+#include "config.h"
4663+#endif
4664+
4665+#include <sys/types.h>
4666+#include <sys/ptrace.h>
4667+#include <asm/ptrace.h>
4668+
4669+#include "common.h"
4670+
4671+#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
4672+# define PTRACE_PEEKUSER PTRACE_PEEKUSR
4673+#endif
4674+
4675+#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
4676+# define PTRACE_POKEUSER PTRACE_POKEUSR
4677+#endif
4678+
4679+void *get_instruction_pointer(Process *proc)
4680+{
4681+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_PPC, 0);
4682+}
4683+
4684+void set_instruction_pointer(Process *proc, void *addr)
4685+{
4686+ ptrace(PTRACE_POKEUSER, proc->pid, 4 * PT_PPC, addr);
4687+}
4688+
4689+void *get_stack_pointer(Process *proc)
4690+{
4691+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_USP, 0);
4692+}
4693+
4694+void *get_return_addr(Process *proc, void *stack_pointer)
4695+{
4696+ return (void *)ptrace(PTRACE_PEEKUSER, proc->pid, 4 * PT_SRP, 0);
4697+}
4698
4699=== added file 'sysdeps/linux-gnu/cris/signalent.h'
4700--- sysdeps/linux-gnu/cris/signalent.h 1970-01-01 00:00:00 +0000
4701+++ sysdeps/linux-gnu/cris/signalent.h 2011-03-15 17:56:13 +0000
4702@@ -0,0 +1,32 @@
4703+ "SIG_0", /* 0 */
4704+ "SIGHUP", /* 1 */
4705+ "SIGINT", /* 2 */
4706+ "SIGQUIT", /* 3 */
4707+ "SIGILL", /* 4 */
4708+ "SIGTRAP", /* 5 */
4709+ "SIGABRT", /* 6 */
4710+ "SIGBUS", /* 7 */
4711+ "SIGFPE", /* 8 */
4712+ "SIGKILL", /* 9 */
4713+ "SIGUSR1", /* 10 */
4714+ "SIGSEGV", /* 11 */
4715+ "SIGUSR2", /* 12 */
4716+ "SIGPIPE", /* 13 */
4717+ "SIGALRM", /* 14 */
4718+ "SIGTERM", /* 15 */
4719+ "SIGSTKFLT", /* 16 */
4720+ "SIGCHLD", /* 17 */
4721+ "SIGCONT", /* 18 */
4722+ "SIGSTOP", /* 19 */
4723+ "SIGTSTP", /* 20 */
4724+ "SIGTTIN", /* 21 */
4725+ "SIGTTOU", /* 22 */
4726+ "SIGURG", /* 23 */
4727+ "SIGXCPU", /* 24 */
4728+ "SIGXFSZ", /* 25 */
4729+ "SIGVTALRM", /* 26 */
4730+ "SIGPROF", /* 27 */
4731+ "SIGWINCH", /* 28 */
4732+ "SIGIO", /* 29 */
4733+ "SIGPWR", /* 30 */
4734+ "SIGSYS", /* 31 */
4735
4736=== added file 'sysdeps/linux-gnu/cris/syscallent.h'
4737--- sysdeps/linux-gnu/cris/syscallent.h 1970-01-01 00:00:00 +0000
4738+++ sysdeps/linux-gnu/cris/syscallent.h 2011-03-15 17:56:13 +0000
4739@@ -0,0 +1,325 @@
4740+"0", /* 0 */
4741+ "exit",
4742+"fork",
4743+"read",
4744+"write",
4745+"open",
4746+"close",
4747+"waitpid",
4748+"creat",
4749+"link",
4750+"unlink",
4751+"execve",
4752+"chdir",
4753+"time",
4754+"mknod",
4755+"chmod",
4756+"lchown",
4757+"break",
4758+"oldstat",
4759+"lseek",
4760+"getpid",
4761+"mount",
4762+"umount",
4763+"setuid",
4764+"getuid",
4765+"stime",
4766+"ptrace",
4767+"alarm",
4768+"oldfstat",
4769+"pause",
4770+"utime",
4771+"stty",
4772+"gtty",
4773+"access",
4774+"nice",
4775+"ftime",
4776+"sync",
4777+"kill",
4778+"rename",
4779+"mkdir",
4780+"rmdir",
4781+"dup",
4782+"pipe",
4783+"times",
4784+"prof",
4785+"brk",
4786+"setgid",
4787+"getgid",
4788+"signal",
4789+"geteuid",
4790+"getegid",
4791+"acct",
4792+"umount2",
4793+"lock",
4794+"ioctl",
4795+"fcntl",
4796+"mpx",
4797+"setpgid",
4798+"ulimit",
4799+"oldolduname",
4800+"umask",
4801+"chroot",
4802+"ustat",
4803+"dup2",
4804+"getppid",
4805+"getpgrp",
4806+"setsid",
4807+"sigaction",
4808+"sgetmask",
4809+"ssetmask",
4810+"setreuid",
4811+"setregid",
4812+"sigsuspend",
4813+"sigpending",
4814+"sethostname",
4815+"setrlimit",
4816+"getrlimit",
4817+"getrusage",
4818+"gettimeofday",
4819+"settimeofday",
4820+"getgroups",
4821+"setgroups",
4822+"select",
4823+"symlink",
4824+"oldlstat",
4825+"readlink",
4826+"uselib",
4827+"swapon",
4828+"reboot",
4829+"readdir",
4830+"mmap",
4831+"munmap",
4832+"truncate",
4833+"ftruncate",
4834+"fchmod",
4835+"fchown",
4836+"getpriority",
4837+"setpriority",
4838+"profil",
4839+"statfs",
4840+"fstatfs",
4841+"ioperm",
4842+"socketcall",
4843+"syslog",
4844+"setitimer",
4845+"getitimer",
4846+"stat",
4847+"lstat",
4848+"fstat",
4849+"olduname",
4850+"iopl",
4851+"vhangup",
4852+"idle",
4853+"vm86",
4854+"wait4",
4855+"swapoff",
4856+"sysinfo",
4857+"ipc",
4858+"fsync",
4859+"sigreturn",
4860+"clone",
4861+"setdomainname",
4862+"uname",
4863+"modify_ldt",
4864+"adjtimex",
4865+"mprotect",
4866+"sigprocmask",
4867+"create_module",
4868+"init_module",
4869+"delete_module",
4870+"get_kernel_syms",
4871+"quotactl",
4872+"getpgid",
4873+"fchdir",
4874+"bdflush",
4875+"sysfs",
4876+"personality",
4877+"afs_syscall",
4878+"setfsuid",
4879+"setfsgid",
4880+"_llseek",
4881+"getdents",
4882+"_newselect",
4883+"flock",
4884+"msync",
4885+"readv",
4886+"writev",
4887+"getsid",
4888+"fdatasync",
4889+"_sysctl",
4890+"mlock",
4891+"munlock",
4892+"mlockall",
4893+"munlockall",
4894+"sched_setparam",
4895+"sched_getparam",
4896+"sched_setscheduler",
4897+"sched_getscheduler",
4898+"sched_yield",
4899+"sched_get_priority_max",
4900+"sched_get_priority_min",
4901+"sched_rr_get_interval",
4902+"nanosleep",
4903+"mremap",
4904+"setresuid",
4905+"getresuid",
4906+"invalid",
4907+"query_module",
4908+"poll",
4909+"nfsservctl",
4910+"setresgid",
4911+"getresgid",
4912+"prctl",
4913+"rt_sigreturn",
4914+"rt_sigaction",
4915+"rt_sigprocmask",
4916+"rt_sigpending",
4917+"rt_sigtimedwait",
4918+"rt_sigqueueinfo",
4919+"rt_sigsuspend",
4920+"pread64",
4921+"pwrite64",
4922+"chown",
4923+"getcwd",
4924+"capget",
4925+"capset",
4926+"sigaltstack",
4927+"sendfile",
4928+"getpmsg",
4929+"putpmsg",
4930+"vfork",
4931+"ugetrlimit",
4932+"mmap2",
4933+"truncate64",
4934+"ftruncate64",
4935+"stat64",
4936+"lstat64",
4937+"fstat64",
4938+"lchown32",
4939+"getuid32",
4940+"getgid32",
4941+"geteuid32",
4942+"getegid32",
4943+"setreuid32",
4944+"setregid32",
4945+"getgroups32",
4946+"setgroups32",
4947+"fchown32",
4948+"setresuid32",
4949+"getresuid32",
4950+"setresgid32",
4951+"getresgid32",
4952+"chown32",
4953+"setuid32",
4954+"setgid32",
4955+"setfsuid32",
4956+"setfsgid32",
4957+"pivot_root",
4958+"mincore",
4959+"madvise",
4960+"getdents64",
4961+"fcntl64",
4962+"invalid",
4963+"invalid",
4964+"gettid",
4965+"readahead",
4966+"setxattr",
4967+"lsetxattr",
4968+"fsetxattr",
4969+"getxattr",
4970+"lgetxattr",
4971+"fgetxattr",
4972+"listxattr",
4973+"llistxattr",
4974+"flistxattr",
4975+"removexattr",
4976+"lremovexattr",
4977+"fremovexattr",
4978+"tkill",
4979+"sendfile64",
4980+"futex",
4981+"sched_setaffinity",
4982+"sched_getaffinity",
4983+"set_thread_area",
4984+"get_thread_area",
4985+"io_setup",
4986+"io_destroy",
4987+"io_getevents",
4988+"io_submit",
4989+"io_cancel",
4990+"fadvise64",
4991+"invalid",
4992+"exit_group",
4993+"lookup_dcookie",
4994+"epoll_create",
4995+"epoll_ctl",
4996+"epoll_wait",
4997+"remap_file_pages",
4998+"set_tid_address",
4999+"timer_create",
5000+"timer_settime",
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: