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